[Intel-gfx] [PATCH 2/3] drm/i915/execlists: Track active elements during dequeue
Mika Kuoppala
mika.kuoppala at linux.intel.com
Wed Mar 11 11:17:17 UTC 2020
Chris Wilson <chris at chris-wilson.co.uk> 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 at chris-wilson.co.uk>
Reviewed-by: Mika Kuoppala <mika.kuoppala at linux.intel.com>
> ---
> 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
More information about the Intel-gfx
mailing list