All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff McGee <jeff.mcgee@intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 3/5] drm/i915: Move engine reset prepare/finish to backends
Date: Thu, 22 Mar 2018 08:28:06 -0700	[thread overview]
Message-ID: <20180322152806.GJ19343@jeffdesk> (raw)
In-Reply-To: <20180320001848.4405-3-chris@chris-wilson.co.uk>

On Tue, Mar 20, 2018 at 12:18:46AM +0000, Chris Wilson wrote:
> In preparation to more carefully handling incomplete preemption during
> reset by execlists, we move the existing code wholesale to the backends
> under a couple of new reset vfuncs.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Michał Winiarski <michal.winiarski@intel.com>
> CC: Michel Thierry <michel.thierry@intel.com>
> Cc: Jeff McGee <jeff.mcgee@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_gem.c         | 42 ++++----------------------
>  drivers/gpu/drm/i915/intel_lrc.c        | 52 +++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/i915/intel_ringbuffer.c | 20 +++++++++++--
>  drivers/gpu/drm/i915/intel_ringbuffer.h |  9 ++++--
>  4 files changed, 78 insertions(+), 45 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 802df8e1a544..38f7160d99c9 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2917,7 +2917,7 @@ static bool engine_stalled(struct intel_engine_cs *engine)
>  struct i915_request *
>  i915_gem_reset_prepare_engine(struct intel_engine_cs *engine)
>  {
> -	struct i915_request *request = NULL;
> +	struct i915_request *request;
>  
>  	/*
>  	 * During the reset sequence, we must prevent the engine from
> @@ -2940,40 +2940,7 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine)
>  	 */
>  	kthread_park(engine->breadcrumbs.signaler);
>  
> -	/*
> -	 * Prevent request submission to the hardware until we have
> -	 * completed the reset in i915_gem_reset_finish(). If a request
> -	 * is completed by one engine, it may then queue a request
> -	 * to a second via its execlists->tasklet *just* as we are
> -	 * calling engine->init_hw() and also writing the ELSP.
> -	 * Turning off the execlists->tasklet until the reset is over
> -	 * prevents the race.
> -	 *
> -	 * Note that this needs to be a single atomic operation on the
> -	 * tasklet (flush existing tasks, prevent new tasks) to prevent
> -	 * a race between reset and set-wedged. It is not, so we do the best
> -	 * we can atm and make sure we don't lock the machine up in the more
> -	 * common case of recursively being called from set-wedged from inside
> -	 * i915_reset.
> -	 */
> -	if (!atomic_read(&engine->execlists.tasklet.count))
> -		tasklet_kill(&engine->execlists.tasklet);
> -	tasklet_disable(&engine->execlists.tasklet);
> -
> -	/*
> -	 * We're using worker to queue preemption requests from the tasklet in
> -	 * GuC submission mode.
> -	 * Even though tasklet was disabled, we may still have a worker queued.
> -	 * Let's make sure that all workers scheduled before disabling the
> -	 * tasklet are completed before continuing with the reset.
> -	 */
> -	if (engine->i915->guc.preempt_wq)
> -		flush_workqueue(engine->i915->guc.preempt_wq);
> -
> -	if (engine->irq_seqno_barrier)
> -		engine->irq_seqno_barrier(engine);
> -
> -	request = i915_gem_find_active_request(engine);
> +	request = engine->reset.prepare(engine);
>  	if (request && request->fence.error == -EIO)
>  		request = ERR_PTR(-EIO); /* Previous reset failed! */
>  
> @@ -3120,7 +3087,7 @@ void i915_gem_reset_engine(struct intel_engine_cs *engine,
>  	}
>  
>  	/* Setup the CS to resume from the breadcrumb of the hung request */
> -	engine->reset_hw(engine, request);
> +	engine->reset.reset(engine, request);
>  }
>  
>  void i915_gem_reset(struct drm_i915_private *dev_priv)
> @@ -3172,7 +3139,8 @@ void i915_gem_reset(struct drm_i915_private *dev_priv)
>  
>  void i915_gem_reset_finish_engine(struct intel_engine_cs *engine)
>  {
> -	tasklet_enable(&engine->execlists.tasklet);
> +	engine->reset.finish(engine);
> +
>  	kthread_unpark(engine->breadcrumbs.signaler);
>  
>  	intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL);
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 0bfaeb56b8c7..f662a9524233 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -1663,6 +1663,44 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine)
>  	return init_workarounds_ring(engine);
>  }
>  
> +static struct i915_request *
> +execlists_reset_prepare(struct intel_engine_cs *engine)
> +{
> +	struct intel_engine_execlists * const execlists = &engine->execlists;
> +
> +	/*
> +	 * Prevent request submission to the hardware until we have
> +	 * completed the reset in i915_gem_reset_finish(). If a request
> +	 * is completed by one engine, it may then queue a request
> +	 * to a second via its execlists->tasklet *just* as we are
> +	 * calling engine->init_hw() and also writing the ELSP.
> +	 * Turning off the execlists->tasklet until the reset is over
> +	 * prevents the race.
> +	 *
> +	 * Note that this needs to be a single atomic operation on the
> +	 * tasklet (flush existing tasks, prevent new tasks) to prevent
> +	 * a race between reset and set-wedged. It is not, so we do the best
> +	 * we can atm and make sure we don't lock the machine up in the more
> +	 * common case of recursively being called from set-wedged from inside
> +	 * i915_reset.
> +	 */
> +	if (!atomic_read(&execlists->tasklet.count))
> +		tasklet_kill(&execlists->tasklet);
> +	tasklet_disable(&execlists->tasklet);
> +
> +	/*
> +	 * We're using worker to queue preemption requests from the tasklet in
> +	 * GuC submission mode.
> +	 * Even though tasklet was disabled, we may still have a worker queued.
> +	 * Let's make sure that all workers scheduled before disabling the
> +	 * tasklet are completed before continuing with the reset.
> +	 */
> +	if (engine->i915->guc.preempt_wq)
> +		flush_workqueue(engine->i915->guc.preempt_wq);
> +
> +	return i915_gem_find_active_request(engine);
> +}
> +
>  static void reset_irq(struct intel_engine_cs *engine)
>  {
>  	struct drm_i915_private *dev_priv = engine->i915;
> @@ -1692,8 +1730,8 @@ static void reset_irq(struct intel_engine_cs *engine)
>  	clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted);
>  }
>  
> -static void reset_common_ring(struct intel_engine_cs *engine,
> -			      struct i915_request *request)
> +static void execlists_reset(struct intel_engine_cs *engine,
> +			    struct i915_request *request)
>  {
>  	struct intel_engine_execlists * const execlists = &engine->execlists;
>  	struct intel_context *ce;
> @@ -1766,6 +1804,11 @@ static void reset_common_ring(struct intel_engine_cs *engine,
>  	unwind_wa_tail(request);
>  }
>  
> +static void execlists_reset_finish(struct intel_engine_cs *engine)
> +{
> +	tasklet_enable(&engine->execlists.tasklet);
> +}
> +
>  static int intel_logical_ring_emit_pdps(struct i915_request *rq)
>  {
>  	struct i915_hw_ppgtt *ppgtt = rq->ctx->ppgtt;
> @@ -2090,7 +2133,10 @@ logical_ring_default_vfuncs(struct intel_engine_cs *engine)
>  {
>  	/* Default vfuncs which can be overriden by each engine. */
>  	engine->init_hw = gen8_init_common_ring;
> -	engine->reset_hw = reset_common_ring;
> +
> +	engine->reset.prepare = execlists_reset_prepare;
> +	engine->reset.reset = execlists_reset;
> +	engine->reset.finish = execlists_reset_finish;
>  
>  	engine->context_pin = execlists_context_pin;
>  	engine->context_unpin = execlists_context_unpin;
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
> index 04d9d9a946a7..eebcc877ef60 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
> @@ -530,8 +530,16 @@ static int init_ring_common(struct intel_engine_cs *engine)
>  	return ret;
>  }
>  
> -static void reset_ring_common(struct intel_engine_cs *engine,
> -			      struct i915_request *request)
> +static struct i915_request *reset_prepare(struct intel_engine_cs *engine)
> +{
> +	if (engine->irq_seqno_barrier)
> +		engine->irq_seqno_barrier(engine);
> +
> +	return i915_gem_find_active_request(engine);
> +}
> +
> +static void reset_ring(struct intel_engine_cs *engine,
> +		       struct i915_request *request)
>  {
>  	/*
>  	 * RC6 must be prevented until the reset is complete and the engine
> @@ -595,6 +603,10 @@ static void reset_ring_common(struct intel_engine_cs *engine,
>  	}
>  }
>  
> +static void reset_finish(struct intel_engine_cs *engine)
> +{
> +}
> +
>  static int intel_rcs_ctx_init(struct i915_request *rq)
>  {
>  	int ret;
> @@ -1987,7 +1999,9 @@ static void intel_ring_default_vfuncs(struct drm_i915_private *dev_priv,
>  	intel_ring_init_semaphores(dev_priv, engine);
>  
>  	engine->init_hw = init_ring_common;
> -	engine->reset_hw = reset_ring_common;
> +	engine->reset.prepare = reset_prepare;
> +	engine->reset.reset = reset_ring;
> +	engine->reset.finish = reset_finish;
>  
>  	engine->context_pin = intel_ring_context_pin;
>  	engine->context_unpin = intel_ring_context_unpin;
> diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
> index 1f50727a5ddb..e2681303ce21 100644
> --- a/drivers/gpu/drm/i915/intel_ringbuffer.h
> +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
> @@ -418,8 +418,13 @@ struct intel_engine_cs {
>  	void		(*irq_disable)(struct intel_engine_cs *engine);
>  
>  	int		(*init_hw)(struct intel_engine_cs *engine);
> -	void		(*reset_hw)(struct intel_engine_cs *engine,
> -				    struct i915_request *rq);
> +
> +	struct {
> +		struct i915_request *(*prepare)(struct intel_engine_cs *engine);
> +		void (*reset)(struct intel_engine_cs *engine,
> +			      struct i915_request *rq);
> +		void (*finish)(struct intel_engine_cs *engine);
> +	} reset;
>  
>  	void		(*park)(struct intel_engine_cs *engine);
>  	void		(*unpark)(struct intel_engine_cs *engine);
> -- 
> 2.16.2
> 

Reviewed-by: Jeff McGee <jeff.mcgee@intel.com>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2018-03-22 15:43 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-20  0:18 [PATCH 1/5] drm/i915: Add control flags to i915_handle_error() Chris Wilson
2018-03-20  0:18 ` [PATCH 2/5] drm/i915/execlists: Refactor out complete_preempt_context() Chris Wilson
2018-03-22 15:26   ` Jeff McGee
2018-03-20  0:18 ` [PATCH 3/5] drm/i915: Move engine reset prepare/finish to backends Chris Wilson
2018-03-22 15:28   ` Jeff McGee [this message]
2018-03-20  0:18 ` [PATCH 4/5] drm/i915: Split execlists/guc reset prepartions Chris Wilson
2018-03-22 15:28   ` Jeff McGee
2018-03-20  0:18 ` [PATCH 5/5] drm/i915/execlists: Flush pending preemption events during reset Chris Wilson
2018-03-21  0:17   ` Jeff McGee
2018-03-22 15:14     ` Jeff McGee
2018-03-26 11:28       ` Chris Wilson
2018-03-20  0:39 ` [PATCH 1/5] drm/i915: Add control flags to i915_handle_error() Michel Thierry
2018-03-20  0:44   ` Chris Wilson
2018-03-20  0:56     ` Michel Thierry
2018-03-20  1:09       ` Chris Wilson
2018-03-20  1:24 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/5] " Patchwork
2018-03-20  1:25 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-03-20  1:41 ` ✓ Fi.CI.BAT: success " Patchwork
2018-03-20  6:45 ` ✗ Fi.CI.IGT: failure " Patchwork

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=20180322152806.GJ19343@jeffdesk \
    --to=jeff.mcgee@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.