Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> writes: > 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> Reviewed-by: Mika Kuoppala <mika.kuoppala@xxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/i915/gt/intel_lrc.c | 32 +++++++++++------------------ > 1 file changed, 12 insertions(+), 20 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c > index ee378a089dd5..1c68b4f4e33d 100644 > --- a/drivers/gpu/drm/i915/gt/intel_lrc.c > +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c > @@ -1678,17 +1678,6 @@ static void virtual_xfer_breadcrumbs(struct virtual_engine *ve, > spin_unlock(&old->breadcrumbs.irq_lock); > } > > -static struct i915_request * > -last_active(const struct intel_engine_execlists *execlists) > -{ > - struct i915_request * const *last = READ_ONCE(execlists->active); > - > - while (*last && i915_request_completed(*last)) > - last++; > - > - return *last; > -} > - > #define for_each_waiter(p__, rq__) \ > list_for_each_entry_lockless(p__, \ > &(rq__)->sched.waiters_list, \ > @@ -1827,11 +1816,9 @@ static void record_preemption(struct intel_engine_execlists *execlists) > (void)I915_SELFTEST_ONLY(execlists->preempt_hang.count++); > } > > -static unsigned long active_preempt_timeout(struct intel_engine_cs *engine) > +static unsigned long active_preempt_timeout(struct intel_engine_cs *engine, > + const struct i915_request *rq) > { > - struct i915_request *rq; > - > - rq = last_active(&engine->execlists); > if (!rq) > return 0; > > @@ -1842,13 +1829,14 @@ static unsigned long active_preempt_timeout(struct intel_engine_cs *engine) > return READ_ONCE(engine->props.preempt_timeout_ms); > } > > -static void set_preempt_timeout(struct intel_engine_cs *engine) > +static void set_preempt_timeout(struct intel_engine_cs *engine, > + const struct i915_request *rq) > { > if (!intel_engine_has_preempt_reset(engine)) > return; > > set_timer_ms(&engine->execlists.preempt, > - active_preempt_timeout(engine)); > + active_preempt_timeout(engine, rq)); > } > > static inline void clear_ports(struct i915_request **ports, int count) > @@ -1861,6 +1849,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; > @@ -1915,7 +1904,10 @@ 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); > + while ((last = *active) && i915_request_completed(last)) > + active++; > + > if (last) { > if (need_preempt(engine, last, rb)) { > ENGINE_TRACE(engine, > @@ -2201,7 +2193,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)); > @@ -2212,7 +2204,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) > clear_ports(port + 1, last_port - port); > > execlists_submit_ports(engine); > - set_preempt_timeout(engine); > + set_preempt_timeout(engine, *active); > } else { > skip_submit: > ring_set_paused(engine, 0); > -- > 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx