[PATCH 18/19] retire-req

Chris Wilson chris at chris-wilson.co.uk
Mon May 21 13:13:18 UTC 2018


---
 drivers/gpu/drm/i915/i915_request.c         |  8 ++---
 drivers/gpu/drm/i915/intel_guc_submission.c | 33 ++++++++++++++++-----
 drivers/gpu/drm/i915/intel_lrc.c            | 29 ++++++++++++------
 drivers/gpu/drm/i915/intel_ringbuffer.c     | 13 ++++++++
 drivers/gpu/drm/i915/intel_ringbuffer.h     |  1 +
 5 files changed, 63 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
index fc499bcbd105..f40d755d7031 100644
--- a/drivers/gpu/drm/i915/i915_request.c
+++ b/drivers/gpu/drm/i915/i915_request.c
@@ -356,11 +356,6 @@ static void __retire_engine_request(struct intel_engine_cs *engine,
 
 	local_irq_disable();
 
-	spin_lock(&engine->timeline.lock);
-	GEM_BUG_ON(!list_is_first(&rq->link, &engine->timeline.requests));
-	list_del_init(&rq->link);
-	spin_unlock(&engine->timeline.lock);
-
 	spin_lock(&rq->lock);
 	if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags))
 		dma_fence_signal_locked(&rq->fence);
@@ -372,6 +367,9 @@ static void __retire_engine_request(struct intel_engine_cs *engine,
 	}
 	spin_unlock(&rq->lock);
 
+	engine->retire_request(rq);
+	GEM_BUG_ON(!list_empty(&rq->link));
+
 	local_irq_enable();
 
 	/*
diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c
index da54e2a521cf..6d8647318565 100644
--- a/drivers/gpu/drm/i915/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/intel_guc_submission.c
@@ -670,7 +670,7 @@ static void port_assign(struct execlist_port *port, struct i915_request *rq)
 {
 	GEM_BUG_ON(port_isset(port));
 
-	port_set(port, i915_request_get(rq));
+	port_set(port, rq);
 }
 
 static inline int rq_prio(const struct i915_request *rq)
@@ -793,16 +793,13 @@ static void guc_submission_tasklet(unsigned long data)
 	rq = port_request(port);
 	while (rq && i915_request_completed(rq)) {
 		trace_i915_request_out(rq);
-		i915_request_put(rq);
 
 		port = execlists_port_complete(execlists, port);
-		if (port_isset(port)) {
+		if (port_isset(port))
 			execlists_user_begin(execlists, port);
-			rq = port_request(port);
-		} else {
+		else
 			execlists_user_end(execlists);
-			rq = NULL;
-		}
+		rq = port_request(port);
 	}
 
 	if (execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT) &&
@@ -814,6 +811,27 @@ static void guc_submission_tasklet(unsigned long data)
 		guc_dequeue(engine);
 }
 
+static void guc_retire_request(struct i915_request *rq)
+{
+	struct intel_engine_cs *engine = rq->engine;
+
+	if (unlikely(rq == port_request(engine->execlists.port))) {
+		struct tasklet_struct *t = &engine->execlists.tasklet;
+
+		while (!tasklet_trylock(t))
+			;
+		t->func(t->data);
+		tasklet_unlock(t);
+	}
+
+	spin_lock(&engine->timeline.lock);
+
+	GEM_BUG_ON(!list_is_first(&rq->link, &engine->timeline.requests));
+	list_del_init(&rq->link);
+
+	spin_unlock(&engine->timeline.lock);
+}
+
 static struct i915_request *
 guc_reset_prepare(struct intel_engine_cs *engine)
 {
@@ -1279,6 +1297,7 @@ static void guc_set_default_submission(struct intel_engine_cs *engine)
 	execlists_set_default_submission(engine);
 
 	engine->execlists.tasklet.func = guc_submission_tasklet;
+	engine->retire_request = guc_retire_request;
 
 	engine->park = guc_submission_park;
 	engine->unpark = guc_submission_unpark;
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 835809ba0585..6c60a4a35d4e 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -523,11 +523,7 @@ static bool can_merge_ctx(const struct intel_context *prev,
 static void port_assign(struct execlist_port *port, struct i915_request *rq)
 {
 	GEM_BUG_ON(rq == port_request(port));
-
-	if (port_isset(port))
-		i915_request_put(port_request(port));
-
-	port_set(port, port_pack(i915_request_get(rq), port_count(port)));
+	port_set(port, port_pack(rq, port_count(port)));
 }
 
 static void inject_preempt_context(struct intel_engine_cs *engine)
@@ -803,8 +799,6 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists)
 					       INTEL_CONTEXT_SCHEDULE_OUT :
 					       INTEL_CONTEXT_SCHEDULE_PREEMPTED);
 
-		i915_request_put(rq);
-
 		memset(port, 0, sizeof(*port));
 		port++;
 	}
@@ -1073,8 +1067,6 @@ static bool process_csb(struct intel_engine_cs *engine)
 
 			execlists_context_schedule_out(rq,
 						       INTEL_CONTEXT_SCHEDULE_OUT);
-			i915_request_put(rq);
-
 			GEM_TRACE("%s completed ctx=%d\n",
 				  engine->name, port->context_id);
 
@@ -2301,9 +2293,28 @@ void intel_logical_ring_cleanup(struct intel_engine_cs *engine)
 	kfree(engine);
 }
 
+static void execlists_retire_request(struct i915_request *rq)
+{
+	struct intel_engine_cs *engine = rq->engine;
+
+	GEM_BUG_ON(!irqs_disabled());
+	spin_lock(&engine->timeline.lock);
+
+	GEM_BUG_ON(!list_is_first(&rq->link, &engine->timeline.requests));
+	if (unlikely(rq == port_request(engine->execlists.port))) {
+		while (!process_csb(engine))
+			barrier();
+		execlists_dequeue(engine);
+	}
+	list_del_init(&rq->link);
+
+	spin_unlock(&engine->timeline.lock);
+}
+
 void execlists_set_default_submission(struct intel_engine_cs *engine)
 {
 	engine->submit_request = execlists_submit_request;
+	engine->retire_request = execlists_retire_request;
 	engine->cancel_requests = execlists_cancel_requests;
 	engine->schedule = execlists_schedule;
 	engine->execlists.tasklet.func = execlists_submission_tasklet;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 97b38bbb7ce2..d4ded15e86e1 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -2018,9 +2018,22 @@ static void intel_ring_init_irq(struct drm_i915_private *dev_priv,
 	}
 }
 
+static void retire_request(struct i915_request *rq)
+{
+	struct intel_engine_cs *engine = rq->engine;
+
+	spin_lock(&engine->timeline.lock);
+
+	GEM_BUG_ON(!list_is_first(&rq->link, &engine->timeline.requests));
+	list_del_init(&rq->link);
+
+	spin_unlock(&engine->timeline.lock);
+}
+
 static void i9xx_set_default_submission(struct intel_engine_cs *engine)
 {
 	engine->submit_request = i9xx_submit_request;
+	engine->retire_request = retire_request;
 	engine->cancel_requests = cancel_requests;
 
 	engine->park = NULL;
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 42a136810e15..7adc26a5846e 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -473,6 +473,7 @@ struct intel_engine_cs {
 	 * be irq safe.
 	 */
 	void		(*submit_request)(struct i915_request *rq);
+	void		(*retire_request)(struct i915_request *rq);
 
 	/* Call when the priority on a request has changed and it and its
 	 * dependencies may need rescheduling. Note the request itself may
-- 
2.17.0



More information about the Intel-gfx-trybot mailing list