summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2019-10-31 09:01:04 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2019-11-01 09:44:48 +0000
commit4a3174152147da1159f7135e90e1831fba74da34 (patch)
treecc2788285ac7ab1053c9d8b55e5a25fa6e4e85f1
parent2b73b3503b0a1393ff1e4a214a3f815d2c6dbffb (diff)
drm/i915/gem: Refine occupancy test in kill_context()
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@chris-wilson.co.uk> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com> Cc: Matthew Auld <matthew.auld@intel.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191031090104.22245-1-chris@chris-wilson.co.uk
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_context.c47
1 files changed, 32 insertions, 15 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..de6e55af82cf 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -333,10 +333,8 @@ static bool __cancel_engine(struct intel_engine_cs *engine)
return __reset_engine(engine);
}
-static struct intel_engine_cs *
-active_engine(struct dma_fence *fence, struct intel_context *ce)
+static struct intel_engine_cs *__active_engine(struct i915_request *rq)
{
- struct i915_request *rq = to_request(fence);
struct intel_engine_cs *engine, *locked;
/*
@@ -360,6 +358,29 @@ active_engine(struct dma_fence *fence, struct intel_context *ce)
return engine;
}
+static struct intel_engine_cs *active_engine(struct intel_context *ce)
+{
+ struct intel_engine_cs *engine = NULL;
+ struct i915_request *rq;
+
+ if (!ce->timeline)
+ return NULL;
+
+ 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);
+ if (engine)
+ break;
+ }
+ rcu_read_unlock();
+
+ return engine;
+}
+
static void kill_context(struct i915_gem_context *ctx)
{
struct i915_gem_engines_iter it;
@@ -383,17 +404,15 @@ static void kill_context(struct i915_gem_context *ctx)
*/
for_each_gem_engine(ce, __context_engines_static(ctx), it) {
struct intel_engine_cs *engine;
- struct dma_fence *fence;
-
- 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.
+ */
+ engine = active_engine(ce);
/* First attempt to gracefully cancel the context */
if (engine && !__cancel_engine(engine))
@@ -403,8 +422,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);
}
}