[Intel-gfx] [PATCH 3/6] drm/i915/icl: new context descriptor support

Oscar Mateo oscar.mateo at intel.com
Tue Mar 6 22:27:24 UTC 2018



On 3/2/2018 8:14 AM, Mika Kuoppala wrote:
> From: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
>
> Starting from Gen11 the context descriptor format has been updated in
> the HW. The hw_id field has been considerably reduced in size and engine
> class and instance fields have been added.
>
> There is a slight name clashing issue because the field that we call
> hw_id is actually called SW Context ID in the specs for Gen11+.
>
> With the current size of the hw_id field we can have a maximum of 2k
> contexts at any time, but we could use the sw_counter field (which is sw
> defined) to increase that because the HW requirement is that
> engine_id + sw id + sw_counter is a unique number.
> GuC uses a similar method to support more contexts but does its tracking
> at lrc level. To avoid doing an implementation that will need to be
> reworked once GuC support lands, defer it for now and mark it as TODO.
>
> v2: rebased, add documentation, fix GEN11_ENGINE_INSTANCE_SHIFT
> v3: rebased, bring back lost code from i915_gem_context.c
> v4: make TODO comment more generic
> v5: be consistent with bit ordering, add extra checks (Chris)
>
> Cc: Oscar Mateo <oscar.mateo at intel.com>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Mika Kuoppala <mika.kuoppala at linux.intel.com>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>

v5 still looks good to me:
Reviewed-by: Oscar Mateo <oscar.mateo at intel.com>

