Message ID | 20210610204626.2995262-3-John.C.Harrison@Intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add support for querying hw info that UMDs need | expand |
On Thu, Jun 10, 2021 at 01:46:25PM -0700, John.C.Harrison@Intel.com wrote: > From: Rodrigo Vivi <rodrigo.vivi@intel.com> > > GuC contains a consolidated table with a bunch of information about the > current device. > > Previously, this information was spread and hardcoded to all the components > including GuC, i915 and various UMDs. The goal here is to consolidate > the data into GuC in a way that all interested components can grab the > very latest and synchronized information using a simple query. > > As per most of the other queries, this one can be called twice. > Once with item.length=0 to determine the exact buffer size, then > allocate the user memory and call it again for to retrieve the > table data. For example: > struct drm_i915_query_item item = { > .query_id = DRM_I915_QUERY_HWCONCFIG_TABLE; > }; > query.items_ptr = (int64_t) &item; > query.num_items = 1; > > ioctl(fd, DRM_IOCTL_I915_QUERY, query, sizeof(query)); > > if (item.length <= 0) > return -ENOENT; > > data = malloc(item.length); > item.data_ptr = (int64_t) &data; > ioctl(fd, DRM_IOCTL_I915_QUERY, query, sizeof(query)); > > // Parse the data as appropriate... > > The returned array is a simple and flexible KLV (Key/Length/Value) > formatted table. For example, it could be just: > enum device_attr { > ATTR_SOME_VALUE = 0, > ATTR_SOME_MASK = 1, > }; > > static const u32 hwconfig[] = { > ATTR_SOME_VALUE, > 1, // Value Length in DWords > 8, // Value > > ATTR_SOME_MASK, > 3, > 0x00FFFFFFFF, 0xFFFFFFFF, 0xFF000000, > }; > > The attribute ids are defined in a hardware spec. The current list as > known to the i915 driver can be found in i915/gt/intel_guc_hwconfig_types.h > > Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> > Cc: Kenneth Graunke <kenneth.w.graunke@intel.com> > Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> > Cc: Slawomir Milczarek <slawomir.milczarek@intel.com> > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> > Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> > --- > drivers/gpu/drm/i915/i915_query.c | 23 +++++++++++++++++++++++ > include/uapi/drm/i915_drm.h | 1 + > 2 files changed, 24 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c > index e49da36c62fb..96bd8fb3e895 100644 > --- a/drivers/gpu/drm/i915/i915_query.c > +++ b/drivers/gpu/drm/i915/i915_query.c > @@ -480,12 +480,35 @@ static int query_memregion_info(struct drm_i915_private *i915, > return total_length; > } > > +static int query_hwconfig_table(struct drm_i915_private *i915, > + struct drm_i915_query_item *query_item) > +{ > + struct intel_gt *gt = &i915->gt; > + struct intel_guc_hwconfig *hwconfig = >->uc.guc.hwconfig; > + > + if (!hwconfig->size || !hwconfig->ptr) > + return -ENODEV; > + > + if (query_item->length == 0) > + return hwconfig->size; > + > + if (query_item->length < hwconfig->size) > + return -EINVAL; > + > + if (copy_to_user(u64_to_user_ptr(query_item->data_ptr), > + hwconfig->ptr, hwconfig->size)) > + return -EFAULT; > + > + return hwconfig->size; > +} > + > static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv, > struct drm_i915_query_item *query_item) = { > query_topology_info, > query_engine_info, > query_perf_config, > query_memregion_info, > + query_hwconfig_table, > }; > > int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file) > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h > index c2c7759b7d2e..87d369cae22a 100644 > --- a/include/uapi/drm/i915_drm.h > +++ b/include/uapi/drm/i915_drm.h > @@ -2233,6 +2233,7 @@ struct drm_i915_query_item { > #define DRM_I915_QUERY_ENGINE_INFO 2 > #define DRM_I915_QUERY_PERF_CONFIG 3 > #define DRM_I915_QUERY_MEMORY_REGIONS 4 > +#define DRM_I915_QUERY_HWCONFIG_TABLE 5 > /* Must be kept compact -- no holes and well documented */ > > /** > -- > 2.25.1 >
On 10.06.2021 22:46, John.C.Harrison@Intel.com wrote: > From: Rodrigo Vivi <rodrigo.vivi@intel.com> > > GuC contains a consolidated table with a bunch of information about the > current device. > > Previously, this information was spread and hardcoded to all the components > including GuC, i915 and various UMDs. The goal here is to consolidate > the data into GuC in a way that all interested components can grab the > very latest and synchronized information using a simple query. > > As per most of the other queries, this one can be called twice. > Once with item.length=0 to determine the exact buffer size, then > allocate the user memory and call it again for to retrieve the > table data. For example: > struct drm_i915_query_item item = { > .query_id = DRM_I915_QUERY_HWCONCFIG_TABLE; > }; > query.items_ptr = (int64_t) &item; > query.num_items = 1; > > ioctl(fd, DRM_IOCTL_I915_QUERY, query, sizeof(query)); > > if (item.length <= 0) > return -ENOENT; > > data = malloc(item.length); > item.data_ptr = (int64_t) &data; > ioctl(fd, DRM_IOCTL_I915_QUERY, query, sizeof(query)); > > // Parse the data as appropriate... > > The returned array is a simple and flexible KLV (Key/Length/Value) > formatted table. For example, it could be just: > enum device_attr { > ATTR_SOME_VALUE = 0, > ATTR_SOME_MASK = 1, > }; > > static const u32 hwconfig[] = { > ATTR_SOME_VALUE, > 1, // Value Length in DWords > 8, // Value > > ATTR_SOME_MASK, > 3, > 0x00FFFFFFFF, 0xFFFFFFFF, 0xFF000000, > }; same example was already added to code in previous patch maybe just refer to that documentation ? > > The attribute ids are defined in a hardware spec. The current list as > known to the i915 driver can be found in i915/gt/intel_guc_hwconfig_types.h previous patch introduced i915/gt/intel_hwconfig_types.h also, i915 seems to be not using any/many of them directly, so it could happen that GuC will return new/updated klvs, so shouldn't we make this klv list more external and maybe even define as uabi header? > > Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> > Cc: Kenneth Graunke <kenneth.w.graunke@intel.com> > Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> > Cc: Slawomir Milczarek <slawomir.milczarek@intel.com> > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> > Signed-off-by: John Harrison <John.C.Harrison@Intel.com> > --- > drivers/gpu/drm/i915/i915_query.c | 23 +++++++++++++++++++++++ > include/uapi/drm/i915_drm.h | 1 + > 2 files changed, 24 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c > index e49da36c62fb..96bd8fb3e895 100644 > --- a/drivers/gpu/drm/i915/i915_query.c > +++ b/drivers/gpu/drm/i915/i915_query.c > @@ -480,12 +480,35 @@ static int query_memregion_info(struct drm_i915_private *i915, > return total_length; > } > > +static int query_hwconfig_table(struct drm_i915_private *i915, > + struct drm_i915_query_item *query_item) > +{ > + struct intel_gt *gt = &i915->gt; > + struct intel_guc_hwconfig *hwconfig = >->uc.guc.hwconfig; > + > + if (!hwconfig->size || !hwconfig->ptr) > + return -ENODEV; shouldn't we also have: if (query_item->flags != 0) return -EINVAL; > + > + if (query_item->length == 0) > + return hwconfig->size; > + > + if (query_item->length < hwconfig->size) > + return -EINVAL; > + > + if (copy_to_user(u64_to_user_ptr(query_item->data_ptr), > + hwconfig->ptr, hwconfig->size)) > + return -EFAULT; > + > + return hwconfig->size; > +} > + > static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv, > struct drm_i915_query_item *query_item) = { > query_topology_info, > query_engine_info, > query_perf_config, > query_memregion_info, > + query_hwconfig_table, > }; > > int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file) > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h > index c2c7759b7d2e..87d369cae22a 100644 > --- a/include/uapi/drm/i915_drm.h > +++ b/include/uapi/drm/i915_drm.h > @@ -2233,6 +2233,7 @@ struct drm_i915_query_item { > #define DRM_I915_QUERY_ENGINE_INFO 2 > #define DRM_I915_QUERY_PERF_CONFIG 3 > #define DRM_I915_QUERY_MEMORY_REGIONS 4 > +#define DRM_I915_QUERY_HWCONFIG_TABLE 5 hmm, not sure is this single line satisfies below "well documented" requirement ;) > /* Must be kept compact -- no holes and well documented */ > > /** >
diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c index e49da36c62fb..96bd8fb3e895 100644 --- a/drivers/gpu/drm/i915/i915_query.c +++ b/drivers/gpu/drm/i915/i915_query.c @@ -480,12 +480,35 @@ static int query_memregion_info(struct drm_i915_private *i915, return total_length; } +static int query_hwconfig_table(struct drm_i915_private *i915, + struct drm_i915_query_item *query_item) +{ + struct intel_gt *gt = &i915->gt; + struct intel_guc_hwconfig *hwconfig = >->uc.guc.hwconfig; + + if (!hwconfig->size || !hwconfig->ptr) + return -ENODEV; + + if (query_item->length == 0) + return hwconfig->size; + + if (query_item->length < hwconfig->size) + return -EINVAL; + + if (copy_to_user(u64_to_user_ptr(query_item->data_ptr), + hwconfig->ptr, hwconfig->size)) + return -EFAULT; + + return hwconfig->size; +} + static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv, struct drm_i915_query_item *query_item) = { query_topology_info, query_engine_info, query_perf_config, query_memregion_info, + query_hwconfig_table, }; int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file) diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index c2c7759b7d2e..87d369cae22a 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -2233,6 +2233,7 @@ struct drm_i915_query_item { #define DRM_I915_QUERY_ENGINE_INFO 2 #define DRM_I915_QUERY_PERF_CONFIG 3 #define DRM_I915_QUERY_MEMORY_REGIONS 4 +#define DRM_I915_QUERY_HWCONFIG_TABLE 5 /* Must be kept compact -- no holes and well documented */ /**