[PATCH 33/33] preempt-timeout

Chris Wilson chris at chris-wilson.co.uk
Sun May 19 11:55:09 UTC 2019


---
 drivers/gpu/drm/i915/gt/intel_engine_types.h |  2 +
 drivers/gpu/drm/i915/gt/intel_lrc.c          | 42 ++++++++++++++++----
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 7f093f4b0af0..57125e6f7076 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -190,6 +190,8 @@ struct intel_engine_execlists {
 	 */
 	int queue_priority_hint;
 
+	ktime_t last_submit;
+
 	/**
 	 * @queue: queue of requests, in priority lists
 	 */
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 2b173a19e5fc..f33454df1292 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1218,6 +1218,10 @@ static bool execlists_dequeue(struct intel_engine_cs *engine)
 		*port = execlists_schedule_in(last, port - execlists->pending);
 		memset(port + 1, 0, (last_port - port) * sizeof(*port));
 		execlists_submit_ports(engine);
+
+		execlists->last_submit = ktime_get();
+		mod_timer(&execlists->timer,
+			  jiffies + msecs_to_jiffies_timeout(10));
 	}
 
 	return submit;
@@ -1375,19 +1379,41 @@ static void process_csb(struct intel_engine_cs *engine)
 	invalidate_csb_entries(&buf[0], &buf[num_entries - 1]);
 }
 
-static void __execlists_submission_tasklet(struct intel_engine_cs *const engine)
+static void preempt_reset(struct intel_engine_cs *engine)
 {
-	bool submit;
+	const unsigned int bit = I915_RESET_ENGINE + engine->id;
+	unsigned long *lock = &engine->i915->gpu_error.flags;
+	unsigned long flags;
+
+	if (test_and_set_bit(bit, lock))
+		return;
+
+	tasklet_disable_nosync(&engine->execlists.tasklet);
+	spin_unlock(&engine->active.lock);
+
+	i915_reset_engine(engine, "preemption timed out");
+
+	spin_lock_irqsave(&engine->active.lock, flags);
+	tasklet_enable(&engine->execlists.tasklet);
+
+	clear_bit(bit, lock);
+	wake_up_bit(lock, bit);
+}
 
+static void __execlists_submission_tasklet(struct intel_engine_cs *const engine)
+{
 	lockdep_assert_held(&engine->active.lock);
 
-	do {
-		process_csb(engine);
+	process_csb(engine);
+	if (!engine->execlists.pending[0]) {
+		execlists_dequeue(engine);
+		return;
+	}
 
-		submit = false;
-		if (!engine->execlists.pending[0])
-			submit = execlists_dequeue(engine);
-	} while (submit);
+	if (intel_engine_has_preemption(engine) &&
+	    ktime_after(ktime_get(),
+			engine->execlists.last_submit + 10*1000*1000))
+		preempt_reset(engine);
 }
 
 /*
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list