Commit cbb465e7 authored by Chris Wilson's avatar Chris Wilson Committed by Eric Anholt

drm/i915: Include instdone[1] in hangcheck

References:

  Bug 26691 - Spurious hangcheck whilst executing a long shader over a
              large vertex buffer
  https://bugs.freedesktop.org/show_bug.cgi?id=26691Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 0b340004
...@@ -286,6 +286,8 @@ typedef struct drm_i915_private { ...@@ -286,6 +286,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_instdone;
uint32_t last_instdone1;
struct drm_mm vram; struct drm_mm vram;
......
...@@ -1229,16 +1229,21 @@ void i915_hangcheck_elapsed(unsigned long data) ...@@ -1229,16 +1229,21 @@ 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; uint32_t acthd, instdone, instdone1;
/* No reset support on this chip yet. */ /* No reset support on this chip yet. */
if (IS_GEN6(dev)) if (IS_GEN6(dev))
return; return;
if (!IS_I965G(dev)) if (!IS_I965G(dev)) {
acthd = I915_READ(ACTHD); acthd = I915_READ(ACTHD);
else instdone = I915_READ(INSTDONE);
instdone1 = 0;
} else {
acthd = I915_READ(ACTHD_I965); acthd = I915_READ(ACTHD_I965);
instdone = I915_READ(INSTDONE_I965);
instdone1 = I915_READ(INSTDONE1);
}
/* If all work is done then ACTHD clearly hasn't advanced. */ /* If all work is done then ACTHD clearly hasn't advanced. */
if (list_empty(&dev_priv->render_ring.request_list) || if (list_empty(&dev_priv->render_ring.request_list) ||
...@@ -1249,21 +1254,24 @@ void i915_hangcheck_elapsed(unsigned long data) ...@@ -1249,21 +1254,24 @@ void i915_hangcheck_elapsed(unsigned long data)
return; return;
} }
if (dev_priv->last_acthd == acthd && dev_priv->hangcheck_count > 0) { if (dev_priv->last_acthd == acthd &&
DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); dev_priv->last_instdone == instdone &&
i915_handle_error(dev, true); dev_priv->last_instdone1 == instdone1) {
return; if (dev_priv->hangcheck_count++ > 1) {
} DRM_ERROR("Hangcheck timer elapsed... GPU hung\n");
i915_handle_error(dev, true);
return;
}
} else {
dev_priv->hangcheck_count = 0;
dev_priv->last_acthd = acthd;
dev_priv->last_instdone = instdone;
dev_priv->last_instdone1 = instdone1;
}
/* Reset timer case chip hangs without another request being added */ /* Reset timer case chip hangs without another request being added */
mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
if (acthd != dev_priv->last_acthd)
dev_priv->hangcheck_count = 0;
else
dev_priv->hangcheck_count++;
dev_priv->last_acthd = acthd;
} }
/* drm_dma.h hooks /* drm_dma.h hooks
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment