Blob Blame History Raw
From c64992e035d7cb2b469f933e33ee89625df97df5 Mon Sep 17 00:00:00 2001
From: Michel Thierry <michel.thierry@intel.com>
Date: Tue, 20 Jun 2017 10:57:44 +0100
Subject: [PATCH] drm/i915: Look for active requests earlier in the reset path
Git-commit: c64992e035d7cb2b469f933e33ee89625df97df5
Patch-mainline: v4.14-rc1
References: FATE#322643 bsc#1055900

And store the active request so that we only search for it once.

V2: Check for request completion inside _prepare_engine, don't use
ECANCELED, remove unnecessary null checks (Chris).

V3: Capture active requests during reset_prepare and store it the
engine hangcheck obj.

V4: Rename commit, change i915_gem_reset_request to just confirm the
active_request is still incomplete, instead of engine_stalled (Chris).

V5: With style; pass the active request to gem_reset_engine, keep single
return in reset_prepare_engine (Chris).

V6: Moved before reset-engine code appears (Chris)

Suggested-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> (v5)
Signed-off-by: Michel Thierry <michel.thierry@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170615201828.23144-2-michel.thierry@intel.com
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20170620095751.13127-3-chris@chris-wilson.co.uk
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/gpu/drm/i915/i915_gem.c         |   15 ++++++++-------
 drivers/gpu/drm/i915/intel_ringbuffer.h |    1 +
 2 files changed, 9 insertions(+), 7 deletions(-)

--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2840,7 +2840,7 @@ int i915_gem_reset_prepare(struct drm_i9
 
 	/* Ensure irq handler finishes, and not run again. */
 	for_each_engine(engine, dev_priv, id) {
-		struct drm_i915_gem_request *request;
+		struct drm_i915_gem_request *request = NULL;
 
 		/* Prevent the signaler thread from updating the request
 		 * state (by calling dma_fence_signal) as we are processing
@@ -2872,6 +2872,8 @@ int i915_gem_reset_prepare(struct drm_i9
 			if (request && request->fence.error == -EIO)
 				err = -EIO; /* Previous reset failed! */
 		}
+
+		engine->hangcheck.active_request = request;
 	}
 
 	i915_gem_revoke_fences(dev_priv);
@@ -2925,7 +2927,7 @@ static void engine_skip_context(struct d
 static bool i915_gem_reset_request(struct drm_i915_gem_request *request)
 {
 	/* Read once and return the resolution */
-	const bool guilty = engine_stalled(request->engine);
+	const bool guilty = !i915_gem_request_completed(request);
 
 	/* The guilty request will get skipped on a hung engine.
 	 *
@@ -2959,11 +2961,9 @@ static bool i915_gem_reset_request(struc
 	return guilty;
 }
 
-static void i915_gem_reset_engine(struct intel_engine_cs *engine)
+static void i915_gem_reset_engine(struct intel_engine_cs *engine,
+				  struct drm_i915_gem_request *request)
 {
-	struct drm_i915_gem_request *request;
-
-	request = i915_gem_find_active_request(engine);
 	if (request && i915_gem_reset_request(request)) {
 		DRM_DEBUG_DRIVER("resetting %s to restart from tail of request 0x%x\n",
 				 engine->name, request->global_seqno);
@@ -2989,7 +2989,7 @@ void i915_gem_reset(struct drm_i915_priv
 	for_each_engine(engine, dev_priv, id) {
 		struct i915_gem_context *ctx;
 
-		i915_gem_reset_engine(engine);
+		i915_gem_reset_engine(engine, engine->hangcheck.active_request);
 		ctx = fetch_and_zero(&engine->last_retired_context);
 		if (ctx)
 			engine->context_unpin(engine, ctx);
@@ -3013,6 +3013,7 @@ void i915_gem_reset_finish(struct drm_i9
 	lockdep_assert_held(&dev_priv->drm.struct_mutex);
 
 	for_each_engine(engine, dev_priv, id) {
+		engine->hangcheck.active_request = NULL;
 		tasklet_enable(&engine->irq_tasklet);
 		kthread_unpark(engine->breadcrumbs.signaler);
 	}
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -121,6 +121,7 @@ struct intel_engine_hangcheck {
 	unsigned long action_timestamp;
 	int deadlock;
 	struct intel_instdone instdone;
+	struct drm_i915_gem_request *active_request;
 	bool stalled;
 };