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 07/10] drm/i915/gt: Hold context/request reference while breadcrumbs are active
Date: Wed, 22 Jul 2020 14:05:35 +0100	[thread overview]
Message-ID: <6f820d97-f60e-03f3-5ac3-88d73486e405@linux.intel.com> (raw)
In-Reply-To: <20200720092312.16975-7-chris@chris-wilson.co.uk>


On 20/07/2020 10:23, Chris Wilson wrote:
> Currently we hold no actual reference to the request nor context while
> they are attached to a breadcrumb. To avoid freeing the request/context
> too early, we serialise with cancel-breadcrumbs by taking the irq
> spinlock in i915_request_retire(). The alternative is to take a
> reference for a new breadcrumb and release it upon signaling; removing
> the more frequently hit contention point in i915_request_retire().
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 58 ++++++++++++++++-----
>   drivers/gpu/drm/i915/i915_request.c         |  9 ++--
>   2 files changed, 48 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
> index d6008034869f..59e8cd505569 100644
> --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
> @@ -29,6 +29,7 @@
>   #include "i915_drv.h"
>   #include "i915_trace.h"
>   #include "intel_breadcrumbs.h"
> +#include "intel_context.h"
>   #include "intel_gt_pm.h"
>   #include "intel_gt_requests.h"
>   
> @@ -100,6 +101,22 @@ static void __intel_breadcrumbs_disarm_irq(struct intel_breadcrumbs *b)
>   	intel_gt_pm_put_async(b->irq_engine->gt);
>   }
>   
> +static void add_signaling_context(struct intel_breadcrumbs *b,
> +				  struct intel_context *ce)
> +{
> +	intel_context_get(ce);
> +	list_add_tail(&ce->signal_link, &b->signalers);
> +	if (list_is_first(&ce->signal_link, &b->signalers))
> +		__intel_breadcrumbs_arm_irq(b);
> +}
> +
> +static void remove_signaling_context(struct intel_breadcrumbs *b,
> +				     struct intel_context *ce)
> +{
> +	list_del(&ce->signal_link);
> +	intel_context_put(ce);
> +}
> +
>   static inline bool __request_completed(const struct i915_request *rq)
>   {
>   	return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno);
> @@ -108,6 +125,9 @@ static inline bool __request_completed(const struct i915_request *rq)
>   __maybe_unused static bool
>   check_signal_order(struct intel_context *ce, struct i915_request *rq)
>   {
> +	if (rq->context != ce)
> +		return false;
> +
>   	if (!list_is_last(&rq->signal_link, &ce->signals) &&
>   	    i915_seqno_passed(rq->fence.seqno,
>   			      list_next_entry(rq, signal_link)->fence.seqno))
> @@ -162,7 +182,6 @@ static bool __signal_request(struct i915_request *rq, struct list_head *signals)
>   	if (!__dma_fence_signal(&rq->fence))
>   		return false;
>   
> -	i915_request_get(rq);
>   	list_add_tail(&rq->signal_link, signals);
>   	return true;
>   }
> @@ -198,7 +217,8 @@ static void signal_irq_work(struct irq_work *work)
>   			 * spinlock as the callback chain may end up adding
>   			 * more signalers to the same context or engine.
>   			 */
> -			__signal_request(rq, &signal);
> +			if (!__signal_request(rq, &signal))
> +				i915_request_put(rq);

Looks like __signal_request could do the request put but doesn't matter 
hugely.

