[Intel-gfx] [PATCH] drm/i915: Skip context_barrier emission for unused contexts

Tvrtko Ursulin tvrtko.ursulin at linux.intel.com
Wed Jun 5 10:40:27 UTC 2019


On 04/06/2019 16:24, Chris Wilson wrote:
> The intent was to skip unused HW contexts by checking ce->state.
> However, this only works for execlists where the ppGTT pointers is
> stored inside the HW context. For gen7, the ppGTT is alongside the
> logical state and must be updated on all active engines but, crucially,
> only on active engines. As we need different checks, and to keep
> context_barrier_task() agnostic, pass in the predicate.
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=110836
> Fixes: 62c8e423450d ("drm/i915: Skip unused contexts for context_barrier_task()")
> 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   | 15 ++++++++++++++-
>   .../drm/i915/gem/selftests/i915_gem_context.c | 19 +++++++++++++++----
>   2 files changed, 29 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index 08721ef62e4e..6819b598d226 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -902,6 +902,7 @@ static void cb_retire(struct i915_active *base)
>   I915_SELFTEST_DECLARE(static intel_engine_mask_t context_barrier_inject_fault);
>   static int context_barrier_task(struct i915_gem_context *ctx,
>   				intel_engine_mask_t engines,
> +				bool (*skip)(struct intel_context *ce, void *data),
>   				int (*emit)(struct i915_request *rq, void *data),
>   				void (*task)(void *data),
>   				void *data)
> @@ -931,7 +932,10 @@ static int context_barrier_task(struct i915_gem_context *ctx,
>   			break;
>   		}
>   
> -		if (!(ce->engine->mask & engines) || !ce->state)
> +		if (!(ce->engine->mask & engines))
> +			continue;
> +
> +		if (skip && skip(ce, data))
>   			continue;
>   
>   		rq = intel_context_create_request(ce);
> @@ -1058,6 +1062,14 @@ static int emit_ppgtt_update(struct i915_request *rq, void *data)
>   	return 0;
>   }
>   
> +static bool skip_ppgtt_update(struct intel_context *ce, void *data)
> +{
> +	if (HAS_LOGICAL_RING_CONTEXTS(ce->engine->i915))
> +		return !ce->state;
> +	else
> +		return !atomic_read(&ce->pin_count);

Would "return !atomic_read(&ce->pin_count) || !ce->state;" work and 
avoid the somewhat irky HAS_LOGICAL_RING_CONTEXTS check?

Regards,

Tvrtko

> +}
> +
>   static int set_ppgtt(struct drm_i915_file_private *file_priv,
>   		     struct i915_gem_context *ctx,
>   		     struct drm_i915_gem_context_param *args)
> @@ -1103,6 +1115,7 @@ static int set_ppgtt(struct drm_i915_file_private *file_priv,
>   	 * only indirectly through the context.
>   	 */
>   	err = context_barrier_task(ctx, ALL_ENGINES,
> +				   skip_ppgtt_update,
>   				   emit_ppgtt_update,
>   				   set_ppgtt_barrier,
>   				   old);
> diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
> index 1bc3b8026400..41105f6ed206 100644
> --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
> @@ -1619,6 +1619,11 @@ __engine_name(struct drm_i915_private *i915, intel_engine_mask_t engines)
>   	return "none";
>   }
>   
> +static bool skip_unused_engines(struct intel_context *ce, void *data)
> +{
> +	return !ce->state;
> +}
> +
>   static void mock_barrier_task(void *data)
>   {
>   	unsigned int *counter = data;
> @@ -1651,7 +1656,7 @@ static int mock_context_barrier(void *arg)
>   
>   	counter = 0;
>   	err = context_barrier_task(ctx, 0,
> -				   NULL, mock_barrier_task, &counter);
> +				   NULL, NULL, mock_barrier_task, &counter);
>   	if (err) {
>   		pr_err("Failed at line %d, err=%d\n", __LINE__, err);
>   		goto out;
> @@ -1664,7 +1669,10 @@ static int mock_context_barrier(void *arg)
>   
>   	counter = 0;
>   	err = context_barrier_task(ctx, ALL_ENGINES,
> -				   NULL, mock_barrier_task, &counter);
> +				   skip_unused_engines,
> +				   NULL,
> +				   mock_barrier_task,
> +				   &counter);
>   	if (err) {
>   		pr_err("Failed at line %d, err=%d\n", __LINE__, err);
>   		goto out;
> @@ -1685,7 +1693,7 @@ static int mock_context_barrier(void *arg)
>   	counter = 0;
>   	context_barrier_inject_fault = BIT(RCS0);
>   	err = context_barrier_task(ctx, ALL_ENGINES,
> -				   NULL, mock_barrier_task, &counter);
> +				   NULL, NULL, mock_barrier_task, &counter);
>   	context_barrier_inject_fault = 0;
>   	if (err == -ENXIO)
>   		err = 0;
> @@ -1700,7 +1708,10 @@ static int mock_context_barrier(void *arg)
>   
>   	counter = 0;
>   	err = context_barrier_task(ctx, ALL_ENGINES,
> -				   NULL, mock_barrier_task, &counter);
> +				   skip_unused_engines,
> +				   NULL,
> +				   mock_barrier_task,
> +				   &counter);
>   	if (err) {
>   		pr_err("Failed at line %d, err=%d\n", __LINE__, err);
>   		goto out;
> 


More information about the Intel-gfx mailing list