Skip to content

Commit a97b786

Browse files
icklerodrigovivi
authored andcommitted
drm/i915/gt: Stage the transfer of the virtual breadcrumb
We move the virtual breadcrumb from one physical engine to the next, if the next virtual request is scheduled on a new physical engine. Since the virtual context can only be in one signal queue, we need it to track the current physical engine for the new breadcrumbs. However, to move the list we need both breadcrumb locks -- and since we cannot take both at the same time (unless we are careful and always ensure consistent ordering) stage the movement of the signaler via the current virtual request. Closes: https://gitlab.freedesktop.org/drm/intel/issues/1510 Fixes: 6d06779 ("drm/i915: Load balancing across a virtual engine") Signed-off-by: Chris Wilson <[email protected]> Cc: Tvrtko Ursulin <[email protected]> Reviewed-by: Tvrtko Ursulin <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] (cherry picked from commit 6c81e21) Signed-off-by: Rodrigo Vivi <[email protected]>
1 parent c1ed2fb commit a97b786

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,17 +1663,27 @@ static bool virtual_matches(const struct virtual_engine *ve,
16631663
}
16641664

16651665
static void virtual_xfer_breadcrumbs(struct virtual_engine *ve,
1666-
struct intel_engine_cs *engine)
1666+
struct i915_request *rq)
16671667
{
16681668
struct intel_engine_cs *old = ve->siblings[0];
16691669

16701670
/* All unattached (rq->engine == old) must already be completed */
16711671

16721672
spin_lock(&old->breadcrumbs.irq_lock);
16731673
if (!list_empty(&ve->context.signal_link)) {
1674-
list_move_tail(&ve->context.signal_link,
1675-
&engine->breadcrumbs.signalers);
1676-
intel_engine_signal_breadcrumbs(engine);
1674+
list_del_init(&ve->context.signal_link);
1675+
1676+
/*
1677+
* We cannot acquire the new engine->breadcrumbs.irq_lock
1678+
* (as we are holding a breadcrumbs.irq_lock already),
1679+
* so attach this request to the signaler on submission.
1680+
* The queued irq_work will occur when we finally drop
1681+
* the engine->active.lock after dequeue.
1682+
*/
1683+
set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &rq->fence.flags);
1684+
1685+
/* Also transfer the pending irq_work for the old breadcrumb. */
1686+
intel_engine_signal_breadcrumbs(rq->engine);
16771687
}
16781688
spin_unlock(&old->breadcrumbs.irq_lock);
16791689
}
@@ -2045,7 +2055,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
20452055
engine);
20462056

20472057
if (!list_empty(&ve->context.signals))
2048-
virtual_xfer_breadcrumbs(ve, engine);
2058+
virtual_xfer_breadcrumbs(ve, rq);
20492059

20502060
/*
20512061
* Move the bound engine to the top of the list

0 commit comments

Comments
 (0)