Skip to content

Commit 60ef5b7

Browse files
committed
drm/i915/execlists: Track active elements during dequeue
Record the initial active element we use when building the next ELSP submission, so that we can compare against it latter to see if there's no change. Fixes: 44d0a9c ("drm/i915/execlists: Skip redundant resubmission") Signed-off-by: Chris Wilson <[email protected]> Reviewed-by: Mika Kuoppala <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 408464b commit 60ef5b7

File tree

1 file changed

+12
-20
lines changed

1 file changed

+12
-20
lines changed

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

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,17 +1678,6 @@ static void virtual_xfer_breadcrumbs(struct virtual_engine *ve,
16781678
spin_unlock(&old->breadcrumbs.irq_lock);
16791679
}
16801680

1681-
static struct i915_request *
1682-
last_active(const struct intel_engine_execlists *execlists)
1683-
{
1684-
struct i915_request * const *last = READ_ONCE(execlists->active);
1685-
1686-
while (*last && i915_request_completed(*last))
1687-
last++;
1688-
1689-
return *last;
1690-
}
1691-
16921681
#define for_each_waiter(p__, rq__) \
16931682
list_for_each_entry_lockless(p__, \
16941683
&(rq__)->sched.waiters_list, \
@@ -1827,11 +1816,9 @@ static void record_preemption(struct intel_engine_execlists *execlists)
18271816
(void)I915_SELFTEST_ONLY(execlists->preempt_hang.count++);
18281817
}
18291818

1830-
static unsigned long active_preempt_timeout(struct intel_engine_cs *engine)
1819+
static unsigned long active_preempt_timeout(struct intel_engine_cs *engine,
1820+
const struct i915_request *rq)
18311821
{
1832-
struct i915_request *rq;
1833-
1834-
rq = last_active(&engine->execlists);
18351822
if (!rq)
18361823
return 0;
18371824

@@ -1842,13 +1829,14 @@ static unsigned long active_preempt_timeout(struct intel_engine_cs *engine)
18421829
return READ_ONCE(engine->props.preempt_timeout_ms);
18431830
}
18441831

1845-
static void set_preempt_timeout(struct intel_engine_cs *engine)
1832+
static void set_preempt_timeout(struct intel_engine_cs *engine,
1833+
const struct i915_request *rq)
18461834
{
18471835
if (!intel_engine_has_preempt_reset(engine))
18481836
return;
18491837

18501838
set_timer_ms(&engine->execlists.preempt,
1851-
active_preempt_timeout(engine));
1839+
active_preempt_timeout(engine, rq));
18521840
}
18531841

18541842
static inline void clear_ports(struct i915_request **ports, int count)
@@ -1861,6 +1849,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
18611849
struct intel_engine_execlists * const execlists = &engine->execlists;
18621850
struct i915_request **port = execlists->pending;
18631851
struct i915_request ** const last_port = port + execlists->port_mask;
1852+
struct i915_request * const *active;
18641853
struct i915_request *last;
18651854
struct rb_node *rb;
18661855
bool submit = false;
@@ -1915,7 +1904,10 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
19151904
* i.e. we will retrigger preemption following the ack in case
19161905
* of trouble.
19171906
*/
1918-
last = last_active(execlists);
1907+
active = READ_ONCE(execlists->active);
1908+
while ((last = *active) && i915_request_completed(last))
1909+
active++;
1910+
19191911
if (last) {
19201912
if (need_preempt(engine, last, rb)) {
19211913
ENGINE_TRACE(engine,
@@ -2201,7 +2193,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
22012193
* Skip if we ended up with exactly the same set of requests,
22022194
* e.g. trying to timeslice a pair of ordered contexts
22032195
*/
2204-
if (!memcmp(execlists->active, execlists->pending,
2196+
if (!memcmp(active, execlists->pending,
22052197
(port - execlists->pending + 1) * sizeof(*port))) {
22062198
do
22072199
execlists_schedule_out(fetch_and_zero(port));
@@ -2212,7 +2204,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
22122204
clear_ports(port + 1, last_port - port);
22132205

22142206
execlists_submit_ports(engine);
2215-
set_preempt_timeout(engine);
2207+
set_preempt_timeout(engine, *active);
22162208
} else {
22172209
skip_submit:
22182210
ring_set_paused(engine, 0);

0 commit comments

Comments
 (0)