Message ID | 20190627205633.1143-36-matthew.auld@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Introduce memory region concept (including device local memory) | expand |
On 27/06/2019 21:56, Matthew Auld wrote: > From: Abdiel Janulgue <abdiel.janulgue@linux.intel.com> > > Returns the available memory region areas supported by the HW. > > Signed-off-by: Abdiel Janulgue <abdiel.janulgue@linux.intel.com> > Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> > --- > drivers/gpu/drm/i915/i915_query.c | 57 +++++++++++++++++++++++++++++++ > include/uapi/drm/i915_drm.h | 39 +++++++++++++++++++++ > 2 files changed, 96 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c > index 7b7016171057..21c4c2592d6c 100644 > --- a/drivers/gpu/drm/i915/i915_query.c > +++ b/drivers/gpu/drm/i915/i915_query.c > @@ -143,10 +143,67 @@ query_engine_info(struct drm_i915_private *i915, > return len; > } > > +static int query_memregion_info(struct drm_i915_private *dev_priv, > + struct drm_i915_query_item *query_item) > +{ > + struct drm_i915_query_memory_region_info __user *query_ptr = > + u64_to_user_ptr(query_item->data_ptr); > + struct drm_i915_memory_region_info __user *info_ptr = > + &query_ptr->regions[0]; > + struct drm_i915_memory_region_info info = { }; > + struct drm_i915_query_memory_region_info query; > + u32 total_length; > + int ret, i; > + > + if (query_item->flags != 0) > + return -EINVAL; > + > + total_length = sizeof(struct drm_i915_query_memory_region_info); > + for (i = 0; i < ARRAY_SIZE(dev_priv->regions); ++i) { > + struct intel_memory_region *region = dev_priv->regions[i]; > + > + if (!region) > + continue; > + > + total_length += sizeof(struct drm_i915_memory_region_info); > + } > + > + ret = copy_query_item(&query, sizeof(query), total_length, > + query_item); > + if (ret != 0) > + return ret; > + > + if (query.num_regions || query.rsvd[0] || query.rsvd[1] || > + query.rsvd[2]) > + return -EINVAL; > + > + for (i = 0; i < ARRAY_SIZE(dev_priv->regions); ++i) { > + struct intel_memory_region *region = dev_priv->regions[i]; > + > + if (!region) > + continue; > + > + info.id = region->id; > + info.size = resource_size(®ion->region); > + > + if (__copy_to_user(info_ptr, &info, sizeof(info))) > + return -EFAULT; > + > + query.num_regions++; > + info_ptr++; > + } > + > + if (__copy_to_user(query_ptr, &query, sizeof(query))) > + return -EFAULT; > + > + return total_length; > +} > + > 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_memregion_info, > }; > > 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 5cf976e7608a..9b77d8af9877 100644 > --- a/include/uapi/drm/i915_drm.h > +++ b/include/uapi/drm/i915_drm.h > @@ -2041,6 +2041,7 @@ struct drm_i915_query_item { > __u64 query_id; > #define DRM_I915_QUERY_TOPOLOGY_INFO 1 > #define DRM_I915_QUERY_ENGINE_INFO 2 > +#define DRM_I915_QUERY_MEMREGION_INFO 3 > /* Must be kept compact -- no holes and well documented */ > > /* > @@ -2180,6 +2181,44 @@ struct drm_i915_query_engine_info { > struct drm_i915_engine_info engines[]; > }; > > +struct drm_i915_memory_region_info { > + > + /** Base type of a region > + */ > +#define I915_SYSTEM_MEMORY 0 > +#define I915_DEVICE_MEMORY 1 > + > + /** The region id is encoded in a layout which makes it possible to > + * retrieve the following information: > + * > + * Base type: log2(ID >> 16) > + * Instance: log2(ID & 0xffff) > + */ > + __u32 id; Should we consider, for simplicity and similarity with the engine interface, go for something like: struct i915_memory_type_instance { __u16 type; __u16 instance; }; struct drm_i915_memory_region_info { struct i915_memory_type_instance region; ... }; ? > + > + /** Reserved field. MBZ */ > + __u32 rsvd0; > + > + /** Unused for now. MBZ */ > + __u64 flags; > + > + __u64 size; > + > + /** Reserved fields must be cleared to zero. */ > + __u64 rsvd1[4]; > +}; > + > +struct drm_i915_query_memory_region_info { > + > + /** Number of struct drm_i915_memory_region_info structs */ > + __u32 num_regions; > + > + /** MBZ */ > + __u32 rsvd[3]; It's not that important, just a note that given some recent discussion on the engine query front, I wished I had more rsvd there. So maybe bump this up just to be extra safe. > + > + struct drm_i915_memory_region_info regions[]; > +}; > + > #if defined(__cplusplus) > } > #endif > Regards, Tvrtko
diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c index 7b7016171057..21c4c2592d6c 100644 --- a/drivers/gpu/drm/i915/i915_query.c +++ b/drivers/gpu/drm/i915/i915_query.c @@ -143,10 +143,67 @@ query_engine_info(struct drm_i915_private *i915, return len; } +static int query_memregion_info(struct drm_i915_private *dev_priv, + struct drm_i915_query_item *query_item) +{ + struct drm_i915_query_memory_region_info __user *query_ptr = + u64_to_user_ptr(query_item->data_ptr); + struct drm_i915_memory_region_info __user *info_ptr = + &query_ptr->regions[0]; + struct drm_i915_memory_region_info info = { }; + struct drm_i915_query_memory_region_info query; + u32 total_length; + int ret, i; + + if (query_item->flags != 0) + return -EINVAL; + + total_length = sizeof(struct drm_i915_query_memory_region_info); + for (i = 0; i < ARRAY_SIZE(dev_priv->regions); ++i) { + struct intel_memory_region *region = dev_priv->regions[i]; + + if (!region) + continue; + + total_length += sizeof(struct drm_i915_memory_region_info); + } + + ret = copy_query_item(&query, sizeof(query), total_length, + query_item); + if (ret != 0) + return ret; + + if (query.num_regions || query.rsvd[0] || query.rsvd[1] || + query.rsvd[2]) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(dev_priv->regions); ++i) { + struct intel_memory_region *region = dev_priv->regions[i]; + + if (!region) + continue; + + info.id = region->id; + info.size = resource_size(®ion->region); + + if (__copy_to_user(info_ptr, &info, sizeof(info))) + return -EFAULT; + + query.num_regions++; + info_ptr++; + } + + if (__copy_to_user(query_ptr, &query, sizeof(query))) + return -EFAULT; + + return total_length; +} + 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_memregion_info, }; 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 5cf976e7608a..9b77d8af9877 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -2041,6 +2041,7 @@ struct drm_i915_query_item { __u64 query_id; #define DRM_I915_QUERY_TOPOLOGY_INFO 1 #define DRM_I915_QUERY_ENGINE_INFO 2 +#define DRM_I915_QUERY_MEMREGION_INFO 3 /* Must be kept compact -- no holes and well documented */ /* @@ -2180,6 +2181,44 @@ struct drm_i915_query_engine_info { struct drm_i915_engine_info engines[]; }; +struct drm_i915_memory_region_info { + + /** Base type of a region + */ +#define I915_SYSTEM_MEMORY 0 +#define I915_DEVICE_MEMORY 1 + + /** The region id is encoded in a layout which makes it possible to + * retrieve the following information: + * + * Base type: log2(ID >> 16) + * Instance: log2(ID & 0xffff) + */ + __u32 id; + + /** Reserved field. MBZ */ + __u32 rsvd0; + + /** Unused for now. MBZ */ + __u64 flags; + + __u64 size; + + /** Reserved fields must be cleared to zero. */ + __u64 rsvd1[4]; +}; + +struct drm_i915_query_memory_region_info { + + /** Number of struct drm_i915_memory_region_info structs */ + __u32 num_regions; + + /** MBZ */ + __u32 rsvd[3]; + + struct drm_i915_memory_region_info regions[]; +}; + #if defined(__cplusplus) } #endif