mirror of
https://github.com/torvalds/linux
synced 2024-10-24 20:29:05 +00:00
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>
This commit is contained in:
parent
832afda6a7
commit
097354eb14
|
@ -337,6 +337,8 @@ typedef struct drm_i915_private {
|
||||||
struct timer_list hangcheck_timer;
|
struct timer_list hangcheck_timer;
|
||||||
int hangcheck_count;
|
int hangcheck_count;
|
||||||
uint32_t last_acthd;
|
uint32_t last_acthd;
|
||||||
|
uint32_t last_acthd_bsd;
|
||||||
|
uint32_t last_acthd_blt;
|
||||||
uint32_t last_instdone;
|
uint32_t last_instdone;
|
||||||
uint32_t last_instdone1;
|
uint32_t last_instdone1;
|
||||||
|
|
||||||
|
|
|
@ -1669,7 +1669,7 @@ void i915_hangcheck_elapsed(unsigned long data)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = (struct drm_device *)data;
|
struct drm_device *dev = (struct drm_device *)data;
|
||||||
drm_i915_private_t *dev_priv = dev->dev_private;
|
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||||
uint32_t acthd, instdone, instdone1;
|
uint32_t acthd, instdone, instdone1, acthd_bsd, acthd_blt;
|
||||||
bool err = false;
|
bool err = false;
|
||||||
|
|
||||||
if (!i915_enable_hangcheck)
|
if (!i915_enable_hangcheck)
|
||||||
|
@ -1686,16 +1686,21 @@ void i915_hangcheck_elapsed(unsigned long data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (INTEL_INFO(dev)->gen < 4) {
|
if (INTEL_INFO(dev)->gen < 4) {
|
||||||
acthd = I915_READ(ACTHD);
|
|
||||||
instdone = I915_READ(INSTDONE);
|
instdone = I915_READ(INSTDONE);
|
||||||
instdone1 = 0;
|
instdone1 = 0;
|
||||||
} else {
|
} else {
|
||||||
acthd = I915_READ(ACTHD_I965);
|
|
||||||
instdone = I915_READ(INSTDONE_I965);
|
instdone = I915_READ(INSTDONE_I965);
|
||||||
instdone1 = I915_READ(INSTDONE1);
|
instdone1 = I915_READ(INSTDONE1);
|
||||||
}
|
}
|
||||||
|
acthd = intel_ring_get_active_head(&dev_priv->ring[RCS]);
|
||||||
|
acthd_bsd = HAS_BSD(dev) ?
|
||||||
|
intel_ring_get_active_head(&dev_priv->ring[VCS]) : 0;
|
||||||
|
acthd_blt = HAS_BLT(dev) ?
|
||||||
|
intel_ring_get_active_head(&dev_priv->ring[BCS]) : 0;
|
||||||
|
|
||||||
if (dev_priv->last_acthd == acthd &&
|
if (dev_priv->last_acthd == acthd &&
|
||||||
|
dev_priv->last_acthd_bsd == acthd_bsd &&
|
||||||
|
dev_priv->last_acthd_blt == acthd_blt &&
|
||||||
dev_priv->last_instdone == instdone &&
|
dev_priv->last_instdone == instdone &&
|
||||||
dev_priv->last_instdone1 == instdone1) {
|
dev_priv->last_instdone1 == instdone1) {
|
||||||
if (dev_priv->hangcheck_count++ > 1) {
|
if (dev_priv->hangcheck_count++ > 1) {
|
||||||
|
@ -1727,6 +1732,8 @@ void i915_hangcheck_elapsed(unsigned long data)
|
||||||
dev_priv->hangcheck_count = 0;
|
dev_priv->hangcheck_count = 0;
|
||||||
|
|
||||||
dev_priv->last_acthd = acthd;
|
dev_priv->last_acthd = acthd;
|
||||||
|
dev_priv->last_acthd_bsd = acthd_bsd;
|
||||||
|
dev_priv->last_acthd_blt = acthd_blt;
|
||||||
dev_priv->last_instdone = instdone;
|
dev_priv->last_instdone = instdone;
|
||||||
dev_priv->last_instdone1 = instdone1;
|
dev_priv->last_instdone1 = instdone1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue