All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 2/3] drm/i915/execlists: Suppress preempting self
Date: Wed, 23 Jan 2019 14:08:56 +0000	[thread overview]
Message-ID: <569302b7-c8f2-3590-9554-c855572a3984@linux.intel.com> (raw)
In-Reply-To: <20190123123602.21816-2-chris@chris-wilson.co.uk>


On 23/01/2019 12:36, Chris Wilson wrote:
> In order to avoid preempting ourselves, we currently refuse to schedule
> the tasklet if we reschedule an inflight context. However, this glosses
> over a few issues such as what happens after a CS completion event and
> we then preempt the newly executing context with itself, or if something
> else causes a tasklet_schedule triggering the same evaluation to
> preempt the active context with itself.
> 
> To avoid the extra complications, after deciding that we have
> potentially queued a request with higher priority than the currently
> executing request, inspect the head of the queue to see if it is indeed
> higher priority from another context.
> 
> References: a2bf92e8cc16 ("drm/i915/execlists: Avoid kicking priority on the current context")
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> ---
>   drivers/gpu/drm/i915/i915_scheduler.c | 20 ++++++--
>   drivers/gpu/drm/i915/intel_lrc.c      | 67 ++++++++++++++++++++++++---
>   2 files changed, 76 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c
> index 340faea6c08a..fb5d953430e5 100644
> --- a/drivers/gpu/drm/i915/i915_scheduler.c
> +++ b/drivers/gpu/drm/i915/i915_scheduler.c
> @@ -239,6 +239,18 @@ sched_lock_engine(struct i915_sched_node *node, struct intel_engine_cs *locked)
>   	return engine;
>   }
>   
> +static bool inflight(const struct i915_request *rq,
> +		     const struct intel_engine_cs *engine)
> +{
> +	const struct i915_request *active;
> +
> +	if (!rq->global_seqno)
> +		return false;
> +
> +	active = port_request(engine->execlists.port);
> +	return active->hw_context == rq->hw_context;
> +}
> +
>   static void __i915_schedule(struct i915_request *rq,
>   			    const struct i915_sched_attr *attr)
>   {
> @@ -328,6 +340,7 @@ static void __i915_schedule(struct i915_request *rq,
>   		INIT_LIST_HEAD(&dep->dfs_link);
>   
>   		engine = sched_lock_engine(node, engine);
> +		lockdep_assert_held(&engine->timeline.lock);
>   
>   		/* Recheck after acquiring the engine->timeline.lock */
>   		if (prio <= node->attr.priority || node_signaled(node))
> @@ -356,17 +369,16 @@ static void __i915_schedule(struct i915_request *rq,
>   		if (prio <= engine->execlists.queue_priority)
>   			continue;
>   
> +		engine->execlists.queue_priority = prio;
> +
>   		/*
>   		 * If we are already the currently executing context, don't
>   		 * bother evaluating if we should preempt ourselves.
>   		 */
> -		if (node_to_request(node)->global_seqno &&
> -		    i915_seqno_passed(port_request(engine->execlists.port)->global_seqno,
> -				      node_to_request(node)->global_seqno))
> +		if (inflight(node_to_request(node), engine))
>   			continue;
>   
>   		/* Defer (tasklet) submission until after all of our updates. */
> -		engine->execlists.queue_priority = prio;
>   		tasklet_hi_schedule(&engine->execlists.tasklet);
>   	}
>   
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 8aa8a4862543..d9d744f6ab2c 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -182,12 +182,64 @@ static inline int rq_prio(const struct i915_request *rq)
>   }
>   
>   static inline bool need_preempt(const struct intel_engine_cs *engine,
> -				const struct i915_request *last,
> -				int prio)
> +				const struct i915_request *rq,
> +				int q_prio)
>   {
> -	return (intel_engine_has_preemption(engine) &&
> -		__execlists_need_preempt(prio, rq_prio(last)) &&
> -		!i915_request_completed(last));
> +	const struct intel_context *ctx = rq->hw_context;
> +	const int last_prio = rq_prio(rq);
> +	struct rb_node *rb;
> +	int idx;
> +
> +	if (!intel_engine_has_preemption(engine))
> +		return false;
> +
> +	if (i915_request_completed(rq))
> +		return false;
> +
> +	if (!__execlists_need_preempt(q_prio, last_prio))
> +		return false;
> +
> +	/*
> +	 * The queue_priority is a mere hint that we may need to preempt.
> +	 * If that hint is stale or we may be trying to preempt ourselves,
> +	 * ignore the request.
> +	 */
> +
> +	list_for_each_entry_continue(rq, &engine->timeline.requests, link) {
> +		GEM_BUG_ON(rq->hw_context == ctx);

Why would there be no more requests belonging to the same context on the 
engine timeline after the first one? Did you mean "if (rq->hw_context == 
ctx) continue;" ?

> +		if (rq_prio(rq) > last_prio)
> +			return true;
> +	}
> +
> +	rb = rb_first_cached(&engine->execlists.queue);
> +	if (!rb)
> +		return false;
> +
> +	priolist_for_each_request(rq, to_priolist(rb), idx)
> +		return rq->hw_context != ctx && rq_prio(rq) > last_prio;

