[Intel-gfx] [PATCH] gpu/drm/i915: disable interrupt when holding spinlock

Wang Xiayang xywang.sjtu at sjtu.edu.cn
Wed Aug 7 14:54:37 UTC 2019


The irq_lock is acquired in multiple functions:

1) i915_request_cancel_breadcrumb
 <- ... <- panfrost_gpu_irq_handler
2) intel_engine_breadcrumbs_irq
 <- ... <- cherryview_irq_handler
3) i915_request_enable_breadcrumb
4) virtual_xfer_breadcrumbs

The former two functions are reachable from IRQ handlers while
the latter two functions are not, and they call spin_lock()
which do not disable interrupt. Being preempted by an interrupt
acquiring the same lock may lead to deadlock.
Other functions acquire irq_lock by spin_lock_irq/irqsave().

This patch switches spin_lock() to spin_lock_irq in the two
process-context functions.

The issue is identified by a static analyzer based on Coccinelle.

Signed-off-by: Wang Xiayang <xywang.sjtu at sjtu.edu.cn>
---
 drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 4 ++--
 drivers/gpu/drm/i915/gt/intel_lrc.c         | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
index c092bdf5f0bf..e0b46450c2f5 100644
--- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
@@ -301,7 +301,7 @@ bool i915_request_enable_breadcrumb(struct i915_request *rq)
 		struct intel_context *ce = rq->hw_context;
 		struct list_head *pos;
 
-		spin_lock(&b->irq_lock);
+		spin_lock_irq(&b->irq_lock);
 		GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags));
 
 		__intel_breadcrumbs_arm_irq(b);
@@ -333,7 +333,7 @@ bool i915_request_enable_breadcrumb(struct i915_request *rq)
 		GEM_BUG_ON(!check_signal_order(ce, rq));
 
 		set_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
-		spin_unlock(&b->irq_lock);
+		spin_unlock_irq(&b->irq_lock);
 	}
 
 	return !__request_completed(rq);
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 82b7ace62d97..42367aeefcce 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -806,13 +806,13 @@ static void virtual_xfer_breadcrumbs(struct virtual_engine *ve,
 
 	/* All unattached (rq->engine == old) must already be completed */
 
-	spin_lock(&old->breadcrumbs.irq_lock);
+	spin_lock_irq(&old->breadcrumbs.irq_lock);
 	if (!list_empty(&ve->context.signal_link)) {
 		list_move_tail(&ve->context.signal_link,
 			       &engine->breadcrumbs.signalers);
 		intel_engine_queue_breadcrumbs(engine);
 	}
-	spin_unlock(&old->breadcrumbs.irq_lock);
+	spin_unlock_irq(&old->breadcrumbs.irq_lock);
 }
 
 static void execlists_dequeue(struct intel_engine_cs *engine)
-- 
2.11.0



More information about the Intel-gfx mailing list