Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 097354eb authored by Daniel Vetter's avatar Daniel Vetter Committed by Keith Packard
Browse files

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: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
parent 832afda6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -337,6 +337,8 @@ typedef struct drm_i915_private {
	struct timer_list hangcheck_timer;
	int hangcheck_count;
	uint32_t last_acthd;
	uint32_t last_acthd_bsd;
	uint32_t last_acthd_blt;
	uint32_t last_instdone;
	uint32_t last_instdone1;

+10 −3
Original line number Diff line number Diff line
@@ -1669,7 +1669,7 @@ void i915_hangcheck_elapsed(unsigned long data)
{
	struct drm_device *dev = (struct drm_device *)data;
	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;

	if (!i915_enable_hangcheck)
@@ -1686,16 +1686,21 @@ void i915_hangcheck_elapsed(unsigned long data)
	}

	if (INTEL_INFO(dev)->gen < 4) {
		acthd = I915_READ(ACTHD);
		instdone = I915_READ(INSTDONE);
		instdone1 = 0;
	} else {
		acthd = I915_READ(ACTHD_I965);
		instdone = I915_READ(INSTDONE_I965);
		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 &&
	    dev_priv->last_acthd_bsd == acthd_bsd &&
	    dev_priv->last_acthd_blt == acthd_blt &&
	    dev_priv->last_instdone == instdone &&
	    dev_priv->last_instdone1 == instdone1) {
		if (dev_priv->hangcheck_count++ > 1) {
@@ -1727,6 +1732,8 @@ void i915_hangcheck_elapsed(unsigned long data)
		dev_priv->hangcheck_count = 0;

		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_instdone1 = instdone1;
	}