Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp4561475imu; Tue, 29 Jan 2019 03:50:25 -0800 (PST) X-Google-Smtp-Source: ALg8bN7gEM2XuGM+yN2n0XNYPcn0NmDl4+SvP5jhL0sddyjy4QzNb1zVGiR1s+sW1b5qFIfUnLap X-Received: by 2002:a62:9719:: with SMTP id n25mr26730964pfe.240.1548762625869; Tue, 29 Jan 2019 03:50:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548762625; cv=none; d=google.com; s=arc-20160816; b=CjDGM2s3tHnMbPA1TcJkbfS5OJTJP07sIB/9T/IyOLt8+5o7rxB0pbxTSvlCUK34nI yaXdL9FXB97EJRNyXT/XJbn5aKvzt0Suv8APKGhfYyvr/qwCkSWidTuh4L7rYCjtP8oo cn/rJhdjh81BrdjH0OTv4S+dIY8lZzCQ23I/lz6N81wbZFb1+yjHdcvyP9/DgyuKBkGl 7IUMZAkQhdpbDsjwjwTD42+eemHcX6KAVfzy3kooch7GAz9ab6M1TSzi3wK45iRQPPH2 CAUnDTuf0e5m4flx97/NK7tUGZP+Sedqb8T06RR/YMj09q5/LIqN/WxmqBWIZjhuwPMW T6OQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:date:subject:user-agent:message-id :references:cc:in-reply-to:from:to:content-transfer-encoding :mime-version; bh=6uBq+Yrba9Gg8FRHozwZ50AHz0JjUo8uxRVKIG5R/nM=; b=y5QVwe/nUgPtzo1KjV7naHKyjyrVhC4tiYUwMj7UodKemiw1TcQTUHA0/yW7n+GCiP 2WmzN9bRT4USl52aVPnypCzQwq36zx4nZjbw+8M97XIlOcH3dfC0HbRfNKrBwgl9zupq 0TJHV69EFFFY0F7/MUKhj13xeKZ2FeAyL9PZLMdAbgdNsrVKc9ajfFr67rUAkiRXx2X/ 1qvcYc8bjEKRXzCo53RrfkmdOdJqLlsDBK8NGwUWULxRsbttxcVAjoKf1xbsKXkz12sh fPlv3Q7ldJUfv272S9JiXhZcmIAYengek/A5/NQVQbaTdQGXohb5NSJGKx7HK7P4lDUG e8DQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c9si7927767pll.439.2019.01.29.03.50.08; Tue, 29 Jan 2019 03:50:25 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731583AbfA2LuE convert rfc822-to-8bit (ORCPT + 99 others); Tue, 29 Jan 2019 06:50:04 -0500 Received: from mail.fireflyinternet.com ([109.228.58.192]:58339 "EHLO fireflyinternet.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731557AbfA2LuB (ORCPT ); Tue, 29 Jan 2019 06:50:01 -0500 X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from localhost (unverified [78.156.65.138]) by fireflyinternet.com (Firefly Internet (M1)) with ESMTP (TLS) id 15388704-1500050 for multiple; Tue, 29 Jan 2019 11:49:46 +0000 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8BIT To: Lyude Paul , intel-gfx@lists.freedesktop.org From: Chris Wilson In-Reply-To: <20190128205603.16372-2-lyude@redhat.com> Cc: Todd Previte , dri-devel@lists.freedesktop.org, David Airlie , linux-kernel@vger.kernel.org, stable@vger.kernel.org, Dave Airlie References: <20190128205603.16372-1-lyude@redhat.com> <20190128205603.16372-2-lyude@redhat.com> Message-ID: <154876258326.22998.16834385719676742479@skylake-alporthouse-com> User-Agent: alot/0.6 Subject: Re: [Intel-gfx] [PATCH v2 1/3] drm/i915: Block fbdev HPD processing during suspend Date: Tue, 29 Jan 2019 11:49:43 +0000 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Quoting Lyude Paul (2019-01-28 20:56:01) > When resuming, we check whether or not any previously connected > MST topologies are still present and if so, attempt to resume them. If > this fails, we disable said MST topologies and fire off a hotplug event > so that userspace knows to reprobe. > > However, sending a hotplug event involves calling > drm_fb_helper_hotplug_event(), which in turn results in fbcon doing a > connector reprobe in the caller's thread - something we can't do at the > point in which i915 calls drm_dp_mst_topology_mgr_resume() since > hotplugging hasn't been fully initialized yet. > > This currently causes some rather subtle but fatal issues. For example, > on my T480s the laptop dock connected to it usually disappears during a > suspend cycle, and comes back up a short while after the system has been > resumed. This guarantees pretty much every suspend and resume cycle, > drm_dp_mst_topology_mgr_set_mst(mgr, false); will be caused and in turn, > a connector hotplug will occur. Now it's Rute Goldberg time: when the > connector hotplug occurs, i915 reprobes /all/ of the connectors, > including eDP. However, eDP probing requires that we power on the panel > VDD which in turn, grabs a wakeref to the appropriate power domain on > the GPU (on my T480s, this is the PORT_DDI_A_IO domain). This is where > things start breaking, since this all happens before > intel_power_domains_enable() is called we end up leaking the wakeref > that was acquired and never releasing it later. Come next suspend/resume > cycle, this causes us to fail to shut down the GPU properly, which > causes it not to resume properly and die a horrible complicated death. > > (as a note: this only happens when there's both an eDP panel and MST > topology connected which is removed mid-suspend. One or the other seems > to always be OK). > > We could try to fix the VDD wakeref leak, but this doesn't seem like > it's worth it at all since we aren't able to handle hotplug detection > while resuming anyway. So, let's go with a more robust solution inspired > by nouveau: block fbdev from handling hotplug events until we resume > fbdev. This allows us to still send sysfs hotplug events to be handled > later by user space while we're resuming, while also preventing us from > actually processing any hotplug events we receive until it's safe. > > This fixes the wakeref leak observed on the T480s and as such, also > fixes suspend/resume with MST topologies connected on this machine. > > Signed-off-by: Lyude Paul > Fixes: 0e32b39ceed6 ("drm/i915: add DP 1.2 MST support (v0.7)") > Cc: Todd Previte > Cc: Dave Airlie > Cc: Jani Nikula > Cc: Joonas Lahtinen > Cc: Rodrigo Vivi > Cc: Imre Deak > Cc: intel-gfx@lists.freedesktop.org > Cc: # v3.17+ > --- > drivers/gpu/drm/i915/intel_drv.h | 10 ++++++++++ > drivers/gpu/drm/i915/intel_fbdev.c | 30 +++++++++++++++++++++++++++++- > 2 files changed, 39 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 85b913ea6e80..c8549588b2ce 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -213,6 +213,16 @@ struct intel_fbdev { > unsigned long vma_flags; > async_cookie_t cookie; > int preferred_bpp; > + > + /* Whether or not fbdev hpd processing is temporarily suspended */ > + bool hpd_suspended : 1; > + /* Set when a hotplug was received while HPD processing was > + * suspended > + */ > + bool hpd_waiting : 1; > + > + /* Protects hpd_suspended */ > + struct mutex hpd_lock; > }; > > struct intel_encoder { > diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c > index 8cf3efe88f02..3a6c0bebaaf9 100644 > --- a/drivers/gpu/drm/i915/intel_fbdev.c > +++ b/drivers/gpu/drm/i915/intel_fbdev.c > @@ -681,6 +681,7 @@ int intel_fbdev_init(struct drm_device *dev) > if (ifbdev == NULL) > return -ENOMEM; > > + mutex_init(&ifbdev->hpd_lock); > drm_fb_helper_prepare(dev, &ifbdev->helper, &intel_fb_helper_funcs); > > if (!intel_fbdev_init_bios(dev, ifbdev)) > @@ -754,6 +755,23 @@ void intel_fbdev_fini(struct drm_i915_private *dev_priv) > intel_fbdev_destroy(ifbdev); > } > > +/* Suspends/resumes fbdev processing of incoming HPD events. When resuming HPD > + * processing, fbdev will perform a full connector reprobe if a hotplug event > + * was received while HPD was suspended. > + */ > +static void intel_fbdev_hpd_set_suspend(struct intel_fbdev *ifbdev, int state) > +{ > + mutex_lock(&ifbdev->hpd_lock); > + ifbdev->hpd_suspended = state == FBINFO_STATE_SUSPENDED; > + if (ifbdev->hpd_waiting) { > + ifbdev->hpd_waiting = false; > + > + DRM_DEBUG_KMS("Handling delayed fbcon HPD event\n"); > + drm_fb_helper_hotplug_event(&ifbdev->helper); Even when set_suspend(true) ? Then on resume, we don't care as another hotplug is generated. Calling the hotplug_even from under the mutex feels like unnecessary lock spreading. > + } > + mutex_unlock(&ifbdev->hpd_lock); I am thinking along the lines of: bool send_event = false; mutex_lock(&hpd_lock); ifbdev->hpd_suspended = state == SUSPENDED; send_event = !hpd_suspended && hpd_waiting; hpd_waiting = false; mutex_unlock(&hpd_lock) if (send_event) { DRM_DEBUG_KMS("Handling delayed fbcon HPD event\n"); drm_fb_helper_hotplug_event(&ifbdev->helper); } > void intel_fbdev_output_poll_changed(struct drm_device *dev) > @@ -812,8 +833,15 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev) > return; > > intel_fbdev_sync(ifbdev); > - if (ifbdev->vma || ifbdev->helper.deferred_setup) > + > + mutex_lock(&ifbdev->hpd_lock); > + if (ifbdev->hpd_suspended) { > + DRM_DEBUG_KMS("fbdev HPD event deferred until resume\n"); > + ifbdev->hpd_waiting = true; > + } else if (ifbdev->vma || ifbdev->helper.deferred_setup) { > drm_fb_helper_hotplug_event(&ifbdev->helper); > + } Seems ripe for simplification. We can always just set hpd_waiting as it will be reset over suspend, so then we just need a way of tidying up the "am I ready to send" check. -Chris