[Intel-gfx] [PATCH] drm/i915/gem: Refine occupancy test in kill_context()

Chris Wilson chris at chris-wilson.co.uk
Thu Oct 31 08:45:34 UTC 2019


Don't just look at the very last request in a queue when deciding if we
need to evict the context from the GPU, as that request may still be in
the submission queue while the rest of the context is running!

Instead, walk back along the queued requests looking for the active
request and checking that.

Fixes: 2e0986a58cc4 ("drm/i915/gem: Cancel contexts when hangchecking is disabled")
Testcase: igt/gem_ctx_persistence/queued
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Cc: Mika Kuoppala <mika.kuoppala at linux.intel.com>
Cc: Matthew Auld <matthew.auld at intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c | 33 +++++++++++++--------
 1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index cbdf2fb32636..e352863a946d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -334,9 +334,8 @@ static bool __cancel_engine(struct intel_engine_cs *engine)
 }
 
 static struct intel_engine_cs *
-active_engine(struct dma_fence *fence, struct intel_context *ce)
+active_engine(struct i915_request *rq, struct intel_context *ce)
 {
-	struct i915_request *rq = to_request(fence);
 	struct intel_engine_cs *engine, *locked;
 
 	/*
@@ -382,18 +381,30 @@ static void kill_context(struct i915_gem_context *ctx)
 	 * engines on which there are incomplete requests.
 	 */
 	for_each_gem_engine(ce, __context_engines_static(ctx), it) {
-		struct intel_engine_cs *engine;
-		struct dma_fence *fence;
+		struct intel_engine_cs *engine = NULL;
+		struct i915_request *rq;
 
 		if (!ce->timeline)
 			continue;
 
-		fence = i915_active_fence_get(&ce->timeline->last_request);
-		if (!fence)
-			continue;
-
-		/* Check with the backend if the request is still inflight */
-		engine = active_engine(fence, ce);
+		/*
+		 * Check the current active state of this context; if we
+		 * are currently executing on the GPU we need to evict
+		 * ourselves. On the other hand, if we haven't yet been
+		 * submitted to the GPU or if everything is complete,
+		 * we have nothing to do.
+		 */
+		rcu_read_lock();
+		list_for_each_entry_reverse(rq, &ce->timeline->requests, link) {
+			if (i915_request_completed(rq))
+				break;
+
+			/* Check with the backend if the request is inflight */
+			engine = active_engine(rq, ce);
+			if (engine)
+				break;
+		}
+		rcu_read_unlock();
 
 		/* First attempt to gracefully cancel the context */
 		if (engine && !__cancel_engine(engine))
@@ -403,8 +414,6 @@ static void kill_context(struct i915_gem_context *ctx)
 			 * reset. We hope the collateral damage is worth it.
 			 */
 			__reset_context(ctx, engine);
-
-		dma_fence_put(fence);
 	}
 }
 
-- 
2.24.0.rc1



More information about the Intel-gfx mailing list