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: 44d0a9c05bc0 ("drm/i915/execlists: Skip redundant resubmission") Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/gt/intel_lrc.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 6266ef2ae6a0..a9d77b0e4e27 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -1674,16 +1674,21 @@ static void virtual_xfer_breadcrumbs(struct virtual_engine *ve, } static struct i915_request * -last_active(const struct intel_engine_execlists *execlists) +__last_active(const struct intel_engine_execlists *execlists, + struct i915_request * const *last) { - struct i915_request * const *last = READ_ONCE(execlists->active); - while (*last && i915_request_completed(*last)) last++; return *last; } +static struct i915_request * +last_active(const struct intel_engine_execlists *execlists) +{ + return __last_active(execlists, READ_ONCE(execlists->active)); +} + #define for_each_waiter(p__, rq__) \ list_for_each_entry_lockless(p__, \ &(rq__)->sched.waiters_list, \ @@ -1852,6 +1857,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) struct intel_engine_execlists * const execlists = &engine->execlists; struct i915_request **port = execlists->pending; struct i915_request ** const last_port = port + execlists->port_mask; + struct i915_request * const *active; struct i915_request *last; struct rb_node *rb; bool submit = false; @@ -1906,7 +1912,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine) * i.e. we will retrigger preemption following the ack in case * of trouble. */ - last = last_active(execlists); + active = READ_ONCE(execlists->active); + last = __last_active(execlists, active); if (last) { if (need_preempt(engine, last, rb)) { ENGINE_TRACE(engine, @@ -2191,7 +2198,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) * Skip if we ended up with exactly the same set of requests, * e.g. trying to timeslice a pair of ordered contexts */ - if (!memcmp(execlists->active, execlists->pending, + if (!memcmp(active, execlists->pending, (port - execlists->pending + 1) * sizeof(*port))) { do execlists_schedule_out(fetch_and_zero(port)); -- 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx