diff mbox

[03/15] drm/i915: Serialize per-engine resets against new requests

Message ID 20170717091141.23102-3-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Chris Wilson July 17, 2017, 9:11 a.m. UTC
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>
---
 drivers/gpu/drm/i915/i915_drv.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

Comments

Michel Thierry July 17, 2017, 9:58 p.m. UTC | #1
On 17/07/17 02:11, Chris Wilson wrote:
> 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>
> ---
>   drivers/gpu/drm/i915/i915_drv.c | 16 +++++++---------
>   1 file changed, 7 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 901c3ff61527..bc121a46ed9a 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -1955,6 +1955,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
> @@ -1963,15 +1969,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
> @@ -1983,6 +1980,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;
>   }
>   
> 

Reviewed-by: Michel Thierry <michel.thierry@intel.com>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 901c3ff61527..bc121a46ed9a 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1955,6 +1955,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
@@ -1963,15 +1969,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
@@ -1983,6 +1980,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;
 }