[PATCH v6] drm/ioctl: Add a ioctl to set and get a label on GEM objects
Eric Anholt
eric at anholt.net
Thu May 28 18:45:24 UTC 2020
On Thu, May 28, 2020 at 10:06 AM Rohan Garg <rohan.garg at collabora.com> wrote:
>
> DRM_IOCTL_HANDLE_SET_LABEL lets you label buffers associated
> with a handle, making it easier to debug issues in userspace
> applications.
>
> DRM_IOCTL_HANDLE_GET_LABEL lets you read the label associated
> with a buffer.
>
> Changes in v2:
> - Hoist the IOCTL up into the drm_driver framework
>
> Changes in v3:
> - Introduce a drm_gem_set_label for drivers to use internally
> in order to label a GEM object
> - Hoist string copying up into the IOCTL
> - Fix documentation
> - Move actual gem labeling into drm_gem_adopt_label
>
> Changes in v4:
> - Refactor IOCTL call to only perform string duplication and move
> all gem lookup logic into GEM specific call
>
> Changes in v5:
> - Fix issues pointed out by kbuild test robot
> - Cleanup minor issues around kfree and out/err labels
> - Fixed API documentation issues
> - Rename to DRM_IOCTL_HANDLE_SET_LABEL
> - Introduce a DRM_IOCTL_HANDLE_GET_LABEL to read labels
> - Added some documentation for consumers of this IOCTL
> - Ensure that label's cannot be longer than PAGE_SIZE
> - Set a default label value
> - Drop useless warning
> - Properly return length of label to userspace even if
> userspace did not allocate memory for label.
>
> Changes in v6:
> - Wrap code to make better use of 80 char limit
> - Drop redundant copies of the label
> - Protect concurrent access to labels
> - Improved documentation
> - Refactor setter/getter ioctl's to be static
> - Return EINVAL when label length > PAGE_SIZE
> - Simplify code by calling the default GEM label'ing
> function for all drivers using GEM
> - Do not error out when fetching empty labels
> - Refactor flags to the u32 type and add documentation
> - Refactor ioctls to use correct DRM_IOCTL{R,W,WR} macros
> - Return length of copied label to userspace
>
> Signed-off-by: Rohan Garg <rohan.garg at collabora.com>
I don't think we should land this until it actually does something
with the label, that feels out of the spirit of our uapi merge rules.
I would suggest looking at dma_buf_set_name(), which would produce
useful output in debugfs's /dma_buf/buf_info. But also presumably you
have something in panfrost using this?
> +int drm_gem_get_label(struct drm_device *dev, struct drm_file *file_priv,
> + struct drm_handle_label *args)
> +{
> + struct drm_gem_object *gem_obj;
> + int len, ret;
> +
> + gem_obj = drm_gem_object_lookup(file_priv, args->handle);
> + if (!gem_obj) {
> + DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
> + return -ENOENT;
> + }
> +
> + if (!gem_obj->label) {
> + args->label = NULL;
> + args->len = 0;
> + return 0;
> + }
> +
> + mutex_lock(&gem_obj->bo_lock);
> + len = strlen(gem_obj->label);
> + ret = copy_to_user(u64_to_user_ptr(args->label), gem_obj->label,
> + min(args->len, len));
> + mutex_unlock(&gem_obj->bo_lock);
> + args->len = len;
> + drm_gem_object_put(gem_obj);
> + return ret;
> +}
I think the !gem_obj->label code path also needs to be under the lock,
otherwise you could be racing to copy_to_user from a NULL pointer,
right?
> #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> index bb924cddc09c..6fcb7b9ff322 100644
> --- a/include/drm/drm_drv.h
> +++ b/include/drm/drm_drv.h
> @@ -540,6 +540,36 @@ struct drm_driver {
> struct drm_device *dev,
> uint32_t handle);
>
> + /**
> + * @set_label:
> + *
> + * Label a buffer object
> + *
> + * Called by the user via ioctl.
> + *
> + * Returns:
> + *
> + * Length of label on success, negative errno on failure.
> + */
> + int (*set_label)(struct drm_device *dev,
> + struct drm_file *file_priv,
> + struct drm_handle_label *args);
> +
> + /**
> + * @get_label:
> + *
> + * Read the label of a buffer object.
> + *
> + * Called by the user via ioctl.
> + *
> + * Returns:
> + *
> + * Length of label on success, negative errno on failiure.
> + */
> + char *(*get_label)(struct drm_device *dev,
> + struct drm_file *file_priv,
> + struct drm_handle_label *args);
> +
I think the documentation should note that these are optional.
More information about the dri-devel
mailing list