Skip to content

Commit 1d9221e

Browse files
committed
drm/i915: Skip signaling a signaled request
Preempt-to-busy introduces various fascinating complications in that the requests may complete as we are unsubmitting them from HW. As they may then signal after unsubmission, we may find ourselves having to cleanup the signaling request from within the signaling callback. This causes us to recurse onto the same i915_request.lock. However, if the request is already signaled (as it will be before we enter the signal callbacks), we know we can skip the signaling of that request during submission, neatly evading the spinlock recursion. unsubmit(ve.rq0) # timeslice expiration or other preemption -> virtual_submit_request(ve.rq0) dma_fence_signal(ve.rq0) # request completed before preemption ack -> submit_notify(ve.rq1) -> virtual_submit_request(ve.rq1) # sees that we have completed ve.rq0 -> __i915_request_submit(ve.rq0) [ 264.210142] BUG: spinlock recursion on CPU#2, sample_multi_tr/2093 [ 264.210150] lock: 0xffff9efd6ac55080, .magic: dead4ead, .owner: sample_multi_tr/2093, .owner_cpu: 2 [ 264.210155] CPU: 2 PID: 2093 Comm: sample_multi_tr Tainted: G U [ 264.210158] Hardware name: Intel Corporation CoffeeLake Client Platform/CoffeeLake S UDIMM RVP, BIOS CNLSFWR1.R00.X212.B01.1909060036 09/06/2019 [ 264.210160] Call Trace: [ 264.210167] dump_stack+0x98/0xda [ 264.210174] spin_dump.cold+0x24/0x3c [ 264.210178] do_raw_spin_lock+0x9a/0xd0 [ 264.210184] _raw_spin_lock_nested+0x6a/0x70 [ 264.210314] __i915_request_submit+0x10a/0x3c0 [i915] [ 264.210415] virtual_submit_request+0x9b/0x380 [i915] [ 264.210516] submit_notify+0xaf/0x14c [i915] [ 264.210602] __i915_sw_fence_complete+0x8a/0x230 [i915] [ 264.210692] i915_sw_fence_complete+0x2d/0x40 [i915] [ 264.210762] __dma_i915_sw_fence_wake+0x19/0x30 [i915] [ 264.210767] dma_fence_signal_locked+0xb1/0x1c0 [ 264.210772] dma_fence_signal+0x29/0x50 [ 264.210871] i915_request_wait+0x5cb/0x830 [i915] [ 264.210876] ? dma_resv_get_fences_rcu+0x294/0x5d0 [ 264.210974] i915_gem_object_wait_fence+0x2f/0x40 [i915] [ 264.211084] i915_gem_object_wait+0xce/0x400 [i915] [ 264.211178] i915_gem_wait_ioctl+0xff/0x290 [i915] Fixes: 22b7a42 ("drm/i915/execlists: Preempt-to-busy") References: 6d06779 ("drm/i915: Load balancing across a virtual engine") Signed-off-by: Chris Wilson <[email protected]> Cc: Tvrtko Ursulin <[email protected]> Cc: "Nayana, Venkata Ramana" <[email protected]> Cc: <[email protected]> # v5.4+ Reviewed-by: Tvrtko Ursulin <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 90a9872 commit 1d9221e

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

drivers/gpu/drm/i915/gt/intel_breadcrumbs.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,13 +314,18 @@ bool i915_request_enable_breadcrumb(struct i915_request *rq)
314314
{
315315
lockdep_assert_held(&rq->lock);
316316

317+
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &rq->fence.flags))
318+
return true;
319+
317320
if (test_bit(I915_FENCE_FLAG_ACTIVE, &rq->fence.flags)) {
318321
struct intel_breadcrumbs *b = &rq->engine->breadcrumbs;
319322
struct intel_context *ce = rq->context;
320323
struct list_head *pos;
321324

322325
spin_lock(&b->irq_lock);
323-
GEM_BUG_ON(test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags));
326+
327+
if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags))
328+
goto unlock;
324329

325330
if (!__intel_breadcrumbs_arm_irq(b))
326331
goto unlock;

drivers/gpu/drm/i915/i915_request.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -560,22 +560,25 @@ bool __i915_request_submit(struct i915_request *request)
560560
engine->serial++;
561561
result = true;
562562

563-
xfer: /* We may be recursing from the signal callback of another i915 fence */
564-
spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING);
565-
563+
xfer:
566564
if (!test_and_set_bit(I915_FENCE_FLAG_ACTIVE, &request->fence.flags)) {
567565
list_move_tail(&request->sched.link, &engine->active.requests);
568566
clear_bit(I915_FENCE_FLAG_PQUEUE, &request->fence.flags);
569-
__notify_execute_cb(request);
570567
}
571-
GEM_BUG_ON(!llist_empty(&request->execute_cb));
572568

573-
if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &request->fence.flags) &&
574-
!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &request->fence.flags) &&
575-
!i915_request_enable_breadcrumb(request))
576-
intel_engine_signal_breadcrumbs(engine);
569+
/* We may be recursing from the signal callback of another i915 fence */
570+
if (!i915_request_signaled(request)) {
571+
spin_lock_nested(&request->lock, SINGLE_DEPTH_NESTING);
572+
573+
__notify_execute_cb(request);
574+
if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
575+
&request->fence.flags) &&
576+
!i915_request_enable_breadcrumb(request))
577+
intel_engine_signal_breadcrumbs(engine);
577578

578-
spin_unlock(&request->lock);
579+
spin_unlock(&request->lock);
580+
GEM_BUG_ON(!llist_empty(&request->execute_cb));
581+
}
579582

580583
return result;
581584
}

0 commit comments

Comments
 (0)