[Intel-gfx] [PATCH] drm/i915/gt: Stage the transfer of the virtual breadcrumb

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Wed Mar 25 14:01:19 UTC 2020


On 25/03/2020 13:00, Chris Wilson wrote:
> We move the virtual breadcrumb from one physical engine to the next, if
> the next virtual request is scheduled on a new physical engine. Since
> the virtual context can only be in one signal queue, we need it to track
> the current physical engine for the new breadcrumbs. However, to move
> the list we need both breadcrumb locks -- and since we cannot take both
> at the same time (unless we are careful and always ensure consistent
> ordering) stage the movement of the signaler via the current virtual
> request.
> 
> Closes: https://gitlab.freedesktop.org/drm/intel/issues/1510
> Fixes: 6d06779e8672 ("drm/i915: Load balancing across a virtual engine")
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> ---
>   drivers/gpu/drm/i915/gt/intel_lrc.c | 18 +++++++++++++-----
>   1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
> index f88d3b95c4e1..2b0923cb0483 100644
> --- a/drivers/gpu/drm/i915/gt/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
> @@ -1663,7 +1663,7 @@ static bool virtual_matches(const struct virtual_engine *ve,
>   }
>   
>   static void virtual_xfer_breadcrumbs(struct virtual_engine *ve,
> -				     struct intel_engine_cs *engine)
> +				     struct i915_request *rq)
>   {
>   	struct intel_engine_cs *old = ve->siblings[0];
>   
> @@ -1671,9 +1671,17 @@ static void virtual_xfer_breadcrumbs(struct virtual_engine *ve,
>   
>   	spin_lock(&old->breadcrumbs.irq_lock);
>   	if (!list_empty(&ve->context.signal_link)) {
> -		list_move_tail(&ve->context.signal_link,
> -			       &engine->breadcrumbs.signalers);
> -		intel_engine_signal_breadcrumbs(engine);
> +		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);
> +		intel_engine_signal_breadcrumbs(rq->engine);
>   	}
>   	spin_unlock(&old->breadcrumbs.irq_lock);
>   }
> @@ -2045,7 +2053,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
>   									engine);
>   
>   				if (!list_empty(&ve->context.signals))
> -					virtual_xfer_breadcrumbs(ve, engine);
> +					virtual_xfer_breadcrumbs(ve, rq);
>   
>   				/*
>   				 * Move the bound engine to the top of the list
> 

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

Regards,

Tvrtko


More information about the Intel-gfx mailing list