Commit 2efa2c52 authored by Chris Wilson's avatar Chris Wilson

drm/i915/gt: Decouple inflight virtual engines

Once a virtual engine has been bound to a sibling, it will remain bound
until we finally schedule out the last active request. We can not rebind
the context to a new sibling while it is inflight as the context save
will conflict, hence we wait. As we cannot then use any other sibliing
while the context is inflight, only kick the bound sibling while it
inflight and upon scheduling out the kick the rest (so that we can swap
engines on timeslicing if the previously bound engine becomes
oversubscribed).
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20201224135544.1713-3-chris@chris-wilson.co.uk
parent 64b7a3fa
......@@ -581,9 +581,8 @@ static inline void execlists_schedule_in(struct i915_request *rq, int idx)
static void kick_siblings(struct i915_request *rq, struct intel_context *ce)
{
struct virtual_engine *ve = container_of(ce, typeof(*ve), context);
struct i915_request *next = READ_ONCE(ve->request);
if (next == rq || (next && next->execution_mask & ~rq->execution_mask))
if (READ_ONCE(ve->request))
tasklet_hi_schedule(&ve->base.execlists.tasklet);
}
......@@ -997,17 +996,13 @@ first_virtual_engine(struct intel_engine_cs *engine)
struct i915_request *rq = READ_ONCE(ve->request);
/* lazily cleanup after another engine handled rq */
if (!rq) {
if (!rq || !virtual_matches(ve, rq, engine)) {
rb_erase_cached(rb, &el->virtual);
RB_CLEAR_NODE(rb);
rb = rb_first_cached(&el->virtual);
continue;
}
if (!virtual_matches(ve, rq, engine)) {
rb = rb_next(rb);
continue;
}
return ve;
}
......@@ -3435,7 +3430,6 @@ static void virtual_submission_tasklet(unsigned long data)
if (unlikely(!mask))
return;
local_irq_disable();
for (n = 0; n < ve->num_siblings; n++) {
struct intel_engine_cs *sibling = READ_ONCE(ve->siblings[n]);
struct ve_node * const node = &ve->nodes[sibling->id];
......@@ -3445,20 +3439,19 @@ static void virtual_submission_tasklet(unsigned long data)
if (!READ_ONCE(ve->request))
break; /* already handled by a sibling's tasklet */
spin_lock_irq(&sibling->active.lock);
if (unlikely(!(mask & sibling->mask))) {
if (!RB_EMPTY_NODE(&node->rb)) {
spin_lock(&sibling->active.lock);
rb_erase_cached(&node->rb,
&sibling->execlists.virtual);
RB_CLEAR_NODE(&node->rb);
spin_unlock(&sibling->active.lock);
}
continue;
}
spin_lock(&sibling->active.lock);
goto unlock_engine;
}
if (!RB_EMPTY_NODE(&node->rb)) {
if (unlikely(!RB_EMPTY_NODE(&node->rb))) {
/*
* Cheat and avoid rebalancing the tree if we can
* reuse this node in situ.
......@@ -3498,9 +3491,12 @@ static void virtual_submission_tasklet(unsigned long data)
if (first && prio > sibling->execlists.queue_priority_hint)
tasklet_hi_schedule(&sibling->execlists.tasklet);
spin_unlock(&sibling->active.lock);
unlock_engine:
spin_unlock_irq(&sibling->active.lock);
if (intel_context_inflight(&ve->context))
break;
}
local_irq_enable();
}
static void virtual_submit_request(struct i915_request *rq)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment