| From 01654de70fb4664215a98b55e0d8746cd81aa08e Mon Sep 17 00:00:00 2001 |
| From: Chris Wilson <chris@chris-wilson.co.uk> |
| Date: Tue, 28 May 2013 10:38:44 +0100 |
| Subject: drm/i915: Avoid promoting a simulated hang to 'wedged' |
| |
| It appears that a beneficial side-effect of Mika's more accurate hangman |
| work is to speed up hang detection and execution. This exposes a bug in |
| the reset code that then treats repeated simulated hangs as an |
| indication that the machine is wedged. Jiggle the code around so that we |
| only do the simulation processing from the hangcheck and avoid confusing |
| it with a real hang. |
| |
| Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65060 |
| Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> |
| Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| (cherry picked from commit 2e7c8ee7a6bf3440478120f14cbf597d416f88b2) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| drivers/gpu/drm/i915/i915_drv.c | 55 +++++++++++++++++------------------------ |
| 1 file changed, 23 insertions(+), 32 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c |
| index daf727e79ded..94492d1cdb0c 100644 |
| --- a/drivers/gpu/drm/i915/i915_drv.c |
| +++ b/drivers/gpu/drm/i915/i915_drv.c |
| @@ -863,37 +863,14 @@ static int gen6_do_reset(struct drm_device *dev) |
| |
| int intel_gpu_reset(struct drm_device *dev) |
| { |
| - struct drm_i915_private *dev_priv = dev->dev_private; |
| - int ret = -ENODEV; |
| - |
| switch (INTEL_INFO(dev)->gen) { |
| case 7: |
| - case 6: |
| - ret = gen6_do_reset(dev); |
| - break; |
| - case 5: |
| - ret = ironlake_do_reset(dev); |
| - break; |
| - case 4: |
| - ret = i965_do_reset(dev); |
| - break; |
| - case 2: |
| - ret = i8xx_do_reset(dev); |
| - break; |
| - } |
| - |
| - /* Also reset the gpu hangman. */ |
| - if (dev_priv->gpu_error.stop_rings) { |
| - DRM_INFO("Simulated gpu hang, resetting stop_rings\n"); |
| - dev_priv->gpu_error.stop_rings = 0; |
| - if (ret == -ENODEV) { |
| - DRM_ERROR("Reset not implemented, but ignoring " |
| - "error for simulated gpu hangs\n"); |
| - ret = 0; |
| - } |
| + case 6: return gen6_do_reset(dev); |
| + case 5: return ironlake_do_reset(dev); |
| + case 4: return i965_do_reset(dev); |
| + case 2: return i8xx_do_reset(dev); |
| + default: return -ENODEV; |
| } |
| - |
| - return ret; |
| } |
| |
| /** |
| @@ -914,6 +891,7 @@ int intel_gpu_reset(struct drm_device *dev) |
| int i915_reset(struct drm_device *dev) |
| { |
| drm_i915_private_t *dev_priv = dev->dev_private; |
| + bool simulated; |
| int ret; |
| |
| if (!i915_try_reset) |
| @@ -923,13 +901,26 @@ int i915_reset(struct drm_device *dev) |
| |
| i915_gem_reset(dev); |
| |
| - ret = -ENODEV; |
| - if (get_seconds() - dev_priv->gpu_error.last_reset < 5) |
| + simulated = dev_priv->gpu_error.stop_rings != 0; |
| + |
| + if (!simulated && get_seconds() - dev_priv->gpu_error.last_reset < 5) { |
| DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); |
| - else |
| + ret = -ENODEV; |
| + } else { |
| ret = intel_gpu_reset(dev); |
| |
| - dev_priv->gpu_error.last_reset = get_seconds(); |
| + /* Also reset the gpu hangman. */ |
| + if (simulated) { |
| + DRM_INFO("Simulated gpu hang, resetting stop_rings\n"); |
| + dev_priv->gpu_error.stop_rings = 0; |
| + if (ret == -ENODEV) { |
| + DRM_ERROR("Reset not implemented, but ignoring " |
| + "error for simulated gpu hangs\n"); |
| + ret = 0; |
| + } |
| + } else |
| + dev_priv->gpu_error.last_reset = get_seconds(); |
| + } |
| if (ret) { |
| DRM_ERROR("Failed to reset chip.\n"); |
| mutex_unlock(&dev->struct_mutex); |
| -- |
| 1.8.5.rc3 |
| |