diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-06-06 07:16:24 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-08-01 22:03:46 -0400 |
commit | cbb465e72ae2cf37d252284c28a0d89ddfaaa240 (patch) | |
tree | 4ea7d5ba990ca20ebb768b2993ca70e37c56b157 /drivers/gpu/drm/i915/i915_irq.c | |
parent | 0b3400040d189b129e9770b7ea2e38729e3d75c4 (diff) |
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=26691
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index fb6b46285471..85785a8844ed 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1229,16 +1229,21 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1229 | { | 1229 | { |
1230 | struct drm_device *dev = (struct drm_device *)data; | 1230 | struct drm_device *dev = (struct drm_device *)data; |
1231 | drm_i915_private_t *dev_priv = dev->dev_private; | 1231 | drm_i915_private_t *dev_priv = dev->dev_private; |
1232 | uint32_t acthd; | 1232 | uint32_t acthd, instdone, instdone1; |
1233 | 1233 | ||
1234 | /* No reset support on this chip yet. */ | 1234 | /* No reset support on this chip yet. */ |
1235 | if (IS_GEN6(dev)) | 1235 | if (IS_GEN6(dev)) |
1236 | return; | 1236 | return; |
1237 | 1237 | ||
1238 | if (!IS_I965G(dev)) | 1238 | if (!IS_I965G(dev)) { |
1239 | acthd = I915_READ(ACTHD); | 1239 | acthd = I915_READ(ACTHD); |
1240 | else | 1240 | instdone = I915_READ(INSTDONE); |
1241 | instdone1 = 0; | ||
1242 | } else { | ||
1241 | acthd = I915_READ(ACTHD_I965); | 1243 | acthd = I915_READ(ACTHD_I965); |
1244 | instdone = I915_READ(INSTDONE_I965); | ||
1245 | instdone1 = I915_READ(INSTDONE1); | ||
1246 | } | ||
1242 | 1247 | ||
1243 | /* If all work is done then ACTHD clearly hasn't advanced. */ | 1248 | /* If all work is done then ACTHD clearly hasn't advanced. */ |
1244 | if (list_empty(&dev_priv->render_ring.request_list) || | 1249 | if (list_empty(&dev_priv->render_ring.request_list) || |
@@ -1249,21 +1254,24 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1249 | return; | 1254 | return; |
1250 | } | 1255 | } |
1251 | 1256 | ||
1252 | if (dev_priv->last_acthd == acthd && dev_priv->hangcheck_count > 0) { | 1257 | if (dev_priv->last_acthd == acthd && |
1253 | DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); | 1258 | dev_priv->last_instdone == instdone && |
1254 | i915_handle_error(dev, true); | 1259 | dev_priv->last_instdone1 == instdone1) { |
1255 | return; | 1260 | if (dev_priv->hangcheck_count++ > 1) { |
1256 | } | 1261 | DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); |
1262 | i915_handle_error(dev, true); | ||
1263 | return; | ||
1264 | } | ||
1265 | } else { | ||
1266 | dev_priv->hangcheck_count = 0; | ||
1267 | |||
1268 | dev_priv->last_acthd = acthd; | ||
1269 | dev_priv->last_instdone = instdone; | ||
1270 | dev_priv->last_instdone1 = instdone1; | ||
1271 | } | ||
1257 | 1272 | ||
1258 | /* Reset timer case chip hangs without another request being added */ | 1273 | /* Reset timer case chip hangs without another request being added */ |
1259 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); | 1274 | mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); |
1260 | |||
1261 | if (acthd != dev_priv->last_acthd) | ||
1262 | dev_priv->hangcheck_count = 0; | ||
1263 | else | ||
1264 | dev_priv->hangcheck_count++; | ||
1265 | |||
1266 | dev_priv->last_acthd = acthd; | ||
1267 | } | 1275 | } |
1268 | 1276 | ||
1269 | /* drm_dma.h hooks | 1277 | /* drm_dma.h hooks |