Message ID | 20180302161501.28594-3-mika.kuoppala@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 3/2/2018 8:14 AM, Mika Kuoppala wrote: > From: Daniele Ceraolo Spurio <daniele.ceraolospurio@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@intel.com> > Cc: Chris Wilson <chris@chris-wilson.co.uk> > Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com> > Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> v5 still looks good to me: Reviewed-by: Oscar Mateo <oscar.mateo@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; > }
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; }