Skip to content

Commit eafc2aa

Browse files
icklejnikula
authored andcommitted
drm/i915/execlists: Enable timeslice on partial virtual engine dequeue
If we stop filling the ELSP due to an incompatible virtual engine request, check if we should enable the timeslice on behalf of the queue. This fixes the case where we are inspecting the last->next element when we know that the last element is the last request in the execution queue, and so decided we did not need to enable timeslicing despite the intent to do so! Fixes: 8ee36e0 ("drm/i915/execlists: Minimalistic timeslicing") Signed-off-by: Chris Wilson <[email protected]> Cc: Mika Kuoppala <[email protected]> Cc: Tvrtko Ursulin <[email protected]> Cc: <[email protected]> # v5.4+ Reviewed-by: Mika Kuoppala <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] (cherry picked from commit 3df2dee) Signed-off-by: Jani Nikula <[email protected]>
1 parent 1d61c5d commit eafc2aa

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

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

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,11 +1679,9 @@ need_timeslice(struct intel_engine_cs *engine, const struct i915_request *rq)
16791679
if (!intel_engine_has_timeslices(engine))
16801680
return false;
16811681

1682-
if (list_is_last(&rq->sched.link, &engine->active.requests))
1683-
return false;
1684-
1685-
hint = max(rq_prio(list_next_entry(rq, sched.link)),
1686-
engine->execlists.queue_priority_hint);
1682+
hint = engine->execlists.queue_priority_hint;
1683+
if (!list_is_last(&rq->sched.link, &engine->active.requests))
1684+
hint = max(hint, rq_prio(list_next_entry(rq, sched.link)));
16871685

16881686
return hint >= effective_prio(rq);
16891687
}
@@ -1725,6 +1723,18 @@ static void set_timeslice(struct intel_engine_cs *engine)
17251723
set_timer_ms(&engine->execlists.timer, active_timeslice(engine));
17261724
}
17271725

1726+
static void start_timeslice(struct intel_engine_cs *engine)
1727+
{
1728+
struct intel_engine_execlists *execlists = &engine->execlists;
1729+
1730+
execlists->switch_priority_hint = execlists->queue_priority_hint;
1731+
1732+
if (timer_pending(&execlists->timer))
1733+
return;
1734+
1735+
set_timer_ms(&execlists->timer, timeslice(engine));
1736+
}
1737+
17281738
static void record_preemption(struct intel_engine_execlists *execlists)
17291739
{
17301740
(void)I915_SELFTEST_ONLY(execlists->preempt_hang.count++);
@@ -1888,11 +1898,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
18881898
* Even if ELSP[1] is occupied and not worthy
18891899
* of timeslices, our queue might be.
18901900
*/
1891-
if (!execlists->timer.expires &&
1892-
need_timeslice(engine, last))
1893-
set_timer_ms(&execlists->timer,
1894-
timeslice(engine));
1895-
1901+
start_timeslice(engine);
18961902
return;
18971903
}
18981904
}
@@ -1927,7 +1933,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
19271933

19281934
if (last && !can_merge_rq(last, rq)) {
19291935
spin_unlock(&ve->base.active.lock);
1930-
return; /* leave this for another */
1936+
start_timeslice(engine);
1937+
return; /* leave this for another sibling */
19311938
}
19321939

19331940
ENGINE_TRACE(engine,

0 commit comments

Comments
 (0)