drm/i915: Report to userspace if we have a (presumed) working GPU reset
authorChris Wilson <chris@chris-wilson.co.uk>
Mon, 15 Jun 2015 11:23:48 +0000 (12:23 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Mon, 15 Jun 2015 14:59:58 +0000 (16:59 +0200)
In igt, we want to test handling of GPU hangs, both for recovery
purposes and for reporting. However, we don't want to inject a genuine
GPU hang onto a machine that cannot recover and so be permenantly
wedged. Rather than embed heuristics into igt, have the kernel report
exactly when it expects the GPU reset to work.

This can also be usefully extended in future to indicate different
levels of fine-grained resets.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Tim Gore <tim.gore@intel.com>
Cc: Tomas Elf <tomas.elf@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_uncore.c
include/uapi/drm/i915_drm.h

index 34248635c36c0499465499364e1de8bf91cd82ee..88795d2f1819e5bd9e6f6a8f82955d536c5a99e4 100644 (file)
@@ -163,6 +163,11 @@ static int i915_getparam(struct drm_device *dev, void *data,
                if (!value)
                        return -ENODEV;
                break;
+       case I915_PARAM_HAS_GPU_RESET:
+               value = i915.enable_hangcheck &&
+                       i915.reset &&
+                       intel_has_gpu_reset(dev);
+               break;
        default:
                DRM_DEBUG("Unknown parameter %d\n", param->param);
                return -EINVAL;
index 971fc330cc35a3dedf3eed3c4bbb8b1ec82971f1..44efb4deccb5dc1ff0fc959bb779be1547ebe908 100644 (file)
@@ -2594,6 +2594,7 @@ extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
                              unsigned long arg);
 #endif
 extern int intel_gpu_reset(struct drm_device *dev);
+extern bool intel_has_gpu_reset(struct drm_device *dev);
 extern int i915_reset(struct drm_device *dev);
 extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv);
 extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
index a6d8a3ee7750adecb552415c8ffab06d599f46ff..4a86cf007aa0b06dc58a6c69d33f28dee20b5499 100644 (file)
@@ -1455,20 +1455,36 @@ static int gen6_do_reset(struct drm_device *dev)
        return ret;
 }
 
-int intel_gpu_reset(struct drm_device *dev)
+static int (*intel_get_gpu_reset(struct drm_device *dev))(struct drm_device *)
 {
        if (INTEL_INFO(dev)->gen >= 6)
-               return gen6_do_reset(dev);
+               return gen6_do_reset;
        else if (IS_GEN5(dev))
-               return ironlake_do_reset(dev);
+               return ironlake_do_reset;
        else if (IS_G4X(dev))
-               return g4x_do_reset(dev);
+               return g4x_do_reset;
        else if (IS_G33(dev))
-               return g33_do_reset(dev);
+               return g33_do_reset;
        else if (INTEL_INFO(dev)->gen >= 3)
-               return i915_do_reset(dev);
+               return i915_do_reset;
        else
+               return NULL;
+}
+
+int intel_gpu_reset(struct drm_device *dev)
+{
+       int (*reset)(struct drm_device *);
+
+       reset = intel_get_gpu_reset(dev);
+       if (reset == NULL)
                return -ENODEV;
+
+       return reset(dev);
+}
+
+bool intel_has_gpu_reset(struct drm_device *dev)
+{
+       return intel_get_gpu_reset(dev) != NULL;
 }
 
 void intel_uncore_check_errors(struct drm_device *dev)
index 92d61a7c942a905976ded3c30aa5066ab832f1fb..f88cc1cac5d98ddfa0153b89290f85590f9ace56 100644 (file)
@@ -354,6 +354,7 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_REVISION              32
 #define I915_PARAM_SUBSLICE_TOTAL       33
 #define I915_PARAM_EU_TOTAL             34
+#define I915_PARAM_HAS_GPU_RESET        35
 
 typedef struct drm_i915_getparam {
        int param;