From patchwork Fri Nov 2 18:14:01 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Barnes X-Patchwork-Id: 1690121 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id 769DC3FCA5 for ; Fri, 2 Nov 2012 18:15:26 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A9ECF9F316 for ; Fri, 2 Nov 2012 11:15:26 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from oproxy7-pub.bluehost.com (oproxy7-pub.bluehost.com [67.222.55.9]) by gabe.freedesktop.org (Postfix) with SMTP id 272D99E806 for ; Fri, 2 Nov 2012 11:14:10 -0700 (PDT) Received: (qmail 5706 invoked by uid 0); 2 Nov 2012 18:14:09 -0000 Received: from unknown (HELO box514.bluehost.com) (74.220.219.114) by oproxy7.bluehost.com with SMTP; 2 Nov 2012 18:14:09 -0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuousgeek.org; s=default; h=References:In-Reply-To:Message-Id:Date:Subject:To:From; bh=ACJVMifjtiXxCUl0nxbwlxkbvAfcMIxzglxbw30p3oE=; b=kp1Belrs1HmcL8Jtd6AQtFauK+KGyeLPtEA8hb/42a0E6lBEKNaQ1Ax8uFznHdx/juqBG0rzJVpYog99TxW7bUQYyaFoHxaRtyPrOtrOw1UmQHKaZkIlzyYSv5uJPODu; Received: from [67.161.37.189] (port=37589 helo=localhost.localdomain) by box514.bluehost.com with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.76) (envelope-from ) id 1TULkt-000850-Dm for intel-gfx@lists.freedesktop.org; Fri, 02 Nov 2012 12:14:07 -0600 From: Jesse Barnes To: intel-gfx@lists.freedesktop.org Date: Fri, 2 Nov 2012 11:14:01 -0700 Message-Id: <1351880042-24935-3-git-send-email-jbarnes@virtuousgeek.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1351880042-24935-1-git-send-email-jbarnes@virtuousgeek.org> References: <1351880042-24935-1-git-send-email-jbarnes@virtuousgeek.org> X-Identified-User: {10642:box514.bluehost.com:virtuous:virtuousgeek.org} {sentby:smtp auth 67.161.37.189 authed with jbarnes@virtuousgeek.org} Subject: [Intel-gfx] [PATCH 3/4] drm/i915: protect RPS/RC6 related accesses (including PCU) with a new mutex X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org This allows the power related code to run independently of the rest of the pipeline, extending the resume and init time improvements into userspace, which would otherwise have been blocked on the struct mutex if we were doing PCU communication. Suggested-by: Daniel Vetter Signed-off-by: Jesse Barnes --- drivers/gpu/drm/i915/i915_debugfs.c | 20 ++++++++++---------- drivers/gpu/drm/i915/i915_dma.c | 2 ++ drivers/gpu/drm/i915/i915_drv.h | 6 ++++++ drivers/gpu/drm/i915/i915_irq.c | 4 ++-- drivers/gpu/drm/i915/intel_pm.c | 16 +++++++++------- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0e405e5..2cae435 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1280,7 +1280,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) return 0; } - ret = mutex_lock_interruptible(&dev->struct_mutex); + ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); if (ret) return ret; @@ -1296,7 +1296,7 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) seq_printf(m, "%d\t\t%d\n", gpu_freq * GT_FREQUENCY_MULTIPLIER, ia_freq * 100); } - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&dev_priv->rps.hw_lock); return 0; } @@ -1713,13 +1713,13 @@ i915_max_freq_read(struct file *filp, if (!(IS_GEN6(dev) || IS_GEN7(dev))) return -ENODEV; - ret = mutex_lock_interruptible(&dev->struct_mutex); + ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); if (ret) return ret; len = snprintf(buf, sizeof(buf), "max freq: %d\n", dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER); - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&dev_priv->rps.hw_lock); if (len > sizeof(buf)) len = sizeof(buf); @@ -1754,7 +1754,7 @@ i915_max_freq_write(struct file *filp, DRM_DEBUG_DRIVER("Manually setting max freq to %d\n", val); - ret = mutex_lock_interruptible(&dev->struct_mutex); + ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); if (ret) return ret; @@ -1764,7 +1764,7 @@ i915_max_freq_write(struct file *filp, dev_priv->rps.max_delay = val / GT_FREQUENCY_MULTIPLIER; gen6_set_rps(dev, val / GT_FREQUENCY_MULTIPLIER); - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&dev_priv->rps.hw_lock); return cnt; } @@ -1789,13 +1789,13 @@ i915_min_freq_read(struct file *filp, char __user *ubuf, size_t max, if (!(IS_GEN6(dev) || IS_GEN7(dev))) return -ENODEV; - ret = mutex_lock_interruptible(&dev->struct_mutex); + ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); if (ret) return ret; len = snprintf(buf, sizeof(buf), "min freq: %d\n", dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER); - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&dev_priv->rps.hw_lock); if (len > sizeof(buf)) len = sizeof(buf); @@ -1828,7 +1828,7 @@ i915_min_freq_write(struct file *filp, const char __user *ubuf, size_t cnt, DRM_DEBUG_DRIVER("Manually setting min freq to %d\n", val); - ret = mutex_lock_interruptible(&dev->struct_mutex); + ret = mutex_lock_interruptible(&dev_priv->rps.hw_lock); if (ret) return ret; @@ -1838,7 +1838,7 @@ i915_min_freq_write(struct file *filp, const char __user *ubuf, size_t cnt, dev_priv->rps.min_delay = val / GT_FREQUENCY_MULTIPLIER; gen6_set_rps(dev, val / GT_FREQUENCY_MULTIPLIER); - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&dev_priv->rps.hw_lock); return cnt; } diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 14526dc..1ce7e49 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1625,6 +1625,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) spin_lock_init(&dev_priv->rps.lock); spin_lock_init(&dev_priv->dpio_lock); + mutex_init(&dev_priv->rps.hw_lock); + if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) dev_priv->num_pipe = 3; else if (IS_MOBILE(dev) || !IS_GEN2(dev)) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2f01de8..b41a90b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -850,6 +850,12 @@ typedef struct drm_i915_private { u8 cur_delay; u8 min_delay; u8 max_delay; + + /* + * Protects RPS/RC6 register access and PCU communication. + * Must be taken after struct_mutex if nested. + */ + struct mutex hw_lock; } rps; /* ilk-only ips/rps state. Everything in here is protected by the global diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b92e6bfb..ad99b10 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -378,7 +378,7 @@ static void gen6_pm_rps_work(struct work_struct *work) if ((pm_iir & GEN6_PM_DEFERRED_EVENTS) == 0) return; - mutex_lock(&dev_priv->dev->struct_mutex); + mutex_lock(&dev_priv->rps.hw_lock); if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) new_delay = dev_priv->rps.cur_delay + 1; @@ -393,7 +393,7 @@ static void gen6_pm_rps_work(struct work_struct *work) gen6_set_rps(dev_priv->dev, new_delay); } - mutex_unlock(&dev_priv->dev->struct_mutex); + mutex_unlock(&dev_priv->rps.hw_lock); } diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6648dba4..cb7043a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2323,7 +2323,7 @@ void gen6_set_rps(struct drm_device *dev, u8 val) struct drm_i915_private *dev_priv = dev->dev_private; u32 limits = gen6_rps_limits(dev_priv, &val); - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); WARN_ON(val > dev_priv->rps.max_delay); WARN_ON(val < dev_priv->rps.min_delay); @@ -2409,7 +2409,7 @@ static void gen6_enable_rps(struct drm_device *dev) int rc6_mode; int i, ret; - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); /* Here begins a magic sequence of register writes to enable * auto-downclocking. @@ -2550,7 +2550,7 @@ static void gen6_update_ring_freq(struct drm_device *dev) int gpu_freq, ia_freq, max_ia_freq; int scaling_factor = 180; - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); max_ia_freq = cpufreq_quick_get_max(0); /* @@ -3311,7 +3311,9 @@ void intel_disable_gt_powersave(struct drm_device *dev) ironlake_disable_rc6(dev); } else if (INTEL_INFO(dev)->gen >= 6 && !IS_VALLEYVIEW(dev)) { cancel_delayed_work_sync(&dev_priv->gen6_power_work); + mutex_lock(&dev_priv->rps.hw_lock); gen6_disable_rps(dev); + mutex_unlock(&dev_priv->rps.hw_lock); } } @@ -3322,10 +3324,10 @@ static void intel_gen6_powersave_work(struct work_struct *work) gen6_power_work.work); struct drm_device *dev = dev_priv->dev; - mutex_lock(&dev->struct_mutex); + mutex_lock(&dev_priv->rps.hw_lock); gen6_enable_rps(dev); gen6_update_ring_freq(dev); - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&dev_priv->rps.hw_lock); } void intel_enable_gt_powersave(struct drm_device *dev) @@ -4212,7 +4214,7 @@ void intel_gt_init(struct drm_device *dev) int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) { - WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); if (I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) { DRM_DEBUG_DRIVER("warning: pcode (read) mailbox access failed\n"); @@ -4236,7 +4238,7 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val) int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) { - WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); if (I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) { DRM_DEBUG_DRIVER("warning: pcode (write) mailbox access failed\n");