> ---
>   drivers/gpu/drm/i915/i915_drv.h         |  1 +
>   drivers/gpu/drm/i915/i915_gem_context.c | 11 ++++++++--
>   drivers/gpu/drm/i915/i915_reg.h         |  6 ++++++
>   drivers/gpu/drm/i915/intel_engine_cs.c  |  3 +++
>   drivers/gpu/drm/i915/intel_lrc.c        | 36 +++++++++++++++++++++++++++++++--
>   5 files changed, 53 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 10c9e5e619ab..8e2e6585549d 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2103,6 +2103,7 @@ struct drm_i915_private {
>   		 */
>   		struct ida hw_ida;
>   #define MAX_CONTEXT_HW_ID (1<<21) /* exclusive */
> +#define GEN11_MAX_CONTEXT_HW_ID (1<<11) /* exclusive */
>   	} contexts;
>   
>   	u32 fdi_rx_config;
> diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
> index a73340ae9419..f2cbea7cf940 100644
> --- a/drivers/gpu/drm/i915/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/i915_gem_context.c
> @@ -211,9 +211,15 @@ static void context_close(struct i915_gem_context *ctx)
>   static int assign_hw_id(struct drm_i915_private *dev_priv, unsigned *out)
>   {
>   	int ret;
> +	unsigned int max;
> +
> +	if (INTEL_GEN(dev_priv) >= 11)
> +		max = GEN11_MAX_CONTEXT_HW_ID;
> +	else
> +		max = MAX_CONTEXT_HW_ID;
>   
>   	ret = ida_simple_get(&dev_priv->contexts.hw_ida,
> -			     0, MAX_CONTEXT_HW_ID, GFP_KERNEL);
> +			     0, max, GFP_KERNEL);
>   	if (ret < 0) {
>   		/* Contexts are only released when no longer active.
>   		 * Flush any pending retires to hopefully release some
> @@ -221,7 +227,7 @@ static int assign_hw_id(struct drm_i915_private *dev_priv, unsigned *out)
>   		 */
>   		i915_retire_requests(dev_priv);
>   		ret = ida_simple_get(&dev_priv->contexts.hw_ida,
> -				     0, MAX_CONTEXT_HW_ID, GFP_KERNEL);
> +				     0, max, GFP_KERNEL);
>   		if (ret < 0)
>   			return ret;
>   	}
> @@ -463,6 +469,7 @@ int i915_gem_contexts_init(struct drm_i915_private *dev_priv)
>   
>   	/* Using the simple ida interface, the max is limited by sizeof(int) */
>   	BUILD_BUG_ON(MAX_CONTEXT_HW_ID > INT_MAX);
> +	BUILD_BUG_ON(GEN11_MAX_CONTEXT_HW_ID > INT_MAX);
>   	ida_init(&dev_priv->contexts.hw_ida);
>   
>   	/* lowest priority; idle task */
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 45ae05d0fe78..9a62d20bea8e 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3912,6 +3912,12 @@ enum {
>   
>   #define GEN8_CTX_ID_SHIFT 32
>   #define GEN8_CTX_ID_WIDTH 21
> +#define GEN11_SW_CTX_ID_SHIFT 37
> +#define GEN11_SW_CTX_ID_WIDTH 11
> +#define GEN11_ENGINE_CLASS_SHIFT 61
> +#define GEN11_ENGINE_CLASS_WIDTH 3
> +#define GEN11_ENGINE_INSTANCE_SHIFT 48
> +#define GEN11_ENGINE_INSTANCE_WIDTH 6
>   
>   #define CHV_CLK_CTL1			_MMIO(0x101100)
>   #define VLV_CLK_CTL2			_MMIO(0x101104)
> diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
> index 911fc08658c5..4ba139c27fba 100644
> --- a/drivers/gpu/drm/i915/intel_engine_cs.c
> +++ b/drivers/gpu/drm/i915/intel_engine_cs.c
> @@ -234,6 +234,9 @@ intel_engine_setup(struct drm_i915_private *dev_priv,
>   	GEM_BUG_ON(info->class >= ARRAY_SIZE(intel_engine_classes));
>   	class_info = &intel_engine_classes[info->class];
>   
> +	BUILD_BUG_ON(MAX_ENGINE_CLASS >= BIT(GEN11_ENGINE_CLASS_WIDTH));
> +	BUILD_BUG_ON(MAX_ENGINE_INSTANCE >= BIT(GEN11_ENGINE_INSTANCE_WIDTH));
> +
>   	if (GEM_WARN_ON(info->class > MAX_ENGINE_CLASS))
>   		return -EINVAL;
>   
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index a96288c85cb9..e50d86af1345 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -204,6 +204,18 @@ static inline bool need_preempt(const struct intel_engine_cs *engine,
>    *      bits 32-52:    ctx ID, a globally unique tag
>    *      bits 53-54:    mbz, reserved for use by hardware
>    *      bits 55-63:    group ID, currently unused and set to 0
> + *
> + * Starting from Gen11, the upper dword of the descriptor has a new format:
> + *
> + *      bits 32-36:    reserved
> + *      bits 37-47:    SW context ID
> + *      bits 48:53:    engine instance
> + *      bit 54:        mbz, reserved for use by hardware
> + *      bits 55-60:    SW counter
> + *      bits 61-63:    engine class
> + *
> + * engine info, SW context ID and SW counter need to form a unique number
> + * (Context ID) per lrc.
>    */
>   static void
>   intel_lr_context_descriptor_update(struct i915_gem_context *ctx,
> @@ -212,12 +224,32 @@ intel_lr_context_descriptor_update(struct i915_gem_context *ctx,
>   	struct intel_context *ce = &ctx->engine[engine->id];
>   	u64 desc;
>   
> -	BUILD_BUG_ON(MAX_CONTEXT_HW_ID > (1<<GEN8_CTX_ID_WIDTH));
> +	BUILD_BUG_ON(MAX_CONTEXT_HW_ID > (BIT(GEN8_CTX_ID_WIDTH)));
> +	BUILD_BUG_ON(GEN11_MAX_CONTEXT_HW_ID > (BIT(GEN11_SW_CTX_ID_WIDTH)));
>   
>   	desc = ctx->desc_template;				/* bits  0-11 */
> +	GEM_BUG_ON(desc & GENMASK_ULL(63, 12));
> +
>   	desc |= i915_ggtt_offset(ce->state) + LRC_HEADER_PAGES * PAGE_SIZE;
>   								/* bits 12-31 */
> -	desc |= (u64)ctx->hw_id << GEN8_CTX_ID_SHIFT;		/* bits 32-52 */
> +	GEM_BUG_ON(desc & GENMASK_ULL(63, 32));
> +
> +	if (INTEL_GEN(ctx->i915) >= 11) {
> +		GEM_BUG_ON(ctx->hw_id >= BIT(GEN11_SW_CTX_ID_WIDTH));
> +		desc |= (u64)ctx->hw_id << GEN11_SW_CTX_ID_SHIFT;
> +								/* bits 37-47 */
> +
> +		desc |= (u64)engine->instance << GEN11_ENGINE_INSTANCE_SHIFT;
> +								/* bits 48-53 */
> +
> +		/* TODO: decide what to do with SW counter (bits 55-60) */
> +
> +		desc |= (u64)engine->class << GEN11_ENGINE_CLASS_SHIFT;
> +								/* bits 61-63 */
> +	} else {
> +		GEM_BUG_ON(ctx->hw_id >= BIT(GEN8_CTX_ID_WIDTH));
> +		desc |= (u64)ctx->hw_id << GEN8_CTX_ID_SHIFT;	/* bits 32-52 */
> +	}
>   
>   	ce->lrc_desc = desc;
>   }



More information about the Intel-gfx mailing list