diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2011-11-27 12:58:17 -0500 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-12-19 22:15:48 -0500 |
commit | 097354eb14fa94d31a09c64d640643f58e4a5a9a (patch) | |
tree | 222aeb2a501ddd82c5ec0877fd09ccc0c851c552 /drivers | |
parent | 832afda6a7d7235ef0e09f4ec46736861540da6d (diff) |
drm/i915: check ACTHD of all rings
Otherwise hangcheck spuriously fires when running blitter/bsd-only
workloads.
Contrary to a similar patch by Ben Widawsky this does not check
INSTDONE of the other rings. Chris Wilson implied that in a failure to
detect a hang, most likely because INSTDONE was fluctuating. Thus only
check ACTHD, which as far as I know is rather reliable. Also, blitter
and bsd rings can't launch complex tasks from a single instruction
(like 3D_PRIM on the render with complex or even infinite shaders).
This fixes spurious gpu hang detection when running
tests/gem_hangcheck_forcewake on snb/ivb.
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 13 |
2 files changed, 12 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 554bef7a3b9c..505af3f64a07 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -337,6 +337,8 @@ typedef struct drm_i915_private { | |||
337 | struct timer_list hangcheck_timer; | 337 | struct timer_list hangcheck_timer; |
338 | int hangcheck_count; | 338 | int hangcheck_count; |
339 | uint32_t last_acthd; | 339 | uint32_t last_acthd; |
340 | uint32_t last_acthd_bsd; | ||
341 | uint32_t last_acthd_blt; | ||
340 | uint32_t last_instdone; | 342 | uint32_t last_instdone; |
341 | uint32_t last_instdone1; | 343 | uint32_t last_instdone1; |
342 | 344 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b40004b55977..d47a53b1db84 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1669,7 +1669,7 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1669 | { | 1669 | { |
1670 | struct drm_device *dev = (struct drm_device *)data; | 1670 | struct drm_device *dev = (struct drm_device *)data; |
1671 | drm_i915_private_t *dev_priv = dev->dev_private; | 1671 | drm_i915_private_t *dev_priv = dev->dev_private; |
1672 | uint32_t acthd, instdone, instdone1; | 1672 | uint32_t acthd, instdone, instdone1, acthd_bsd, acthd_blt; |
1673 | bool err = false; | 1673 | bool err = false; |
1674 | 1674 | ||
1675 | if (!i915_enable_hangcheck) | 1675 | if (!i915_enable_hangcheck) |
@@ -1686,16 +1686,21 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1686 | } | 1686 | } |
1687 | 1687 | ||
1688 | if (INTEL_INFO(dev)->gen < 4) { | 1688 | if (INTEL_INFO(dev)->gen < 4) { |
1689 | acthd = I915_READ(ACTHD); | ||
1690 | instdone = I915_READ(INSTDONE); | 1689 | instdone = I915_READ(INSTDONE); |
1691 | instdone1 = 0; | 1690 | instdone1 = 0; |
1692 | } else { | 1691 | } else { |
1693 | acthd = I915_READ(ACTHD_I965); | ||
1694 | instdone = I915_READ(INSTDONE_I965); | 1692 | instdone = I915_READ(INSTDONE_I965); |
1695 | instdone1 = I915_READ(INSTDONE1); | 1693 | instdone1 = I915_READ(INSTDONE1); |
1696 | } | 1694 | } |
1695 | acthd = intel_ring_get_active_head(&dev_priv->ring[RCS]); | ||
1696 | acthd_bsd = HAS_BSD(dev) ? | ||
1697 | intel_ring_get_active_head(&dev_priv->ring[VCS]) : 0; | ||
1698 | acthd_blt = HAS_BLT(dev) ? | ||
1699 | intel_ring_get_active_head(&dev_priv->ring[BCS]) : 0; | ||
1697 | 1700 | ||
1698 | if (dev_priv->last_acthd == acthd && | 1701 | if (dev_priv->last_acthd == acthd && |
1702 | dev_priv->last_acthd_bsd == acthd_bsd && | ||
1703 | dev_priv->last_acthd_blt == acthd_blt && | ||
1699 | dev_priv->last_instdone == instdone && | 1704 | dev_priv->last_instdone == instdone && |
1700 | dev_priv->last_instdone1 == instdone1) { | 1705 | dev_priv->last_instdone1 == instdone1) { |
1701 | if (dev_priv->hangcheck_count++ > 1) { | 1706 | if (dev_priv->hangcheck_count++ > 1) { |
@@ -1727,6 +1732,8 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1727 | dev_priv->hangcheck_count = 0; | 1732 | dev_priv->hangcheck_count = 0; |
1728 | 1733 | ||
1729 | dev_priv->last_acthd = acthd; | 1734 | dev_priv->last_acthd = acthd; |
1735 | dev_priv->last_acthd_bsd = acthd_bsd; | ||
1736 | dev_priv->last_acthd_blt = acthd_blt; | ||
1730 | dev_priv->last_instdone = instdone; | 1737 | dev_priv->last_instdone = instdone; |
1731 | dev_priv->last_instdone1 = instdone1; | 1738 | dev_priv->last_instdone1 = instdone1; |
1732 | } | 1739 | } |