drm/msm/gem: Add metadata uapi
Subsystems (5)
v3 cover drm/msm/gem: Add metadata uapi
From: Rob Clark <[email protected]>
Add metadata mechanism to provide a back-channel to communicate image layout information between vk and gl, because EXT_external_objects doesn't support explicit modifiers and "OPTIMAL_TILING_EXT" is not enough information for the importer to deduce the layout.
Rob Clark (2):
drm/msm: Small uabi fixes
drm/msm/gem: Add metadata
drivers/gpu/drm/msm/msm_drv.c | 94 ++++++++++++++++++++++++++++++++++- drivers/gpu/drm/msm/msm_gem.c | 1 + drivers/gpu/drm/msm/msm_gem.h | 4 ++ include/uapi/drm/msm_drm.h | 2 + 4 files changed, 99 insertions(+), 2 deletions(-)
Signature · 1 line
2.41.0
PATCH v3 1/2 drm/msm: Small uabi fixes
From: Rob Clark <[email protected]>
Correct the minor version exposed and error return value for MSM_INFO_GET_NAME.
--- drivers/gpu/drm/msm/msm_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/msm/msm_drv.c +2 -2
@@ -51,7 +51,7 @@* - 1.11.0 - Add wait boost (MSM_WAIT_FENCE_BOOST, MSM_PREP_BOOST) */ #define MSM_VERSION_MAJOR 1 -#define MSM_VERSION_MINOR 10 +#define MSM_VERSION_MINOR 11#define MSM_VERSION_PATCHLEVEL 0static void msm_deinit_vram (struct drm_device *ddev);
@@ -896,7 +896,7 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data,break ;case MSM_INFO_GET_NAME :if (args->value && (args->len <strlen (msm_obj->name))) { - ret = -EINVAL ; + ret = -ETOOSMALL ;break ; } args->len =strlen (msm_obj->name);
Signature · 1 line
2.41.0
PATCH v3 2/2 drm/msm/gem: Add metadata
In reply to Rob ClarkFrom: Rob Clark <[email protected]>
The EXT_external_objects extension is a bit awkward as it doesn't pass explicit modifiers, leaving the importer to guess with incomplete information. In the case of vk (turnip) exporting and gl (freedreno) importing, the "OPTIMAL_TILING_EXT" layout depends on VkImageCreateInfo flags (among other things), which the importer does not know. Which unfortunately leaves us with the need for a metadata back-channel.
The contents of the metadata are defined by userspace. The EXT_external_objects extension is only required to work between compatible versions of gl and vk drivers, as defined by device and driver UUIDs.
v2: add missing metadata kfree
v3: Rework to move copy_from/to_user out from under gem obj lock
to avoid angering lockdep about deadlocks against fs-reclaim
---
Note, I dropped Dmitry's r-b on this version because it was a bit of a re-write of the original patch.
drivers/gpu/drm/msm/msm_drv.c | 92 ++++++++++++++++++++++++++++++++++- drivers/gpu/drm/msm/msm_gem.c | 1 + drivers/gpu/drm/msm/msm_gem.h | 4 ++ include/uapi/drm/msm_drm.h | 2 + 4 files changed, 98 insertions(+), 1 deletion(-)
drivers/gpu/drm/msm/msm_drv.c +91 -1
@@ -49,9 +49,10 @@* - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN * - 1.10.0 - Add MSM_SUBMIT_BO_NO_IMPLICIT * - 1.11.0 - Add wait boost (MSM_WAIT_FENCE_BOOST, MSM_PREP_BOOST) +* - 1.12.0 - Add MSM_INFO_SET_METADATA and MSM_INFO_GET_METADATA */ #define MSM_VERSION_MAJOR 1 -#define MSM_VERSION_MINOR 11 +#define MSM_VERSION_MINOR 12#define MSM_VERSION_PATCHLEVEL 0static void msm_deinit_vram (struct drm_device *ddev);
@@ -822,6 +823,85 @@ static int msm_ioctl_gem_info_set_iova(struct drm_device *dev,return msm_gem_set_iova (obj, ctx->aspace, iova); } +static int msm_ioctl_gem_info_set_metadata (struct drm_gem_object *obj, +__user void *metadata, +u32 metadata_size) +{ +struct msm_gem_object *msm_obj =to_msm_bo (obj); +void *buf; +int ret; + +/* Impose a moderate upper bound on metadata size: */ +if (metadata_size >128 ) { +return -EOVERFLOW ; + } + +/* Use a temporary buf to keep copy_from_user() outside of gem obj lock: */ + buf =memdup_user (metadata, metadata_size); +if (IS_ERR (buf)) +return PTR_ERR (buf); + + ret =msm_gem_lock_interruptible (obj); +if (ret) + goto out; + + msm_obj->metadata = +krealloc (msm_obj->metadata, metadata_size,GFP_KERNEL ); + msm_obj->metadata_size = metadata_size; +memcpy (msm_obj->metadata, buf, metadata_size); + +msm_gem_unlock (obj); + +out: +kfree (buf); + +return ret; +} + +static int msm_ioctl_gem_info_get_metadata (struct drm_gem_object *obj, +__user void *metadata, +u32 *metadata_size) +{ +struct msm_gem_object *msm_obj =to_msm_bo (obj); +void *buf; +int ret, len; + +if (!metadata) { +/* +* Querying the size is inherently racey, but +* EXT_external_objects expects the app to confirm +* via device and driver UUIDs that the exporter and +* importer versions match. All we can do from the +* kernel side is check the length under obj lock +* when userspace tries to retrieve the metadata +*/ + *metadata_size = msm_obj->metadata_size; +return 0 ; + } + + ret =msm_gem_lock_interruptible (obj); +if (ret) +return ret; + +/* Avoid copy_to_user() under gem obj lock: */ + len = msm_obj->metadata_size; + buf =kmemdup (msm_obj->metadata, len,GFP_KERNEL ); + +msm_gem_unlock (obj); + +if (*metadata_size < len) { + ret = -ETOOSMALL ; + }else if (copy_to_user (metadata, buf, len)) { + ret = -EFAULT ; + }else { + *metadata_size = len; + } + +kfree (buf); + +return 0 ; +} +static int msm_ioctl_gem_info (struct drm_device *dev,void *data,struct drm_file *file) {
@@ -844,6 +924,8 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data,break ;case MSM_INFO_SET_NAME :case MSM_INFO_GET_NAME : +case MSM_INFO_SET_METADATA : +case MSM_INFO_GET_METADATA :break ;default :return -EINVAL ;
@@ -906,6 +988,14 @@ static int msm_ioctl_gem_info(struct drm_device *dev, void *data, ret = -EFAULT ; }break ; +case MSM_INFO_SET_METADATA : + ret =msm_ioctl_gem_info_set_metadata ( + obj,u64_to_user_ptr (args->value), args->len); +break ; +case MSM_INFO_GET_METADATA : + ret =msm_ioctl_gem_info_get_metadata ( + obj,u64_to_user_ptr (args->value), &args->len); +break ; }drm_gem_object_put (obj);
drivers/gpu/drm/msm/msm_gem.c +1 -0
@@ -1058,6 +1058,7 @@ static void msm_gem_free_object(struct drm_gem_object *obj)drm_gem_object_release (obj); +kfree (msm_obj->metadata);kfree (msm_obj); }
drivers/gpu/drm/msm/msm_gem.h +4 -0
@@ -109,6 +109,10 @@ struct msm_gem_object {char name[32 ];/* Identifier to print for the debugfs files */ +/* userspace metadata backchannel */ +void *metadata; +u32 metadata_size; +/** * pin_count: Number of times the pages are pinned *
include/uapi/drm/msm_drm.h +2 -0
@@ -139,6 +139,8 @@ struct drm_msm_gem_new {#define MSM_INFO_GET_NAME 0x03/* get debug name, returned by pointer */ #define MSM_INFO_SET_IOVA 0x04/* set the iova, passed by value */ #define MSM_INFO_GET_FLAGS 0x05/* get the MSM_BO_x flags */ +#define MSM_INFO_SET_METADATA 0x06/* set userspace metadata */ +#define MSM_INFO_GET_METADATA 0x07/* get userspace metadata */ struct drm_msm_gem_info {__u32 handle;/* in */
Signature · 1 line
2.41.0