This isn't equivalent to top of the queue priority 
(engine->execlists.queue_priority)? Apart from the different ctx check. 
So I guess it is easier than storing new engine->execlists.queue_top_ctx 
and wondering about the validity of that pointer.

Regards,

Tvrtko

> +
> +	return false;
> +}
> +
> +__maybe_unused static inline bool
> +assert_priority_queue(const struct intel_engine_execlists *execlists,
> +		      const struct i915_request *prev,
> +		      const struct i915_request *next)
> +{
> +	if (!prev)
> +		return true;
> +
> +	/*
> +	 * Without preemption, the prev may refer to the still active element
> +	 * which we refuse to let go.
> +	 *
> +	 * Even with premption, there are times when we think it is better not
> +	 * to preempt and leave an ostensibly lower priority request in flight.
> +	 */
> +	if (port_request(execlists->port) == prev)
> +		return true;
> +
> +	return rq_prio(prev) >= rq_prio(next);
>   }
>   
>   /*
> @@ -626,8 +678,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
>   		int i;
>   
>   		priolist_for_each_request_consume(rq, rn, p, i) {
> -			GEM_BUG_ON(last &&
> -				   need_preempt(engine, last, rq_prio(rq)));
> +			GEM_BUG_ON(!assert_priority_queue(execlists, last, rq));
>   
>   			/*
>   			 * Can we combine this request with the current port?
> @@ -872,6 +923,8 @@ static void process_csb(struct intel_engine_cs *engine)
>   	const u32 * const buf = execlists->csb_status;
>   	u8 head, tail;
>   
> +	lockdep_assert_held(&engine->timeline.lock);
> +
>   	/*
>   	 * Note that csb_write, csb_status may be either in HWSP or mmio.
>   	 * When reading from the csb_write mmio register, we have to be
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2019-01-23 14:08 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-23 12:36 [PATCH 1/3] drm/i915/execlists: Mark up priority boost on preemption Chris Wilson
2019-01-23 12:36 ` [PATCH 2/3] drm/i915/execlists: Suppress preempting self Chris Wilson
2019-01-23 14:08   ` Tvrtko Ursulin [this message]
2019-01-23 14:22     ` Chris Wilson
2019-01-23 16:40       ` Tvrtko Ursulin
2019-01-23 17:09         ` Chris Wilson
2019-01-23 17:35   ` [PATCH v2] " Chris Wilson
2019-01-23 12:36 ` [PATCH 3/3] drm/i915/execlists: Suppress redundant preemption Chris Wilson
2019-01-23 13:47   ` Chris Wilson
2019-01-23 14:14     ` Chris Wilson
2019-01-23 14:44       ` Chris Wilson
2019-01-23 15:13   ` [PATCH v2] " Chris Wilson
2019-01-23 13:22 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/3] drm/i915/execlists: Mark up priority boost on preemption Patchwork
2019-01-23 13:22 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-01-23 13:34 ` [PATCH 1/3] " Tvrtko Ursulin
2019-01-23 13:40 ` ✗ Fi.CI.BAT: failure for series starting with [1/3] " Patchwork
2019-01-23 15:34 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/3] drm/i915/execlists: Mark up priority boost on preemption (rev2) Patchwork
2019-01-23 15:35 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-01-23 15:53 ` ✓ Fi.CI.BAT: success " Patchwork
2019-01-23 17:46 ` ✗ Fi.CI.BAT: failure for series starting with [1/3] drm/i915/execlists: Mark up priority boost on preemption (rev3) Patchwork
2019-01-23 18:15 ` ✓ Fi.CI.IGT: success for series starting with [1/3] drm/i915/execlists: Mark up priority boost on preemption (rev2) Patchwork
2019-01-25 22:05 [PATCH 1/3] drm/i915: Rename execlists->queue_priority to preempt_priority_hint Chris Wilson
2019-01-25 22:05 ` [PATCH 2/3] drm/i915/execlists: Suppress preempting self Chris Wilson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=569302b7-c8f2-3590-9554-c855572a3984@linux.intel.com \
    --to=tvrtko.ursulin@linux.intel.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.