Skip to content

Commit 3df2dee

Browse files
committed
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]
1 parent e3e7aee commit 3df2dee

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
@@ -1757,11 +1757,9 @@ need_timeslice(struct intel_engine_cs *engine, const struct i915_request *rq)
17571757
if (!intel_engine_has_timeslices(engine))
17581758
return false;
17591759

1760-
if (list_is_last(&rq->sched.link, &engine->active.requests))
1761-
return false;
1762-
1763-
hint = max(rq_prio(list_next_entry(rq, sched.link)),
1764-
engine->execlists.queue_priority_hint);
1760+
hint = engine->execlists.queue_priority_hint;
1761+
if (!list_is_last(&rq->sched.link, &engine->active.requests))
1762+
hint = max(hint, rq_prio(list_next_entry(rq, sched.link)));
17651763

17661764
return hint >= effective_prio(rq);
17671765
}
@@ -1803,6 +1801,18 @@ static void set_timeslice(struct intel_engine_cs *engine)
18031801
set_timer_ms(&engine->execlists.timer, active_timeslice(engine));
18041802
}
18051803

1804+
static void start_timeslice(struct intel_engine_cs *engine)
1805+
{
1806+
struct intel_engine_execlists *execlists = &engine->execlists;
1807+
1808+
execlists->switch_priority_hint = execlists->queue_priority_hint;
1809+
1810+
if (timer_pending(&execlists->timer))
1811+
return;
1812+
1813+
set_timer_ms(&execlists->timer, timeslice(engine));
1814+
}
1815+
18061816
static void record_preemption(struct intel_engine_execlists *execlists)
18071817
{
18081818
(void)I915_SELFTEST_ONLY(execlists->preempt_hang.count++);
@@ -1966,11 +1976,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
19661976
* Even if ELSP[1] is occupied and not worthy
19671977
* of timeslices, our queue might be.
19681978
*/
1969-
if (!execlists->timer.expires &&
1970-
need_timeslice(engine, last))
1971-
set_timer_ms(&execlists->timer,
1972-
timeslice(engine));
1973-
1979+
start_timeslice(engine);
19741980
return;
19751981
}
19761982
}
@@ -2005,7 +2011,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
20052011

20062012
if (last && !can_merge_rq(last, rq)) {
20072013
spin_unlock(&ve->base.active.lock);
2008-
return; /* leave this for another */
2014+
start_timeslice(engine);
2015+
return; /* leave this for another sibling */
20092016
}
20102017

20112018
ENGINE_TRACE(engine,

0 commit comments

Comments
 (0)