[PATCH 12/13] drm/i915: Perform device reset under stop-machine
Chris Wilson
chris at chris-wilson.co.uk
Sat Jul 21 10:22:16 UTC 2018
If we do a device level reset, we lose vital registers that may be in
concurrent use by userspace (i.e. the GGTT and its fencing). To be
paranoid and prevent that memory access from being corrupted, we want to
pause all other processes/threads, so that the device reset is the only
thing running on the system.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_reset.c | 58 +++++++++++++++++++------------
1 file changed, 36 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reset.c b/drivers/gpu/drm/i915/i915_reset.c
index 5e1bf30ec6cf..25676e6ac2ef 100644
--- a/drivers/gpu/drm/i915/i915_reset.c
+++ b/drivers/gpu/drm/i915/i915_reset.c
@@ -5,6 +5,7 @@
*/
#include <linux/sched/mm.h>
+#include <linux/stop_machine.h>
#include "i915_drv.h"
#include "i915_gpu_error.h"
@@ -848,6 +849,40 @@ bool i915_gem_unset_wedged(struct drm_i915_private *i915)
return true;
}
+struct __i915_reset {
+ struct drm_i915_private *i915;
+ unsigned int stalled_mask;
+};
+
+static int __i915_reset__BKL(void *data)
+{
+ struct __i915_reset *arg = data;
+ int i, err;
+
+ for (i = 0; i < 3; i++) {
+ err = intel_gpu_reset(arg->i915, ALL_ENGINES);
+ if (!err)
+ break;
+
+ mdelay(100);
+ }
+ if (err)
+ return err;
+
+ /* Ok, now get things going again... */
+
+ /*
+ * Everything depends on having the GTT running, so we need to start
+ * there.
+ */
+ err = i915_ggtt_enable_hw(arg->i915);
+ if (err)
+ return err;
+
+ gt_reset(arg->i915, arg->stalled_mask);
+ return 0;
+}
+
/**
* i915_reset - reset chip after a hang
* @i915: #drm_i915_private to reset
@@ -873,7 +908,6 @@ void i915_reset(struct drm_i915_private *i915,
{
struct i915_gpu_error *error = &i915->gpu_error;
int ret;
- int i;
GEM_TRACE("flags=%lx\n", error->flags);
@@ -908,32 +942,12 @@ void i915_reset(struct drm_i915_private *i915,
goto error;
}
- for (i = 0; i < 3; i++) {
- ret = intel_gpu_reset(i915, ALL_ENGINES);
- if (ret == 0)
- break;
-
- msleep(100);
- }
+ ret = stop_machine(__i915_reset__BKL, i915, NULL);
if (ret) {
dev_err(i915->drm.dev, "Failed to reset chip\n");
goto taint;
}
- /* Ok, now get things going again... */
-
- /*
- * Everything depends on having the GTT running, so we need to start
- * there.
- */
- ret = i915_ggtt_enable_hw(i915);
- if (ret) {
- DRM_ERROR("Failed to re-enable GGTT following reset (%d)\n",
- ret);
- goto error;
- }
-
- gt_reset(i915, stalled_mask);
intel_overlay_reset(i915);
/*
--
2.18.0
More information about the Intel-gfx-trybot
mailing list