>   		}
>   
>   		/*
> @@ -210,7 +230,7 @@ static void signal_irq_work(struct irq_work *work)
>   			/* Advance the list to the first incomplete request */
>   			__list_del_many(&ce->signals, pos);
>   			if (&ce->signals == pos) { /* now empty */
> -				list_del_init(&ce->signal_link);
> +				remove_signaling_context(b, ce);
>   				add_retire(b, ce->timeline);
>   			}
>   		}
> @@ -282,6 +302,8 @@ void intel_breadcrumbs_park(struct intel_breadcrumbs *b)
>   	spin_lock_irqsave(&b->irq_lock, flags);
>   	if (b->irq_armed)
>   		__intel_breadcrumbs_disarm_irq(b);
> +	if (!list_empty(&b->signalers))
> +		irq_work_queue(&b->irq_work);
>   	spin_unlock_irqrestore(&b->irq_lock, flags);
>   }
>   
> @@ -299,6 +321,8 @@ static void insert_breadcrumb(struct i915_request *rq,
>   	if (test_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags))
>   		return;
>   
> +	i915_request_get(rq);
> +
>   	/*
>   	 * If the request is already completed, we can transfer it
>   	 * straight onto a signaled list, and queue the irq worker for
> @@ -307,11 +331,11 @@ static void insert_breadcrumb(struct i915_request *rq,
>   	if (__request_completed(rq)) {
>   		if (__signal_request(rq, &b->signaled_requests))
>   			irq_work_queue(&b->irq_work);
> +		else
> +			i915_request_put(rq);
>   		return;
>   	}
>   
> -	__intel_breadcrumbs_arm_irq(b);
> -
>   	/*
>   	 * We keep the seqno in retirement order, so we can break
>   	 * inside intel_engine_signal_breadcrumbs as soon as we've
> @@ -326,16 +350,20 @@ static void insert_breadcrumb(struct i915_request *rq,
>   	 * start looking for our insertion point from the tail of
>   	 * the list.
>   	 */
> -	list_for_each_prev(pos, &ce->signals) {
> -		struct i915_request *it =
> -			list_entry(pos, typeof(*it), signal_link);
> -
> -		if (i915_seqno_passed(rq->fence.seqno, it->fence.seqno))
> -			break;
> +	if (list_empty(&ce->signals)) {
> +		add_signaling_context(b, ce);
> +		GEM_BUG_ON(!b->irq_armed);
> +		pos = &ce->signals;
> +	} else {
> +		list_for_each_prev(pos, &ce->signals) {
> +			struct i915_request *it =
> +				list_entry(pos, typeof(*it), signal_link);
> +
> +			if (i915_seqno_passed(rq->fence.seqno, it->fence.seqno))
> +				break;
> +		}
>   	}
>   	list_add(&rq->signal_link, pos);
> -	if (pos == &ce->signals) /* catch transitions from empty list */
> -		list_move_tail(&ce->signal_link, &b->signalers);
>   	GEM_BUG_ON(!check_signal_order(ce, rq));
>   	set_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
>   
> @@ -416,9 +444,10 @@ void i915_request_cancel_breadcrumb(struct i915_request *rq)
>   
>   		list_del(&rq->signal_link);
>   		if (list_empty(&ce->signals))
> -			list_del_init(&ce->signal_link);
> +			remove_signaling_context(b, ce);
>   
>   		clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
> +		i915_request_put(rq);
>   	}
>   	spin_unlock(&b->irq_lock);
>   }
> @@ -433,6 +462,7 @@ void intel_engine_print_breadcrumbs(struct intel_engine_cs *engine,
>   	if (!b || list_empty(&b->signalers))
>   		return;
>   
> +	drm_printf(p, "IRQ: %s\n", enableddisabled(b->irq_armed));
>   	drm_printf(p, "Signals:\n");
>   
>   	spin_lock_irq(&b->irq_lock);
> diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c
> index 394587e70a2d..4ebb0f144ac4 100644
> --- a/drivers/gpu/drm/i915/i915_request.c
> +++ b/drivers/gpu/drm/i915/i915_request.c
> @@ -300,12 +300,11 @@ bool i915_request_retire(struct i915_request *rq)
>   		__i915_request_fill(rq, POISON_FREE);
>   	rq->ring->head = rq->postfix;
>   
> -	spin_lock_irq(&rq->lock);
> -	if (!i915_request_signaled(rq))
> +	if (!i915_request_signaled(rq)) {
> +		spin_lock_irq(&rq->lock);
>   		dma_fence_signal_locked(&rq->fence);
> -	if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &rq->fence.flags))
> -		i915_request_cancel_breadcrumb(rq);
> -	spin_unlock_irq(&rq->lock);
> +		spin_unlock_irq(&rq->lock);
> +	}
>   
>   	if (i915_request_has_waitboost(rq)) {
>   		GEM_BUG_ON(!atomic_read(&rq->engine->gt->rps.num_waiters));
> 

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

  reply	other threads:[~2020-07-22 13:05 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-20  9:23 [Intel-gfx] [PATCH 01/10] drm/i915/gem: Remove disordered per-file request list for throttling Chris Wilson
2020-07-20  9:23 ` [Intel-gfx] [PATCH 02/10] drm/i915: Remove requirement for holding i915_request.lock for breadcrumbs Chris Wilson
2020-07-20  9:23 ` [Intel-gfx] [PATCH 03/10] drm/i915/gt: Replace intel_engine_transfer_stale_breadcrumbs Chris Wilson
2020-07-20  9:32   ` Tvrtko Ursulin
2020-07-20  9:23 ` [Intel-gfx] [PATCH 04/10] drm/i915/gt: Only transfer the virtual context to the new engine if active Chris Wilson
2020-07-20  9:23 ` [Intel-gfx] [PATCH 05/10] drm/i915/gt: Distinguish the virtual breadcrumbs from the irq breadcrumbs Chris Wilson
2020-07-20 11:23   ` Tvrtko Ursulin
2020-07-20 15:02     ` Chris Wilson
2020-07-22  8:12       ` Tvrtko Ursulin
2020-07-22  8:30         ` Chris Wilson
2020-07-21  7:59   ` kernel test robot
2020-07-21  7:59     ` kernel test robot
2020-07-20  9:23 ` [Intel-gfx] [PATCH 06/10] drm/i915/gt: Move intel_breadcrumbs_arm_irq earlier Chris Wilson
2020-07-22 12:55   ` Tvrtko Ursulin
2020-07-20  9:23 ` [Intel-gfx] [PATCH 07/10] drm/i915/gt: Hold context/request reference while breadcrumbs are active Chris Wilson
2020-07-22 13:05   ` Tvrtko Ursulin [this message]
2020-07-22 13:11     ` Chris Wilson
2020-07-20  9:23 ` [Intel-gfx] [PATCH 08/10] drm/i915/gt: Track signaled breadcrumbs outside of the breadcrumb spinlock Chris Wilson
2020-07-22 13:26   ` Tvrtko Ursulin
2020-07-22 13:42     ` Chris Wilson
2020-07-20  9:23 ` [Intel-gfx] [PATCH 09/10] drm/i915/gt: Split the breadcrumb spinlock between global and contexts Chris Wilson
2020-07-20  9:23 ` [Intel-gfx] [PATCH 10/10] drm/i915: Drop i915_request.lock serialisation around await_start Chris Wilson
2020-07-20 10:33 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/10] drm/i915/gem: Remove disordered per-file request list for throttling Patchwork
2020-07-20 10:34 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-07-20 10:55 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-07-20 13:44 ` [Intel-gfx] ✗ 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=6f820d97-f60e-03f3-5ac3-88d73486e405@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.