From patchwork Fri Jul 11 17:30:15 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rodrigo Vivi X-Patchwork-Id: 4538461 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 5229C9F1D6 for ; Sat, 12 Jul 2014 00:28:52 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 647A220254 for ; Sat, 12 Jul 2014 00:28:51 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 57CE22017E for ; Sat, 12 Jul 2014 00:28:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D8CA88A21A; Fri, 11 Jul 2014 17:28:49 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id 889BC6E220 for ; Fri, 11 Jul 2014 17:28:40 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 11 Jul 2014 17:28:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.01,646,1400050800"; d="scan'208";a="542272157" Received: from di-604.jf.intel.com (HELO rdvivi-hillsboro.jf.intel.com) ([10.7.201.28]) by orsmga001.jf.intel.com with ESMTP; 11 Jul 2014 17:28:35 -0700 From: Rodrigo Vivi To: intel-gfx@lists.freedesktop.org Date: Fri, 11 Jul 2014 10:30:15 -0700 Message-Id: <1405099819-11119-7-git-send-email-rodrigo.vivi@intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1405099819-11119-1-git-send-email-rodrigo.vivi@intel.com> References: <1405099819-11119-1-git-send-email-rodrigo.vivi@intel.com> Cc: Daniel Vetter , Rodrigo Vivi Subject: [Intel-gfx] [PATCH 07/11] drm/i915: Add locking to psr code X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-3.3 required=5.0 tests=BAYES_00, DATE_IN_PAST_06_12, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Daniel Vetter It's not really optional to have locking ... The ugly part is how much locking the psr work needs since it has to recheck everything. Which is way too much. But we need to ditch the psr work in it's current form anyway and implement proper frontbuffer tracking. The other nasty bit that had to go was the delayed work cancle in psr_exit. Which means a bunch of races just became a bit more likely, but mea culpa. v2: Fixup HAS_PSR checks, resulting in uninitialized mutex issues. Reviewed-by: Rodrigo Vivi Signed-off-by: Daniel Vetter Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_dp.c | 38 +++++++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1ec4d4a..ae069b6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -656,6 +656,7 @@ struct i915_drrs { struct intel_dp; struct i915_psr { + struct mutex lock; bool sink_support; bool source_ok; struct intel_dp *enabled; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5854ae6..a59d5a6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1800,6 +1800,11 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp) struct drm_i915_gem_object *obj = intel_fb_obj(crtc->primary->fb); struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; + lockdep_assert_held(&dev_priv->psr.lock); + lockdep_assert_held(&dev->struct_mutex); + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); + dev_priv->psr.source_ok = false; if (!HAS_PSR(dev)) { @@ -1869,6 +1874,7 @@ static void intel_edp_psr_do_enable(struct intel_dp *intel_dp) WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE); WARN_ON(dev_priv->psr.active); + lockdep_assert_held(&dev_priv->psr.lock); /* Enable PSR on the panel */ intel_edp_psr_enable_sink(intel_dp); @@ -1895,8 +1901,10 @@ void intel_edp_psr_enable(struct intel_dp *intel_dp) return; } + mutex_lock(&dev_priv->psr.lock); if (dev_priv->psr.enabled) { DRM_DEBUG_KMS("PSR already in use\n"); + mutex_unlock(&dev_priv->psr.lock); return; } @@ -1905,6 +1913,7 @@ void intel_edp_psr_enable(struct intel_dp *intel_dp) if (intel_edp_psr_match_conditions(intel_dp)) intel_edp_psr_do_enable(intel_dp); + mutex_unlock(&dev_priv->psr.lock); } void intel_edp_psr_disable(struct intel_dp *intel_dp) @@ -1912,9 +1921,15 @@ void intel_edp_psr_disable(struct intel_dp *intel_dp) struct drm_device *dev = intel_dp_to_dev(intel_dp); struct drm_i915_private *dev_priv = dev->dev_private; - if (!dev_priv->psr.enabled) + if (!HAS_PSR(dev)) return; + mutex_lock(&dev_priv->psr.lock); + if (!dev_priv->psr.enabled) { + mutex_unlock(&dev_priv->psr.lock); + return; + } + if (dev_priv->psr.active) { I915_WRITE(EDP_PSR_CTL(dev), I915_READ(EDP_PSR_CTL(dev)) & ~EDP_PSR_ENABLE); @@ -1930,19 +1945,30 @@ void intel_edp_psr_disable(struct intel_dp *intel_dp) } dev_priv->psr.enabled = NULL; + mutex_unlock(&dev_priv->psr.lock); } static void intel_edp_psr_work(struct work_struct *work) { struct drm_i915_private *dev_priv = container_of(work, typeof(*dev_priv), psr.work.work); + struct drm_device *dev = dev_priv->dev; struct intel_dp *intel_dp = dev_priv->psr.enabled; + drm_modeset_lock_all(dev); + mutex_lock(&dev->struct_mutex); + mutex_lock(&dev_priv->psr.lock); + intel_dp = dev_priv->psr.enabled; + if (!intel_dp) - return; + goto unlock; if (intel_edp_psr_match_conditions(intel_dp)) intel_edp_psr_do_enable(intel_dp); +unlock: + mutex_unlock(&dev_priv->psr.lock); + mutex_unlock(&dev->struct_mutex); + drm_modeset_unlock_all(dev); } void intel_edp_psr_exit(struct drm_device *dev) @@ -1955,8 +1981,7 @@ void intel_edp_psr_exit(struct drm_device *dev) if (!dev_priv->psr.enabled) return; - cancel_delayed_work_sync(&dev_priv->psr.work); - + mutex_lock(&dev_priv->psr.lock); if (dev_priv->psr.active) { u32 val = I915_READ(EDP_PSR_CTL(dev)); @@ -1969,16 +1994,15 @@ void intel_edp_psr_exit(struct drm_device *dev) schedule_delayed_work(&dev_priv->psr.work, msecs_to_jiffies(100)); + mutex_unlock(&dev_priv->psr.lock); } void intel_edp_psr_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - if (!HAS_PSR(dev)) - return; - INIT_DELAYED_WORK(&dev_priv->psr.work, intel_edp_psr_work); + mutex_init(&dev_priv->psr.lock); } static void intel_disable_dp(struct intel_encoder *encoder)