Blob Blame History Raw
From 523e7c9278f0a2ca6174319e33f255161e74d16c Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Sat, 16 Sep 2017 21:44:11 +0100
Subject: [PATCH] drm/i915/execlists: Kick start request processing after a reset
Mime-version: 1.0
Content-type: text/plain; charset=UTF-8
Content-transfer-encoding: 8bit
Git-commit: 523e7c9278f0a2ca6174319e33f255161e74d16c
Patch-mainline: v4.15-rc1
References: FATE#322643 bsc#1055900

During a reset, we may skip over completed requests and lost
context-switch interrupts. Following the reset, we may then may end up
with no active requests in the ELSP (and so do not resubmit to restart
the engine), but have a queue of requests ready for execution. This is
unlikely, it requires the last request to complete after the hang is
detected, but not impossible. The outcome of this is that the engine
stalls, possibly leading to full ring and indefinite wait under
struct_mutex, eventually leading to a full driver hang.

Alternatively, we can solve this by unsubmitting the incomplete requests
and just kickstarting the tasklet. Michał has patches for that, which I
initially disliked due to the extra complexity, but the complexity of
this "simple" restart is growing...

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Michał Winiarski <michal.winiarski@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170916204414.32762-1-chris@chris-wilson.co.uk
Reviewed-by: Michał Winiarski <michal.winiarski@intel.com>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/gpu/drm/i915/intel_lrc.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1357,8 +1357,12 @@ static int gen8_init_common_ring(struct
 		submit = true;
 	}
 
-	if (submit && !i915.enable_guc_submission)
-		execlists_submit_ports(engine);
+	if (!i915.enable_guc_submission) {
+		if (submit)
+			execlists_submit_ports(engine);
+		else if (engine->execlist_first)
+			tasklet_schedule(&engine->irq_tasklet);
+	}
 
 	return 0;
 }