aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_debugfs.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2011-12-14 07:57:03 -0500
committerKeith Packard <keithp@keithp.com>2012-01-19 14:51:31 -0500
commit9f1f46a45a681d357d1ceedecec3671a5ae957f4 (patch)
treefbb1ccb3dc2afded75087e2d187a5160e356849f /drivers/gpu/drm/i915/i915_debugfs.c
parent8109021313c7a3d8947677391ce6ab9cd0bb1d28 (diff)
drm/i915: protect force_wake_(get|put) with the gt_lock
The problem this patch solves is that the forcewake accounting necessary for register reads is protected by dev->struct_mutex. But the hangcheck and error_capture code need to access registers without grabbing this mutex because we hold it while waiting for the gpu. So a new lock is required. Because currently the error_state capture is called from the error irq handler and the hangcheck code runs from a timer, it needs to be an irqsafe spinlock (note that the registers used by the irq handler (neglecting the error handling part) only uses registers that don't need the forcewake dance). We could tune this down to a normal spinlock when we rework the error_state capture and hangcheck code to run from a workqueue. But we don't have any read in a fastpath that needs forcewake, so I've decided to not care much about overhead. This prevents tests/gem_hangcheck_forcewake from i-g-t from killing my snb on recent kernels - something must have slightly changed the timings. On previous kernels it only trigger a WARN about the broken locking. v2: Drop the previous patch for the register writes. v3: Improve the commit message per Chris Wilson's suggestions. Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com> Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_debugfs.c')
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index f8b8ed22b4dc..a017b989b1ab 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1398,9 +1398,13 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
1398 struct drm_info_node *node = (struct drm_info_node *) m->private; 1398 struct drm_info_node *node = (struct drm_info_node *) m->private;
1399 struct drm_device *dev = node->minor->dev; 1399 struct drm_device *dev = node->minor->dev;
1400 struct drm_i915_private *dev_priv = dev->dev_private; 1400 struct drm_i915_private *dev_priv = dev->dev_private;
1401 unsigned forcewake_count;
1401 1402
1402 seq_printf(m, "forcewake count = %d\n", 1403 spin_lock_irq(&dev_priv->gt_lock);
1403 atomic_read(&dev_priv->forcewake_count)); 1404 forcewake_count = dev_priv->forcewake_count;
1405 spin_unlock_irq(&dev_priv->gt_lock);
1406
1407 seq_printf(m, "forcewake count = %u\n", forcewake_count);
1404 1408
1405 return 0; 1409 return 0;
1406} 1410}