[Intel-gfx] [PATCH 2/7] drm/i915: Introduce engine_skip_context

Mika Kuoppala mika.kuoppala at linux.intel.com
Tue Jan 17 15:59:02 UTC 2017


Add a new function for skipping all pending requests
for a context in order to make engine reset flow more
readable.

Cc: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala at intel.com>
---
 drivers/gpu/drm/i915/i915_gem.c | 59 ++++++++++++++++++++++++-----------------
 1 file changed, 34 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 021d1e9..a83a4cc 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2604,13 +2604,26 @@ i915_gem_find_active_request(struct intel_engine_cs *engine)
 		if (__i915_gem_request_completed(request))
 			continue;
 
+		GEM_BUG_ON(request->engine != engine);
 		return request;
 	}
 
 	return NULL;
 }
 
-static void reset_request(struct drm_i915_gem_request *request)
+void i915_gem_reset_prepare(struct drm_i915_private *dev_priv)
+{
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
+
+	/* Ensure irq handler finishes, and not run again. */
+	for_each_engine(engine, dev_priv, id)
+		tasklet_kill(&engine->irq_tasklet);
+
+	i915_gem_revoke_fences(dev_priv);
+}
+
+static void skip_request(struct drm_i915_gem_request *request)
 {
 	void *vaddr = request->ring->vaddr;
 	u32 head;
@@ -2629,24 +2642,33 @@ static void reset_request(struct drm_i915_gem_request *request)
 	dma_fence_set_error(&request->fence, -EIO);
 }
 
-void i915_gem_reset_prepare(struct drm_i915_private *dev_priv)
+static void engine_skip_context(struct drm_i915_gem_request *request)
 {
-	struct intel_engine_cs *engine;
-	enum intel_engine_id id;
+	struct intel_engine_cs *engine = request->engine;
+	struct i915_gem_context *hung_ctx = request->ctx;
+	struct intel_timeline *timeline;
+	unsigned long flags;
 
-	/* Ensure irq handler finishes, and not run again. */
-	for_each_engine(engine, dev_priv, id)
-		tasklet_kill(&engine->irq_tasklet);
+	timeline = i915_gem_context_lookup_timeline(hung_ctx, engine);
 
-	i915_gem_revoke_fences(dev_priv);
+	spin_lock_irqsave(&engine->timeline->lock, flags);
+	spin_lock(&timeline->lock);
+
+	list_for_each_entry_continue(request, &engine->timeline->requests, link)
+		if (request->ctx == hung_ctx)
+			skip_request(request);
+
+	list_for_each_entry(request, &timeline->requests, link)
+		skip_request(request);
+
+	spin_unlock(&timeline->lock);
+	spin_unlock_irqrestore(&engine->timeline->lock, flags);
 }
 
 static void i915_gem_reset_engine(struct intel_engine_cs *engine)
 {
 	struct drm_i915_gem_request *request;
 	struct i915_gem_context *hung_ctx;
-	struct intel_timeline *timeline;
-	unsigned long flags;
 	bool ring_hung;
 
 	if (engine->irq_seqno_barrier)
@@ -2668,7 +2690,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
 
 	if (ring_hung) {
 		i915_gem_context_mark_guilty(hung_ctx);
-		reset_request(request);
+		skip_request(request);
 	} else {
 		i915_gem_context_mark_innocent(hung_ctx);
 		dma_fence_set_error(&request->fence, -EAGAIN);
@@ -2696,20 +2718,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
 	if (i915_gem_context_is_default(hung_ctx))
 		return;
 
-	timeline = i915_gem_context_lookup_timeline(hung_ctx, engine);
-
-	spin_lock_irqsave(&engine->timeline->lock, flags);
-	spin_lock(&timeline->lock);
-
-	list_for_each_entry_continue(request, &engine->timeline->requests, link)
-		if (request->ctx == hung_ctx)
-			reset_request(request);
-
-	list_for_each_entry(request, &timeline->requests, link)
-		reset_request(request);
-
-	spin_unlock(&timeline->lock);
-	spin_unlock_irqrestore(&engine->timeline->lock, flags);
+	engine_skip_context(request);
 }
 
 void i915_gem_reset_finish(struct drm_i915_private *dev_priv)
-- 
2.7.4



More information about the Intel-gfx mailing list