[Intel-gfx] [PATCH 4/4] drm/i915: Protect timeline->hwsp dereferencing

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Thu Sep 19 10:48:25 UTC 2019


On 18/09/2019 15:54, Chris Wilson wrote:
> As not only is the signal->timeline volatile, so will be acquiring the
> timeline's HWSP. We must first carefully acquire the timeline from the
> signaling request and then lock the timeline. With the removal of the
> struct_mutex serialisation of request construction, we can have multiple
> timelines active at once, and so we must avoid using the nested mutex
> lock as it is quite possible for both timelines to be establishing
> semaphores on the other and so deadlock.
> 
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin at linux.intel.com>
> ---
>   drivers/gpu/drm/i915/gt/intel_timeline.c | 32 ++++++++++++++++++------
>   1 file changed, 25 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c
> index 2ce81bdf7f86..7b1d4098dd2e 100644
> --- a/drivers/gpu/drm/i915/gt/intel_timeline.c
> +++ b/drivers/gpu/drm/i915/gt/intel_timeline.c
> @@ -500,17 +500,32 @@ int intel_timeline_read_hwsp(struct i915_request *from,
>   			     struct i915_request *to,
>   			     u32 *hwsp)
>   {
> -	struct intel_timeline_cacheline *cl = from->hwsp_cacheline;
> -	struct intel_timeline *tl = from->timeline;

I think this should have been annotated in 2/4.

> +	struct intel_timeline *tl;
>   	int err;
>   
> +	rcu_read_lock();
> +	tl = rcu_dereference(from->timeline);
> +	if (i915_request_completed(from) || !kref_get_unless_zero(&tl->kref))
> +		tl = NULL;
> +	rcu_read_unlock();
> +	if (!tl) /* already completed */
> +		return 1;
> +
>   	GEM_BUG_ON(rcu_access_pointer(to->timeline) == tl);
>   
> -	mutex_lock_nested(&tl->mutex, SINGLE_DEPTH_NESTING);
> -	err = i915_request_completed(from);
> -	if (!err)
> +	err = -EBUSY;
> +	if (mutex_trylock(&tl->mutex)) {
> +		struct intel_timeline_cacheline *cl = from->hwsp_cacheline;
> +
> +		if (i915_request_completed(from)) {
> +			err = 1;
> +			goto unlock;
> +		}
> +
>   		err = cacheline_ref(cl, to);
> -	if (!err) {
> +		if (err)
> +			goto unlock;
> +
>   		if (likely(cl == tl->hwsp_cacheline)) {
>   			*hwsp = tl->hwsp_offset;
>   		} else { /* across a seqno wrap, recover the original offset */
> @@ -518,8 +533,11 @@ int intel_timeline_read_hwsp(struct i915_request *from,
>   				ptr_unmask_bits(cl->vaddr, CACHELINE_BITS) *
>   				CACHELINE_BYTES;
>   		}
> +
> +unlock:
> +		mutex_unlock(&tl->mutex);
>   	}
> -	mutex_unlock(&tl->mutex);
> +	intel_timeline_put(tl);
>   
>   	return err;
>   }
> 

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

Regards,

Tvrtko


More information about the Intel-gfx mailing list