From 0364cd19d61caad7292cc4e87f5001595b6c7642 Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Fri, 21 Jul 2017 13:32:21 +0100
Subject: [PATCH] drm/i915: Serialize per-engine resets against new requests
Git-commit: 0364cd19d61caad7292cc4e87f5001595b6c7642
Patch-mainline: v4.14-rc1
References: FATE#322643 bsc#1055900
We rely on disabling the execlists (by stopping the tasklet) to prevent
new requests from submitting to the engine ELSP before we are ready.
However, we re-enable the engine before we call init_hw which gives
userspace the opportunity to subit a new request which is then
overwritten by init_hw -- but not before the HW may have started
executing. The subsequent out-of-order CSB is detected by our sanity
checks in intel_lrc_irq_handler().
Fixes: a1ef70e14453 ("drm/i915: Add support for per engine reset recovery")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Michel Thierry <michel.thierry@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: Michel Thierry <michel.thierry@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170721123238.16428-3-chris@chris-wilson.co.uk
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Takashi Iwai <tiwai@suse.de>
---
drivers/gpu/drm/i915/i915_drv.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1951,6 +1951,12 @@ int i915_reset_engine(struct intel_engin
}
ret = intel_gpu_reset(engine->i915, intel_engine_flag(engine));
+ if (ret) {
+ /* If we fail here, we expect to fallback to a global reset */
+ DRM_DEBUG_DRIVER("Failed to reset %s, ret=%d\n",
+ engine->name, ret);
+ goto out;
+ }
/*
* The request that caused the hang is stuck on elsp, we know the
@@ -1959,15 +1965,6 @@ int i915_reset_engine(struct intel_engin
*/
i915_gem_reset_engine(engine, active_request);
- i915_gem_reset_finish_engine(engine);
-
- if (ret) {
- /* If we fail here, we expect to fallback to a global reset */
- DRM_DEBUG_DRIVER("Failed to reset %s, ret=%d\n",
- engine->name, ret);
- goto out;
- }
-
/*
* The engine and its registers (and workarounds in case of render)
* have been reset to their default values. Follow the init_ring
@@ -1979,6 +1976,7 @@ int i915_reset_engine(struct intel_engin
error->reset_engine_count[engine->id]++;
out:
+ i915_gem_reset_finish_engine(engine);
return ret;
}