aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-07-21 13:32:21 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2017-07-21 15:05:15 +0100
commit4dc3af0169888cc1e3d08f8ba2d1164001fdc194 (patch)
treee062892a20479043168e0bf313c638bb76609d29 /drivers/gpu
parent806313bfff0f7313e1fd75aecfc52275e9b9f89d (diff)
drm/i915: Serialize per-engine resets against new requests
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
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 853d6741d3a5..6753fc861dbb 100644
--- 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_engine_cs *engine)
}
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_engine_cs *engine)
*/
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_engine_cs *engine)
error->reset_engine_count[engine->id]++;
out:
+ i915_gem_reset_finish_engine(engine);
return ret;
}