[Intel-gfx] [PATCH v3] drm/i915: Add to timeline requires the timeline mutex

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Mon Jul 8 12:18:02 UTC 2019


On 08/07/2019 12:39, Chris Wilson wrote:
> Modifying a remote context requires careful serialisation with requests
> on that context, and that serialisation requires us to take their
> timeline->mutex. Make it so.
> 
> Note that while struct_mutex rules, we can't create more than one
> request in parallel, but that age is soon coming to an end.
> 
> v2: Though it doesn't affect the current users, contexts may share
> timelines so check if we already hold the right mutex.
> 
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> ---
>   drivers/gpu/drm/i915/gem/i915_gem_context.c | 16 ++-------
>   drivers/gpu/drm/i915/gt/intel_context.c     | 38 +++++++++++++++++++++
>   drivers/gpu/drm/i915/gt/intel_context.h     |  3 ++
>   drivers/gpu/drm/i915/i915_perf.c            |  7 +---
>   4 files changed, 44 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index 1f0d10bb88c1..6000177472ee 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -1192,20 +1192,8 @@ gen8_modify_rpcs(struct intel_context *ce, struct intel_sseu sseu)
>   	if (IS_ERR(rq))
>   		return PTR_ERR(rq);
>   
> -	/* Queue this switch after all other activity by this context. */
> -	ret = i915_active_request_set(&ce->ring->timeline->last_request, rq);
> -	if (ret)
> -		goto out_add;
> -
> -	/*
> -	 * Guarantee context image and the timeline remains pinned until the
> -	 * modifying request is retired by setting the ce activity tracker.
> -	 *
> -	 * But we only need to take one pin on the account of it. Or in other
> -	 * words transfer the pinned ce object to tracked active request.
> -	 */
> -	GEM_BUG_ON(i915_active_is_idle(&ce->active));
> -	ret = i915_active_ref(&ce->active, rq->fence.context, rq);
> +	/* Serialise with the remote context */
> +	ret = intel_context_prepare_remote_request(ce, rq);
>   	if (ret)
>   		goto out_add;
>   
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
> index 1110fc8f657a..b1e2e4b60027 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.c
> +++ b/drivers/gpu/drm/i915/gt/intel_context.c
> @@ -239,6 +239,44 @@ void intel_context_exit_engine(struct intel_context *ce)
>   	intel_engine_pm_put(ce->engine);
>   }
>   
> +int intel_context_prepare_remote_request(struct intel_context *ce,
> +					 struct i915_request *rq)
> +{
> +	struct intel_timeline *tl = ce->ring->timeline;
> +	int err;
> +
> +	/* Only suitable for use in remotely modifying this context */
> +	GEM_BUG_ON(rq->hw_context == ce);
> +
> +	if (rq->timeline != tl) { /* beware timeline sharing */
> +		err = mutex_lock_interruptible_nested(&tl->mutex,
> +						      SINGLE_DEPTH_NESTING);

Which caller is holding tl->mutex?

Regards,

Tvrtko

> +		if (err)
> +			return err;
> +	}
> +	lockdep_assert_held(&tl->mutex);
> +
> +	/* Queue this switch after all other activity by this context. */
> +	err = i915_active_request_set(&tl->last_request, rq);
> +	if (err)
> +		goto unlock;
> +
> +	/*
> +	 * Guarantee context image and the timeline remains pinned until the
> +	 * modifying request is retired by setting the ce activity tracker.
> +	 *
> +	 * But we only need to take one pin on the account of it. Or in other
> +	 * words transfer the pinned ce object to tracked active request.
> +	 */
> +	GEM_BUG_ON(i915_active_is_idle(&ce->active));
> +	err = i915_active_ref(&ce->active, rq->fence.context, rq);
> +
> +unlock:
> +	if (rq->timeline != tl)
> +		mutex_unlock(&tl->mutex);
> +	return err;
> +}
> +
>   struct i915_request *intel_context_create_request(struct intel_context *ce)
>   {
>   	struct i915_request *rq;
> diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
> index 40cd8320fcc3..b41c610c2ce6 100644
> --- a/drivers/gpu/drm/i915/gt/intel_context.h
> +++ b/drivers/gpu/drm/i915/gt/intel_context.h
> @@ -139,6 +139,9 @@ static inline void intel_context_timeline_unlock(struct intel_context *ce)
>   	mutex_unlock(&ce->ring->timeline->mutex);
>   }
>   
> +int intel_context_prepare_remote_request(struct intel_context *ce,
> +					 struct i915_request *rq);
> +
>   struct i915_request *intel_context_create_request(struct intel_context *ce);
>   
>   #endif /* __INTEL_CONTEXT_H__ */
> diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
> index 25c34a0b521e..6f77014640b8 100644
> --- a/drivers/gpu/drm/i915/i915_perf.c
> +++ b/drivers/gpu/drm/i915/i915_perf.c
> @@ -1762,12 +1762,7 @@ static int gen8_modify_context(struct intel_context *ce,
>   		return PTR_ERR(rq);
>   
>   	/* Serialise with the remote context */
> -	err = i915_active_request_set(&ce->ring->timeline->last_request, rq);
> -	if (err)
> -		goto out_add;
> -
> -	/* Keep the remote context alive until after we finish editing */
> -	err = i915_active_ref(&ce->active, rq->fence.context, rq);
> +	err = intel_context_prepare_remote_request(ce, rq);
>   	if (err)
>   		goto out_add;
>   
> 


More information about the Intel-gfx mailing list