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: [Intel-gfx] [PATCH 01/24] drm/i915/gt: Transfer old virtual breadcrumbs to irq_worker
Date: Thu, 14 May 2020 09:55:21 +0100	[thread overview]
Message-ID: <f5ada51e-fda6-c57e-0d1b-8fd008a92c4b@linux.intel.com> (raw)
In-Reply-To: <20200513074809.18194-1-chris@chris-wilson.co.uk>


On 13/05/2020 08:47, Chris Wilson wrote:
> The second try at staging the transfer of the breadcrumb. In part one,
> we realised we could not simply move to the second engine as we were
> only holding the breadcrumb lock on the first. So in commit 6c81e21a4742
> ("drm/i915/gt: Stage the transfer of the virtual breadcrumb"), we
> removed it from the first engine and marked up this request to reattach
> the signaling on the new engine. However, this failed to take into
> account that we only attach the breadcrumb if the new request is added
> at the start of the queue, which if we are transferring, it is because
> we know there to be a request to be signaled (and hence we would not be
> attached).
> 
> In this attempt, we try to transfer the completed requests to the
> irq_worker on its rq->engine->breadcrumbs. This preserves the coupling
> between the rq and its breadcrumbs, so that
> i915_request_cancel_breadcrumb() does not attempt to manipulate the list
> under the wrong lock.
> 
> v2: Code sharing is fun.
> 
> Fixes: 6c81e21a4742 ("drm/i915/gt: Stage the transfer of the virtual breadcrumb")
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
> ---
>   drivers/gpu/drm/i915/gt/intel_breadcrumbs.c  | 52 ++++++++++++++++----
>   drivers/gpu/drm/i915/gt/intel_engine.h       |  3 ++
>   drivers/gpu/drm/i915/gt/intel_engine_types.h |  2 +
>   drivers/gpu/drm/i915/gt/intel_lrc.c          | 34 ++++---------
>   4 files changed, 57 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
> index cbedba857d43..d907d538176e 100644
> --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
> @@ -142,6 +142,18 @@ static void add_retire(struct intel_breadcrumbs *b, struct intel_timeline *tl)
>   	intel_engine_add_retire(engine, tl);
>   }
>   
> +static void __signal_request(struct i915_request *rq, struct list_head *signals)
> +{
> +	GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags));
> +	clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
> +
> +	if (!__dma_fence_signal(&rq->fence))
> +		return;
> +
> +	i915_request_get(rq);
> +	list_add_tail(&rq->signal_link, signals);
> +}
> +
>   static void signal_irq_work(struct irq_work *work)
>   {
>   	struct intel_breadcrumbs *b = container_of(work, typeof(*b), irq_work);
> @@ -155,6 +167,8 @@ static void signal_irq_work(struct irq_work *work)
>   	if (b->irq_armed && list_empty(&b->signalers))
>   		__intel_breadcrumbs_disarm_irq(b);
>   
> +	list_splice_init(&b->signaled_requests, &signal);
> +
>   	list_for_each_entry_safe(ce, cn, &b->signalers, signal_link) {
>   		GEM_BUG_ON(list_empty(&ce->signals));
>   
> @@ -163,24 +177,15 @@ static void signal_irq_work(struct irq_work *work)
>   				list_entry(pos, typeof(*rq), signal_link);
>   
>   			GEM_BUG_ON(!check_signal_order(ce, rq));
> -
>   			if (!__request_completed(rq))
>   				break;
>   
> -			GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL,
> -					     &rq->fence.flags));
> -			clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
> -
> -			if (!__dma_fence_signal(&rq->fence))
> -				continue;
> -
>   			/*
>   			 * Queue for execution after dropping the signaling
>   			 * spinlock as the callback chain may end up adding
>   			 * more signalers to the same context or engine.
>   			 */
> -			i915_request_get(rq);
> -			list_add_tail(&rq->signal_link, &signal);
> +			__signal_request(rq, &signal);
>   		}
>   
>   		/*
> @@ -255,6 +260,7 @@ void intel_engine_init_breadcrumbs(struct intel_engine_cs *engine)
>   
>   	spin_lock_init(&b->irq_lock);
>   	INIT_LIST_HEAD(&b->signalers);
> +	INIT_LIST_HEAD(&b->signaled_requests);
>   
>   	init_irq_work(&b->irq_work, signal_irq_work);
>   }
> @@ -274,6 +280,32 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine)
>   	spin_unlock_irqrestore(&b->irq_lock, flags);
>   }
>   
> +void intel_engine_transfer_stale_breadcrumbs(struct intel_engine_cs *engine,
> +					     struct intel_context *ce)
> +{
> +	struct intel_breadcrumbs *b = &engine->breadcrumbs;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&b->irq_lock, flags);
> +	if (!list_empty(&ce->signals)) {
> +		struct i915_request *rq, *next;
> +
> +		/* Queue for executing the signal callbacks in the irq_work */
> +		list_for_each_entry_safe(rq, next, &ce->signals, signal_link) {
> +			GEM_BUG_ON(rq->engine != engine);
> +			GEM_BUG_ON(!__request_completed(rq));
> +
> +			__signal_request(rq, &b->signaled_requests);
> +		}
> +
> +		INIT_LIST_HEAD(&ce->signals);
> +		list_del_init(&ce->signal_link);
> +
> +		irq_work_queue(&b->irq_work);
> +	}
> +	spin_unlock_irqrestore(&b->irq_lock, flags);
> +}
> +
>   void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)
>   {
>   }
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
> index cb789c8bf06b..9bf6d4989968 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine.h
> @@ -238,6 +238,9 @@ intel_engine_signal_breadcrumbs(struct intel_engine_cs *engine)
>   void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine);
>   void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine);
>   
> +void intel_engine_transfer_stale_breadcrumbs(struct intel_engine_cs *engine,
> +					     struct intel_context *ce);
> +
>   void intel_engine_print_breadcrumbs(struct intel_engine_cs *engine,
>   				    struct drm_printer *p);
>   
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> index c113b7805e65..e20b39eefd79 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
> @@ -377,6 +377,8 @@ struct intel_engine_cs {
>   		spinlock_t irq_lock;
>   		struct list_head signalers;
>   
> +		struct list_head signaled_requests;
> +
>   		struct irq_work irq_work; /* for use from inside irq_lock */
>   
>   		unsigned int irq_enabled;
> diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
> index 15716e4d6b76..3d0e0894c015 100644
> --- a/drivers/gpu/drm/i915/gt/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
> @@ -1821,30 +1821,16 @@ static bool virtual_matches(const struct virtual_engine *ve,
>   	return true;
>   }
>   
> -static void virtual_xfer_breadcrumbs(struct virtual_engine *ve,
> -				     struct i915_request *rq)
> +static void virtual_xfer_breadcrumbs(struct virtual_engine *ve)
>   {
> -	struct intel_engine_cs *old = ve->siblings[0];
> -
> -	/* All unattached (rq->engine == old) must already be completed */
> -
> -	spin_lock(&old->breadcrumbs.irq_lock);
> -	if (!list_empty(&ve->context.signal_link)) {
> -		list_del_init(&ve->context.signal_link);
> -
> -		/*
> -		 * We cannot acquire the new engine->breadcrumbs.irq_lock
> -		 * (as we are holding a breadcrumbs.irq_lock already),
> -		 * so attach this request to the signaler on submission.
> -		 * The queued irq_work will occur when we finally drop
> -		 * the engine->active.lock after dequeue.
> -		 */
> -		set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &rq->fence.flags);
> -
> -		/* Also transfer the pending irq_work for the old breadcrumb. */
> -		intel_engine_signal_breadcrumbs(rq->engine);
> -	}
> -	spin_unlock(&old->breadcrumbs.irq_lock);
> +	/*
> +	 * All the outstanding signals on ve->siblings[0] must have
> +	 * been completed, just pending the interrupt handler. As those
> +	 * signals still refer to the old sibling (via rq->engine), we must
> +	 * transfer those to the old irq_worker to keep our locking
> +	 * consistent.
> +	 */
> +	intel_engine_transfer_stale_breadcrumbs(ve->siblings[0], &ve->context);
>   }
>   
>   #define for_each_waiter(p__, rq__) \
> @@ -2279,7 +2265,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
>   									engine);
>   
>   				if (!list_empty(&ve->context.signals))
> -					virtual_xfer_breadcrumbs(ve, rq);
> +					virtual_xfer_breadcrumbs(ve);
>   
>   				/*
>   				 * Move the bound engine to the top of the list
> 

Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Regards,

Tvrtko
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

      parent reply	other threads:[~2020-05-14  8:55 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-13  7:47 [Intel-gfx] [PATCH 01/24] drm/i915/gt: Transfer old virtual breadcrumbs to irq_worker Chris Wilson
2020-05-13  7:47 ` [Intel-gfx] [PATCH 02/24] dma-buf: Use atomic_fetch_add() for the context id Chris Wilson
2020-05-13 12:37   ` Patelczyk, Maciej
2020-05-13  7:47 ` [Intel-gfx] [PATCH 03/24] drm/i915: Mark the addition of the initial-breadcrumb in the request Chris Wilson
2020-05-13  7:47 ` [Intel-gfx] [PATCH 04/24] dma-buf: Proxy fence, an unsignaled fence placeholder Chris Wilson
2020-05-13  7:47 ` [Intel-gfx] [PATCH 05/24] drm/syncobj: Allow use of dma-fence-proxy Chris Wilson
2020-05-13  7:47 ` [Intel-gfx] [PATCH 06/24] drm/i915/gem: Teach execbuf how to wait on future syncobj Chris Wilson
2020-05-13  7:47 ` [Intel-gfx] [PATCH 07/24] drm/i915/gem: Allow combining submit-fences with syncobj Chris Wilson
2020-05-13  7:47 ` [Intel-gfx] [PATCH 08/24] drm/i915/gt: Declare when we enabled timeslicing Chris Wilson
2020-05-13  7:47 ` [Intel-gfx] [PATCH 09/24] drm/i915/gem: Remove redundant exec_fence Chris Wilson
2020-05-13  7:47 ` [Intel-gfx] [PATCH 10/24] drm/i915: Drop no-semaphore boosting Chris Wilson
2020-05-13 17:04   ` Mika Kuoppala
2020-05-13  7:47 ` [Intel-gfx] [PATCH 11/24] drm/i915: Move saturated workload detection back to the context Chris Wilson
2020-05-13  7:47 ` [Intel-gfx] [PATCH 12/24] drm/i915: Remove the saturation backoff for HW semaphores Chris Wilson
2020-05-13  7:47 ` [Intel-gfx] [PATCH 13/24] drm/i915/gt: Use built-in active intel_context reference Chris Wilson
2020-05-13  7:47 ` [Intel-gfx] [PATCH 14/24] drm/i915: Drop I915_RESET_TIMEOUT and friends Chris Wilson
2020-05-13 12:48   ` Patelczyk, Maciej
2020-05-13  7:48 ` [Intel-gfx] [PATCH 15/24] drm/i915: Drop I915_IDLE_ENGINES_TIMEOUT Chris Wilson
2020-05-13  7:48 ` [Intel-gfx] [PATCH 16/24] drm/i915/selftests: Always call the provided engine->emit_init_breadcrumb Chris Wilson
2020-05-14  7:55   ` Mika Kuoppala
2020-05-13  7:48 ` [Intel-gfx] [PATCH 17/24] drm/i915/gt: Do not suspend bonded requests if one hangs Chris Wilson
2020-05-13  7:48 ` [Intel-gfx] [PATCH 18/24] drm/i915: Always defer fenced work to the worker Chris Wilson
2020-05-13  7:48 ` [Intel-gfx] [PATCH 19/24] drm/i915/gem: Assign context id for async work Chris Wilson
2020-05-13  7:48 ` [Intel-gfx] [PATCH 20/24] drm/i915: Export a preallocate variant of i915_active_acquire() Chris Wilson
2020-05-13  7:48 ` [Intel-gfx] [PATCH 21/24] drm/i915/gem: Separate the ww_mutex walker into its own list Chris Wilson
2020-05-13  7:48 ` [Intel-gfx] [PATCH 22/24] drm/i915/gem: Asynchronous GTT unbinding Chris Wilson
2020-05-13  7:48 ` [Intel-gfx] [PATCH 23/24] drm/i915/gem: Bind the fence async for execbuf Chris Wilson
2020-05-13  7:48 ` [Intel-gfx] [PATCH 24/24] drm/i915: Show per-engine default property values in sysfs Chris Wilson
2020-05-13 13:40   ` Patelczyk, Maciej
2020-05-13  8:01 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/24] drm/i915/gt: Transfer old virtual breadcrumbs to irq_worker Patchwork
2020-05-13  8:28 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2020-05-14  8:55 ` Tvrtko Ursulin [this message]

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=f5ada51e-fda6-c57e-0d1b-8fd008a92c4b@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.