[Intel-gfx] [PATCH 5/5] drm/i915: Prevent bonded requests from overtaking each other on preemption

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Mon Sep 23 13:48:44 UTC 2019


On 21/09/2019 10:55, Chris Wilson wrote:
> Force bonded requests to run on distinct engines so that they cannot be
> shuffled onto the same engine where timeslicing will reverse the order.
> A bonded request will often wait on a semaphore signaled by its master,
> creating an implicit dependency -- if we ignore that implicit dependency
> and allow the bonded request to run on the same engine and before its
> master, we will cause a GPU hang. [Whether it will hang the GPU is
> debatable, we should keep on timeslicing and each timeslice should be
> "accidentally" counted as forward progress, in which case it should run
> but at one-half to one-third speed.]
> 
> We can prevent this inversion by restricting which engines we allow
> ourselves to jump to upon preemption, i.e. baking in the arrangement
> established at first execution. (We should also consider capturing the
> implicit dependency using i915_sched_add_dependency(), but first we need
> to think about the constraints that requires on the execution/retirement
> ordering.)
> 
> Fixes: 8ee36e048c98 ("drm/i915/execlists: Minimalistic timeslicing")
> References: ee1136908e9b ("drm/i915/execlists: Virtual engine bonding")
> Testcase: igt/gem_exec_balancer/bonded-slice
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Mika Kuoppala <mika.kuoppala at linux.intel.com>
> Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> ---
>   drivers/gpu/drm/i915/gt/intel_lrc.c | 20 ++++++++++++--------
>   1 file changed, 12 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c
> index 3eadd294bcd7..9872bb4c99fc 100644
> --- a/drivers/gpu/drm/i915/gt/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
> @@ -3846,18 +3846,22 @@ static void
>   virtual_bond_execute(struct i915_request *rq, struct dma_fence *signal)
>   {
>   	struct virtual_engine *ve = to_virtual_engine(rq->engine);
> +	intel_engine_mask_t allowed, exec;
>   	struct ve_bond *bond;
>   
> +	allowed = ~to_request(signal)->engine->mask;
> +
>   	bond = virtual_find_bond(ve, to_request(signal)->engine);
> -	if (bond) {
> -		intel_engine_mask_t old, new, cmp;
> +	if (bond)
> +		allowed &= bond->sibling_mask;
>   
> -		cmp = READ_ONCE(rq->execution_mask);
> -		do {
> -			old = cmp;
> -			new = cmp & bond->sibling_mask;
> -		} while ((cmp = cmpxchg(&rq->execution_mask, old, new)) != old);
> -	}
> +	/* Restrict the bonded request to run on only the available engines */
> +	exec = READ_ONCE(rq->execution_mask);
> +	while (!try_cmpxchg(&rq->execution_mask, &exec, exec & allowed))
> +		;
> +
> +	/* Prevent the master from being re-run on the bonded engines */
> +	to_request(signal)->execution_mask &= ~allowed;

I had an open here whether we should also fix the slave. At re-submit 
time what is preventing the slave being put on the same engine as the 
master?

Regards,

Tvrtko

>   }
>   
>   struct intel_context *
> 


More information about the Intel-gfx mailing list