[PATCH 13/13] drm/i915: Reduce spinlock hold time during notify_ring() interrupt

Chris Wilson chris at chris-wilson.co.uk
Tue Jan 2 13:27:22 UTC 2018


Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_irq.c | 37 +++++++++++++++++++++----------------
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 3517c6548e2c..2845b33cccc5 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1066,6 +1066,7 @@ static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv)
 static void notify_ring(struct intel_engine_cs *engine)
 {
 	struct drm_i915_gem_request *rq = NULL;
+	struct task_struct *tsk = NULL;
 	struct intel_wait *wait;
 
 	if (!engine->breadcrumbs.irq_armed)
@@ -1074,12 +1075,13 @@ static void notify_ring(struct intel_engine_cs *engine)
 	atomic_inc(&engine->irq_count);
 	set_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
 
+	rcu_read_lock();
+
 	spin_lock(&engine->breadcrumbs.irq_lock);
 	wait = engine->breadcrumbs.irq_wait;
 	if (wait) {
-		bool wakeup = engine->irq_seqno_barrier;
-
-		/* We use a callback from the dma-fence to submit
+		/*
+		 * We use a callback from the dma-fence to submit
 		 * requests after waiting on our own requests. To
 		 * ensure minimum delay in queuing the next request to
 		 * hardware, signal the fence now rather than wait for
@@ -1092,27 +1094,30 @@ static void notify_ring(struct intel_engine_cs *engine)
 		 */
 		if (i915_seqno_passed(intel_engine_get_seqno(engine),
 				      wait->seqno)) {
-			struct drm_i915_gem_request *waiter = wait->request;
-
-			wakeup = true;
-			if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
-				      &waiter->fence.flags) &&
-			    intel_wait_check_request(wait, waiter))
-				rq = i915_gem_request_get(waiter);
+			tsk = wait->tsk;
+			rq = wait->request;
+			if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
+				     &rq->fence.flags) ||
+			    intel_wait_check_request(wait, rq))
+				rq = NULL;
+		} else {
+			if (engine->irq_seqno_barrier &&
+			    i915_seqno_passed(intel_engine_get_seqno(engine),
+					      wait->seqno - 1))
+				tsk = wait->tsk;
 		}
-
-		if (wakeup)
-			wake_up_process(wait->tsk);
 	} else {
 		if (engine->breadcrumbs.irq_armed)
 			__intel_engine_disarm_breadcrumbs(engine);
 	}
 	spin_unlock(&engine->breadcrumbs.irq_lock);
 
-	if (rq) {
+	if (rq)
 		dma_fence_signal(&rq->fence);
-		i915_gem_request_put(rq);
-	}
+	if (tsk)
+		wake_up_process(tsk);
+
+	rcu_read_unlock();
 
 	trace_intel_engine_notify(engine, wait);
 }
-- 
2.15.1



More information about the Intel-gfx-trybot mailing list