[PATCH 37/46] drm/i915/gt: Update engine->breadcrumbs after virtual engine transfer

Chris Wilson chris at chris-wilson.co.uk
Sun Feb 7 19:59:58 UTC 2021


Maintain ce->engine->breadcrumbs to pointer to the physical engine after
we transfer the virtual engine to a sibling. This ensures that we always
have a stable backpointer when enabling/cancelling the breadcrumb.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gt/intel_breadcrumbs.c       |  4 ++--
 .../gpu/drm/i915/gt/intel_execlists_submission.c  | 15 +++++++--------
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
index 2527182b642e..d81fb7bd3eb7 100644
--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
@@ -415,8 +415,8 @@ static void irq_signal_request(struct i915_request *rq,
 
 static void insert_breadcrumb(struct i915_request *rq)
 {
-	struct intel_breadcrumbs *b = READ_ONCE(rq->engine)->breadcrumbs;
 	struct intel_context *ce = rq->context;
+	struct intel_breadcrumbs *b = ce->engine->breadcrumbs;
 	struct list_head *pos;
 
 	if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags))
@@ -501,8 +501,8 @@ bool i915_request_enable_breadcrumb(struct i915_request *rq)
 
 void i915_request_cancel_breadcrumb(struct i915_request *rq)
 {
-	struct intel_breadcrumbs *b = READ_ONCE(rq->engine)->breadcrumbs;
 	struct intel_context *ce = rq->context;
+	struct intel_breadcrumbs *b = ce->engine->breadcrumbs;
 	bool release;
 
 	spin_lock(&ce->signal_lock);
diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index 72278c5394ff..c8399042a21d 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -997,6 +997,7 @@ static void virtual_xfer_context(struct virtual_engine *ve,
 	if (!list_empty(&ve->context.signals))
 		intel_context_remove_breadcrumbs(&ve->context,
 						 ve->siblings[0]->breadcrumbs);
+	ve->base.breadcrumbs = engine->breadcrumbs;
 
 	GEM_BUG_ON(READ_ONCE(ve->context.inflight));
 	if (!intel_engine_has_relative_mmio(engine))
@@ -3079,7 +3080,6 @@ static void rcu_virtual_context_destroy(struct work_struct *wrk)
 	lrc_fini(&ve->context);
 	intel_context_fini(&ve->context);
 
-	intel_breadcrumbs_free(ve->base.breadcrumbs);
 	intel_engine_free_request_pool(&ve->base);
 
 	kfree(ve->bonds);
@@ -3107,7 +3107,8 @@ static void virtual_context_destroy(struct kref *kref)
 	queue_rcu_work(system_wq, &ve->rcu);
 }
 
-static void virtual_engine_initial_hint(struct virtual_engine *ve)
+static struct intel_engine_cs *
+virtual_engine_initial_hint(struct virtual_engine *ve)
 {
 	int swp;
 
@@ -3127,6 +3128,8 @@ static void virtual_engine_initial_hint(struct virtual_engine *ve)
 	swp = prandom_u32_max(ve->num_siblings);
 	if (swp)
 		swap(ve->siblings[swp], ve->siblings[0]);
+
+	return ve->siblings[0];
 }
 
 static int virtual_context_alloc(struct intel_context *ce)
@@ -3378,11 +3381,6 @@ intel_execlists_create_virtual(struct intel_engine_cs **siblings,
 
 	intel_context_init(&ve->context, &ve->base);
 
-	ve->base.breadcrumbs = intel_breadcrumbs_create(NULL);
-	if (!ve->base.breadcrumbs) {
-		err = -ENOMEM;
-		goto err_put;
-	}
 
 	sched = ~0U;
 	for (n = 0; n < count; n++) {
@@ -3462,7 +3460,8 @@ intel_execlists_create_virtual(struct intel_engine_cs **siblings,
 	ve->base.sched.revoke_context = execlists_revoke_context;
 	tasklet_setup(&ve->base.sched.tasklet, virtual_submission_tasklet);
 
-	virtual_engine_initial_hint(ve);
+	ve->base.breadcrumbs = virtual_engine_initial_hint(ve)->breadcrumbs;
+
 	return &ve->context;
 
 err_put:
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list