Re: [Intel-gfx] [PATCH 2/2] drm/i915/uapi: Add query for hwconfig table

Matthew Brost
2021-09-09T16:48:18Z

On Thu, Sep 02, 2021 at 05:53:33PM -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.
>
> 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 5e2b909827f4..96989a37453c 100644
> --- a/drivers/gpu/drm/i915/i915_query.c
> +++ b/drivers/gpu/drm/i915/i915_query.c
> @@ -477,12 +477,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 = &gt->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 bde5860b3686..a1281f35b190 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -2499,6 +2499,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
>