diff mbox series

[v4] drm/ioctl: Add a ioctl to label GEM objects

Message ID 20191011143009.17503-1-rohan.garg@collabora.com (mailing list archive)
State New, archived
Headers show
Series [v4] drm/ioctl: Add a ioctl to label GEM objects | expand

Commit Message

Rohan Garg Oct. 11, 2019, 2:30 p.m. UTC
DRM_IOCTL_DUMB_SET_LABEL lets you label GEM objects, making it
easier to debug issues in userspace applications.

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

Signed-off-by: Rohan Garg <rohan.garg@collabora.com>
---
 drivers/gpu/drm/drm_gem.c      | 70 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_internal.h |  8 ++++
 drivers/gpu/drm/drm_ioctl.c    |  1 +
 include/drm/drm_drv.h          | 16 ++++++++
 include/drm/drm_gem.h          |  7 ++++
 include/uapi/drm/drm.h         | 20 ++++++++++
 6 files changed, 122 insertions(+)

Comments

Daniel Stone Oct. 11, 2019, 5:09 p.m. UTC | #1
Hi Rohan,

On Fri, 11 Oct 2019 at 15:30, Rohan Garg <rohan.garg@collabora.com> wrote:
> DRM_IOCTL_DUMB_SET_LABEL lets you label GEM objects, making it
> easier to debug issues in userspace applications.

I'm not sure if this was pointed out already, but dumb buffers != GEM
buffers. GEM buffers _can_ be dumb, but might not be.

Could you please rename to GEM_SET_LABEL?

Cheers,
Daniel
Boris Brezillon Oct. 11, 2019, 5:31 p.m. UTC | #2
Hello Rohan,

On Fri, 11 Oct 2019 16:30:09 +0200
Rohan Garg <rohan.garg@collabora.com> wrote:

> DRM_IOCTL_DUMB_SET_LABEL lets you label GEM objects, making it
> easier to debug issues in userspace applications.
> 
> 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
> 
> Signed-off-by: Rohan Garg <rohan.garg@collabora.com>
> ---
>  drivers/gpu/drm/drm_gem.c      | 70 ++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_internal.h |  8 ++++
>  drivers/gpu/drm/drm_ioctl.c    |  1 +
>  include/drm/drm_drv.h          | 16 ++++++++
>  include/drm/drm_gem.h          |  7 ++++
>  include/uapi/drm/drm.h         | 20 ++++++++++
>  6 files changed, 122 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index 6854f5867d51..0fa4609b2817 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -941,6 +941,71 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
>  	idr_destroy(&file_private->object_idr);
>  }
>  
> +int drm_dumb_set_label_ioctl(struct drm_device *dev,

Why dumb? Not sure what a smart set_label_ioctl() function would
do differently :-).

Oh, and if this function can be used to label TTM BOs it should be moved
somewhere else (drm_ioctl.c ?).

> +				void *data, struct drm_file *file_priv)

Indentation is broken here.

> +{
> +	char *label;
> +	struct drm_dumb_set_label_object *args = data;
> +	int ret = 0;
> +
> +	if (!args->len || !args->name)

Hm, I thought args->len == 0 was a valid case and meant "free the
existing label". Has it changed. The case that's not allowed is
args->len && !args->name.
		

> +		return -EINVAL;
> +
> +	if (!dev->driver->label)
> +		return -EOPNOTSUPP;
> +
> +	label = strndup_user(u64_to_user_ptr(args->name), args->len);
> +

Remove this blank line.

> +	if (IS_ERR(label)) {
> +		ret = PTR_ERR(label);
> +		goto err;
> +	}
> +
> +	ret = dev->driver->label(dev, file_priv, args->handle, label);
> +
> +err:

I would s/err/out/ as this is not an error-only path.

> +	kfree(label);
> +	return ret;
> +}
> +
> +int drm_gem_set_label(struct drm_device *dev,
> +		       struct drm_file *file_priv,
> +			   uint32_t handle,
> +			   const char *label)
> +{
> +	struct drm_gem_object *gem_obj;
> +	int ret = 0;
> +
> +	gem_obj = drm_gem_object_lookup(file_priv, handle);
> +	if (!gem_obj) {
> +		DRM_DEBUG("Failed to look up GEM BO %d\n", handle);
> +		ret = -ENOENT;
> +		goto err;
> +	}
> +	drm_gem_adopt_label(gem_obj, label);
> +
> +err:

Ditto: s/err/out/

> +	drm_gem_object_put_unlocked(gem_obj);
> +	return ret;
> +}
> +EXPORT_SYMBOL(drm_gem_set_label);
> +
> +void drm_gem_adopt_label(struct drm_gem_object *gem_obj, const char *label)
> +{
> +	char *adopted_label = NULL;
> +
> +	if (label)
> +		adopted_label = kstrdup(label, GFP_KERNEL);

Add

		WARN_ON(adopted_label);

> +
> +	if (gem_obj->label) {
> +		kfree(gem_obj->label);
> +		gem_obj->label = NULL;

This assignment is useless since gem_obj->label is assigned below.

> +	}
> +
> +	gem_obj->label = adopted_label;
> +}
> +EXPORT_SYMBOL(drm_gem_adopt_label);
> +
>  /**
>   * drm_gem_object_release - release GEM buffer object resources
>   * @obj: GEM buffer object
> @@ -958,6 +1023,11 @@ drm_gem_object_release(struct drm_gem_object *obj)
>  
>  	dma_resv_fini(&obj->_resv);
>  	drm_gem_free_mmap_offset(obj);
> +
> +	if (obj->label) {
> +		kfree(obj->label);
> +		obj->label = NULL;
> +	}

You can call kfree(obj->label) directly (kfree() checks for NULL vals),
and no need to reset obj->label (obj should be free when the function
returns).

>  }
>  EXPORT_SYMBOL(drm_gem_object_release);
>  
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index 51a2055c8f18..cbc3f7b7fb9b 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -137,6 +137,14 @@ int drm_gem_pin(struct drm_gem_object *obj);
>  void drm_gem_unpin(struct drm_gem_object *obj);
>  void *drm_gem_vmap(struct drm_gem_object *obj);
>  void drm_gem_vunmap(struct drm_gem_object *obj, void *vaddr);
> +int drm_dumb_set_label_ioctl(struct drm_device *dev,
> +			void *data,
> +			struct drm_file *file_priv);
> +int drm_gem_set_label(struct drm_device *dev,
> +			struct drm_file *file_priv,
> +			uint32_t handle,
> +			const char *label);
> +void drm_gem_adopt_label(struct drm_gem_object *gem_obj, const char *label);
>  
>  /* drm_debugfs.c drm_debugfs_crc.c */
>  #if defined(CONFIG_DEBUG_FS)
> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> index fcd728d7cf72..f34e1571d70f 100644
> --- a/drivers/gpu/drm/drm_ioctl.c
> +++ b/drivers/gpu/drm/drm_ioctl.c
> @@ -714,6 +714,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER),
>  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER),
>  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER),
> +	DRM_IOCTL_DEF(DRM_IOCTL_DUMB_SET_LABEL, drm_dumb_set_label_ioctl, DRM_RENDER_ALLOW),
>  };
>  
>  #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> index cf13470810a5..501a3924354a 100644
> --- a/include/drm/drm_drv.h
> +++ b/include/drm/drm_drv.h
> @@ -715,6 +715,22 @@ struct drm_driver {
>  			    struct drm_device *dev,
>  			    uint32_t handle);
>  
> +	/**
> +	 * @label:
> +	 *
> +	 * This label's a buffer object.
> +	 *
> +	 * Called by the user via ioctl.
> +	 *
> +	 * Returns:
> +	 *
> +	 * Zero on success, negative errno on failure.
> +	 */
> +	int (*label)(struct drm_device *dev,

Maybe label_bo or set_bo_label instead of just label, just to make it
clear that the label is applied to a buffer object.

> +				struct drm_file *file_priv,
> +				uint32_t handle,
> +				char *label);

Indentation issue here as well.

> +
>  	/**
>  	 * @gem_vm_ops: Driver private ops for this object
>  	 *
> diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
> index 6aaba14f5972..f801c054e972 100644
> --- a/include/drm/drm_gem.h
> +++ b/include/drm/drm_gem.h
> @@ -237,6 +237,13 @@ struct drm_gem_object {
>  	 */
>  	int name;
>  
> +	/**
> +	 * @label:
> +	 *
> +	 * Label for this object, should be a human readable string.
> +	 */
> +	char *label;
> +
>  	/**
>  	 * @dma_buf:
>  	 *
> diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
> index 8a5b2f8f8eb9..309c3c091385 100644
> --- a/include/uapi/drm/drm.h
> +++ b/include/uapi/drm/drm.h
> @@ -626,6 +626,25 @@ struct drm_gem_open {
>  	__u64 size;
>  };
>  
> +/** struct drm_dumb_set_label_object - ioctl argument for labelling BOs.
> + *
> + * This label's a BO with a userspace label
> + *
> + */
> +struct drm_dumb_set_label_object {
> +	/** Handle for the object being labelled. */
> +	__u32 handle;
> +
> +	/** Label and label length.
> +	 *  len includes the trailing NUL.
> +	 */

Nitpick: the comment fits on a single line.

	/** Label and label length (len includes the trailing NUL). */

> +	__u32 len;
> +	__u64 name;
> +
> +	/** Flags */
> +	int flags;
> +};
> +
>  #define DRM_CAP_DUMB_BUFFER		0x1
>  #define DRM_CAP_VBLANK_HIGH_CRTC	0x2
>  #define DRM_CAP_DUMB_PREFERRED_DEPTH	0x3
> @@ -946,6 +965,7 @@ extern "C" {
>  #define DRM_IOCTL_SYNCOBJ_QUERY		DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
>  #define DRM_IOCTL_SYNCOBJ_TRANSFER	DRM_IOWR(0xCC, struct drm_syncobj_transfer)
>  #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL	DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
> +#define DRM_IOCTL_DUMB_SET_LABEL      DRM_IOWR(0xCE, struct drm_dumb_set_label_object)

Maybe s/DRM_IOCTL_DUMB_SET_LABEL/DRM_IOCTL_SET_BO_LABEL/ and
s/drm_dumb_set_label_object/drm_set_bo_label/

>  
>  /**
>   * Device specific ioctls should only be in their respective headers
Thomas Zimmermann Oct. 11, 2019, 5:55 p.m. UTC | #3
Hi

Am 11.10.19 um 19:09 schrieb Daniel Stone:
> Hi Rohan,
> 
> On Fri, 11 Oct 2019 at 15:30, Rohan Garg <rohan.garg@collabora.com> wrote:
>> DRM_IOCTL_DUMB_SET_LABEL lets you label GEM objects, making it
>> easier to debug issues in userspace applications.
> 
> I'm not sure if this was pointed out already, but dumb buffers != GEM
> buffers. GEM buffers _can_ be dumb, but might not be.
> 
> Could you please rename to GEM_SET_LABEL?

This change to build upon dumb buffers was suggested by me, as dumb 
buffers is the closes thing there is to a buffer management interface. 
Drivers with 'smart buffers' would have to add their own ioctl interfaces.

What I really miss here is a userspace application that uses this 
functionality. It would be much easier to discuss if there was an actual 
example.

Best regards

> Cheers,
> Daniel
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
Dan Carpenter Oct. 12, 2019, 1:35 p.m. UTC | #4
Hi Rohan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[cannot apply to v5.4-rc2 next-20191011]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Rohan-Garg/drm-ioctl-Add-a-ioctl-to-label-GEM-objects/20191012-062955

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

smatch warnings:
drivers/gpu/drm/drm_gem.c:967 drm_dumb_set_label_ioctl() error: 'label' dereferencing possible ERR_PTR()

# https://github.com/0day-ci/linux/commit/0f0cd7ef9f3b1623ab982f12dc748998f31e10b4
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 0f0cd7ef9f3b1623ab982f12dc748998f31e10b4
vim +/label +967 drivers/gpu/drm/drm_gem.c

673a394b1e3b69 Eric Anholt 2008-07-30  943  
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  944  int drm_dumb_set_label_ioctl(struct drm_device *dev,
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  945  				void *data, struct drm_file *file_priv)
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  946  {
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  947  	char *label;
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  948  	struct drm_dumb_set_label_object *args = data;
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  949  	int ret = 0;
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  950  
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  951  	if (!args->len || !args->name)
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  952  		return -EINVAL;
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  953  
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  954  	if (!dev->driver->label)
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  955  		return -EOPNOTSUPP;
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  956  
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  957  	label = strndup_user(u64_to_user_ptr(args->name), args->len);
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  958  
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  959  	if (IS_ERR(label)) {
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  960  		ret = PTR_ERR(label);
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  961  		goto err;
                                                        ^^^^^^^^
Just return PTR_ERR(label);


0f0cd7ef9f3b16 Rohan Garg  2019-10-11  962  	}
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  963  
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  964  	ret = dev->driver->label(dev, file_priv, args->handle, label);
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  965  
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  966  err:
0f0cd7ef9f3b16 Rohan Garg  2019-10-11 @967  	kfree(label);
                                                ^^^^^^^^^^^^
This will Oops.

0f0cd7ef9f3b16 Rohan Garg  2019-10-11  968  	return ret;
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  969  }
0f0cd7ef9f3b16 Rohan Garg  2019-10-11  970  

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Daniel Vetter Oct. 14, 2019, 8:58 a.m. UTC | #5
On Fri, Oct 11, 2019 at 07:55:36PM +0200, Thomas Zimmermann wrote:
> Hi
> 
> Am 11.10.19 um 19:09 schrieb Daniel Stone:
> > Hi Rohan,
> > 
> > On Fri, 11 Oct 2019 at 15:30, Rohan Garg <rohan.garg@collabora.com> wrote:
> > > DRM_IOCTL_DUMB_SET_LABEL lets you label GEM objects, making it
> > > easier to debug issues in userspace applications.
> > 
> > I'm not sure if this was pointed out already, but dumb buffers != GEM
> > buffers. GEM buffers _can_ be dumb, but might not be.
> > 
> > Could you please rename to GEM_SET_LABEL?
> 
> This change to build upon dumb buffers was suggested by me, as dumb buffers
> is the closes thing there is to a buffer management interface. Drivers with
> 'smart buffers' would have to add their own ioctl interfaces.

We already have some IOCTLs that apply to gem buffers, not just dumb
buffers, so GEM_SET_LABEL seems a lot more reasonable to me, too.

> What I really miss here is a userspace application that uses this
> functionality. It would be much easier to discuss if there was an actual
> example.

+1.

Cheers, Daniel
Daniel Vetter Oct. 14, 2019, 8:59 a.m. UTC | #6
On Fri, Oct 11, 2019 at 04:30:09PM +0200, Rohan Garg wrote:
> DRM_IOCTL_DUMB_SET_LABEL lets you label GEM objects, making it
> easier to debug issues in userspace applications.
> 
> 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

I still think we should just make this GEM-only and avoid the indirection.
Except if your userspace actually does run on vmwgfx, and you absolutely
want/need it to run there. Everything else is GEM-only.
-Daniel

> 
> Signed-off-by: Rohan Garg <rohan.garg@collabora.com>
> ---
>  drivers/gpu/drm/drm_gem.c      | 70 ++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/drm_internal.h |  8 ++++
>  drivers/gpu/drm/drm_ioctl.c    |  1 +
>  include/drm/drm_drv.h          | 16 ++++++++
>  include/drm/drm_gem.h          |  7 ++++
>  include/uapi/drm/drm.h         | 20 ++++++++++
>  6 files changed, 122 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index 6854f5867d51..0fa4609b2817 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -941,6 +941,71 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
>  	idr_destroy(&file_private->object_idr);
>  }
>  
> +int drm_dumb_set_label_ioctl(struct drm_device *dev,
> +				void *data, struct drm_file *file_priv)
> +{
> +	char *label;
> +	struct drm_dumb_set_label_object *args = data;
> +	int ret = 0;
> +
> +	if (!args->len || !args->name)
> +		return -EINVAL;
> +
> +	if (!dev->driver->label)
> +		return -EOPNOTSUPP;
> +
> +	label = strndup_user(u64_to_user_ptr(args->name), args->len);
> +
> +	if (IS_ERR(label)) {
> +		ret = PTR_ERR(label);
> +		goto err;
> +	}
> +
> +	ret = dev->driver->label(dev, file_priv, args->handle, label);
> +
> +err:
> +	kfree(label);
> +	return ret;
> +}
> +
> +int drm_gem_set_label(struct drm_device *dev,
> +		       struct drm_file *file_priv,
> +			   uint32_t handle,
> +			   const char *label)
> +{
> +	struct drm_gem_object *gem_obj;
> +	int ret = 0;
> +
> +	gem_obj = drm_gem_object_lookup(file_priv, handle);
> +	if (!gem_obj) {
> +		DRM_DEBUG("Failed to look up GEM BO %d\n", handle);
> +		ret = -ENOENT;
> +		goto err;
> +	}
> +	drm_gem_adopt_label(gem_obj, label);
> +
> +err:
> +	drm_gem_object_put_unlocked(gem_obj);
> +	return ret;
> +}
> +EXPORT_SYMBOL(drm_gem_set_label);
> +
> +void drm_gem_adopt_label(struct drm_gem_object *gem_obj, const char *label)
> +{
> +	char *adopted_label = NULL;
> +
> +	if (label)
> +		adopted_label = kstrdup(label, GFP_KERNEL);
> +
> +	if (gem_obj->label) {
> +		kfree(gem_obj->label);
> +		gem_obj->label = NULL;
> +	}
> +
> +	gem_obj->label = adopted_label;
> +}
> +EXPORT_SYMBOL(drm_gem_adopt_label);
> +
>  /**
>   * drm_gem_object_release - release GEM buffer object resources
>   * @obj: GEM buffer object
> @@ -958,6 +1023,11 @@ drm_gem_object_release(struct drm_gem_object *obj)
>  
>  	dma_resv_fini(&obj->_resv);
>  	drm_gem_free_mmap_offset(obj);
> +
> +	if (obj->label) {
> +		kfree(obj->label);
> +		obj->label = NULL;
> +	}
>  }
>  EXPORT_SYMBOL(drm_gem_object_release);
>  
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index 51a2055c8f18..cbc3f7b7fb9b 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -137,6 +137,14 @@ int drm_gem_pin(struct drm_gem_object *obj);
>  void drm_gem_unpin(struct drm_gem_object *obj);
>  void *drm_gem_vmap(struct drm_gem_object *obj);
>  void drm_gem_vunmap(struct drm_gem_object *obj, void *vaddr);
> +int drm_dumb_set_label_ioctl(struct drm_device *dev,
> +			void *data,
> +			struct drm_file *file_priv);
> +int drm_gem_set_label(struct drm_device *dev,
> +			struct drm_file *file_priv,
> +			uint32_t handle,
> +			const char *label);
> +void drm_gem_adopt_label(struct drm_gem_object *gem_obj, const char *label);
>  
>  /* drm_debugfs.c drm_debugfs_crc.c */
>  #if defined(CONFIG_DEBUG_FS)
> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> index fcd728d7cf72..f34e1571d70f 100644
> --- a/drivers/gpu/drm/drm_ioctl.c
> +++ b/drivers/gpu/drm/drm_ioctl.c
> @@ -714,6 +714,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER),
>  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER),
>  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER),
> +	DRM_IOCTL_DEF(DRM_IOCTL_DUMB_SET_LABEL, drm_dumb_set_label_ioctl, DRM_RENDER_ALLOW),
>  };
>  
>  #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
> diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> index cf13470810a5..501a3924354a 100644
> --- a/include/drm/drm_drv.h
> +++ b/include/drm/drm_drv.h
> @@ -715,6 +715,22 @@ struct drm_driver {
>  			    struct drm_device *dev,
>  			    uint32_t handle);
>  
> +	/**
> +	 * @label:
> +	 *
> +	 * This label's a buffer object.
> +	 *
> +	 * Called by the user via ioctl.
> +	 *
> +	 * Returns:
> +	 *
> +	 * Zero on success, negative errno on failure.
> +	 */
> +	int (*label)(struct drm_device *dev,
> +				struct drm_file *file_priv,
> +				uint32_t handle,
> +				char *label);
> +
>  	/**
>  	 * @gem_vm_ops: Driver private ops for this object
>  	 *
> diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
> index 6aaba14f5972..f801c054e972 100644
> --- a/include/drm/drm_gem.h
> +++ b/include/drm/drm_gem.h
> @@ -237,6 +237,13 @@ struct drm_gem_object {
>  	 */
>  	int name;
>  
> +	/**
> +	 * @label:
> +	 *
> +	 * Label for this object, should be a human readable string.
> +	 */
> +	char *label;
> +
>  	/**
>  	 * @dma_buf:
>  	 *
> diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
> index 8a5b2f8f8eb9..309c3c091385 100644
> --- a/include/uapi/drm/drm.h
> +++ b/include/uapi/drm/drm.h
> @@ -626,6 +626,25 @@ struct drm_gem_open {
>  	__u64 size;
>  };
>  
> +/** struct drm_dumb_set_label_object - ioctl argument for labelling BOs.
> + *
> + * This label's a BO with a userspace label
> + *
> + */
> +struct drm_dumb_set_label_object {
> +	/** Handle for the object being labelled. */
> +	__u32 handle;
> +
> +	/** Label and label length.
> +	 *  len includes the trailing NUL.
> +	 */
> +	__u32 len;
> +	__u64 name;
> +
> +	/** Flags */
> +	int flags;
> +};
> +
>  #define DRM_CAP_DUMB_BUFFER		0x1
>  #define DRM_CAP_VBLANK_HIGH_CRTC	0x2
>  #define DRM_CAP_DUMB_PREFERRED_DEPTH	0x3
> @@ -946,6 +965,7 @@ extern "C" {
>  #define DRM_IOCTL_SYNCOBJ_QUERY		DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
>  #define DRM_IOCTL_SYNCOBJ_TRANSFER	DRM_IOWR(0xCC, struct drm_syncobj_transfer)
>  #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL	DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
> +#define DRM_IOCTL_DUMB_SET_LABEL      DRM_IOWR(0xCE, struct drm_dumb_set_label_object)
>  
>  /**
>   * Device specific ioctls should only be in their respective headers
> -- 
> 2.17.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
Rohan Garg Oct. 22, 2019, 8:58 a.m. UTC | #7
Hey Daniel
On lunes, 14 de octubre de 2019 10:59:38 (CEST) Daniel Vetter wrote:
> On Fri, Oct 11, 2019 at 04:30:09PM +0200, Rohan Garg wrote:
> > DRM_IOCTL_DUMB_SET_LABEL lets you label GEM objects, making it
> > easier to debug issues in userspace applications.
> > 
> > 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
> 
> I still think we should just make this GEM-only and avoid the indirection.
> Except if your userspace actually does run on vmwgfx, and you absolutely
> want/need it to run there. Everything else is GEM-only.
> -Daniel
>

The plan for TTM drivers is to call drm_gem_adopt_label internally. So in 
practice, there really won't be too much TTM specific code.

This approach also future proof's us to be able to label any handles, not just 
GEM handle.

For the reasons above, I'd like to stick with my approach.

Cheers
Rohan Garg
 
> > Signed-off-by: Rohan Garg <rohan.garg@collabora.com>
> > ---
> > 
> >  drivers/gpu/drm/drm_gem.c      | 70 ++++++++++++++++++++++++++++++++++
> >  drivers/gpu/drm/drm_internal.h |  8 ++++
> >  drivers/gpu/drm/drm_ioctl.c    |  1 +
> >  include/drm/drm_drv.h          | 16 ++++++++
> >  include/drm/drm_gem.h          |  7 ++++
> >  include/uapi/drm/drm.h         | 20 ++++++++++
> >  6 files changed, 122 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> > index 6854f5867d51..0fa4609b2817 100644
> > --- a/drivers/gpu/drm/drm_gem.c
> > +++ b/drivers/gpu/drm/drm_gem.c
> > @@ -941,6 +941,71 @@ drm_gem_release(struct drm_device *dev, struct
> > drm_file *file_private)> 
> >  	idr_destroy(&file_private->object_idr);
> >  
> >  }
> > 
> > +int drm_dumb_set_label_ioctl(struct drm_device *dev,
> > +				void *data, struct drm_file 
*file_priv)
> > +{
> > +	char *label;
> > +	struct drm_dumb_set_label_object *args = data;
> > +	int ret = 0;
> > +
> > +	if (!args->len || !args->name)
> > +		return -EINVAL;
> > +
> > +	if (!dev->driver->label)
> > +		return -EOPNOTSUPP;
> > +
> > +	label = strndup_user(u64_to_user_ptr(args->name), args->len);
> > +
> > +	if (IS_ERR(label)) {
> > +		ret = PTR_ERR(label);
> > +		goto err;
> > +	}
> > +
> > +	ret = dev->driver->label(dev, file_priv, args->handle, label);
> > +
> > +err:
> > +	kfree(label);
> > +	return ret;
> > +}
> > +
> > +int drm_gem_set_label(struct drm_device *dev,
> > +		       struct drm_file *file_priv,
> > +			   uint32_t handle,
> > +			   const char *label)
> > +{
> > +	struct drm_gem_object *gem_obj;
> > +	int ret = 0;
> > +
> > +	gem_obj = drm_gem_object_lookup(file_priv, handle);
> > +	if (!gem_obj) {
> > +		DRM_DEBUG("Failed to look up GEM BO %d\n", handle);
> > +		ret = -ENOENT;
> > +		goto err;
> > +	}
> > +	drm_gem_adopt_label(gem_obj, label);
> > +
> > +err:
> > +	drm_gem_object_put_unlocked(gem_obj);
> > +	return ret;
> > +}
> > +EXPORT_SYMBOL(drm_gem_set_label);
> > +
> > +void drm_gem_adopt_label(struct drm_gem_object *gem_obj, const char
> > *label) +{
> > +	char *adopted_label = NULL;
> > +
> > +	if (label)
> > +		adopted_label = kstrdup(label, GFP_KERNEL);
> > +
> > +	if (gem_obj->label) {
> > +		kfree(gem_obj->label);
> > +		gem_obj->label = NULL;
> > +	}
> > +
> > +	gem_obj->label = adopted_label;
> > +}
> > +EXPORT_SYMBOL(drm_gem_adopt_label);
> > +
> > 
> >  /**
> >  
> >   * drm_gem_object_release - release GEM buffer object resources
> >   * @obj: GEM buffer object
> > 
> > @@ -958,6 +1023,11 @@ drm_gem_object_release(struct drm_gem_object *obj)
> > 
> >  	dma_resv_fini(&obj->_resv);
> >  	drm_gem_free_mmap_offset(obj);
> > 
> > +
> > +	if (obj->label) {
> > +		kfree(obj->label);
> > +		obj->label = NULL;
> > +	}
> > 
> >  }
> >  EXPORT_SYMBOL(drm_gem_object_release);
> > 
> > diff --git a/drivers/gpu/drm/drm_internal.h
> > b/drivers/gpu/drm/drm_internal.h index 51a2055c8f18..cbc3f7b7fb9b 100644
> > --- a/drivers/gpu/drm/drm_internal.h
> > +++ b/drivers/gpu/drm/drm_internal.h
> > @@ -137,6 +137,14 @@ int drm_gem_pin(struct drm_gem_object *obj);
> > 
> >  void drm_gem_unpin(struct drm_gem_object *obj);
> >  void *drm_gem_vmap(struct drm_gem_object *obj);
> >  void drm_gem_vunmap(struct drm_gem_object *obj, void *vaddr);
> > 
> > +int drm_dumb_set_label_ioctl(struct drm_device *dev,
> > +			void *data,
> > +			struct drm_file *file_priv);
> > +int drm_gem_set_label(struct drm_device *dev,
> > +			struct drm_file *file_priv,
> > +			uint32_t handle,
> > +			const char *label);
> > +void drm_gem_adopt_label(struct drm_gem_object *gem_obj, const char
> > *label);> 
> >  /* drm_debugfs.c drm_debugfs_crc.c */
> >  #if defined(CONFIG_DEBUG_FS)
> > 
> > diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> > index fcd728d7cf72..f34e1571d70f 100644
> > --- a/drivers/gpu/drm/drm_ioctl.c
> > +++ b/drivers/gpu/drm/drm_ioctl.c
> > @@ -714,6 +714,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
> > 
> >  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, 
drm_mode_list_lessees_ioctl,
> >  	DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE,
> >  	drm_mode_get_lease_ioctl, DRM_MASTER),
> >  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, 
drm_mode_revoke_lease_ioctl,
> >  	DRM_MASTER),> 
> > +	DRM_IOCTL_DEF(DRM_IOCTL_DUMB_SET_LABEL, drm_dumb_set_label_ioctl,
> > DRM_RENDER_ALLOW),> 
> >  };
> >  
> >  #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
> > 
> > diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> > index cf13470810a5..501a3924354a 100644
> > --- a/include/drm/drm_drv.h
> > +++ b/include/drm/drm_drv.h
> > @@ -715,6 +715,22 @@ struct drm_driver {
> > 
> >  			    struct drm_device *dev,
> >  			    uint32_t handle);
> > 
> > +	/**
> > +	 * @label:
> > +	 *
> > +	 * This label's a buffer object.
> > +	 *
> > +	 * Called by the user via ioctl.
> > +	 *
> > +	 * Returns:
> > +	 *
> > +	 * Zero on success, negative errno on failure.
> > +	 */
> > +	int (*label)(struct drm_device *dev,
> > +				struct drm_file *file_priv,
> > +				uint32_t handle,
> > +				char *label);
> > +
> > 
> >  	/**
> >  	
> >  	 * @gem_vm_ops: Driver private ops for this object
> >  	 *
> > 
> > diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
> > index 6aaba14f5972..f801c054e972 100644
> > --- a/include/drm/drm_gem.h
> > +++ b/include/drm/drm_gem.h
> > @@ -237,6 +237,13 @@ struct drm_gem_object {
> > 
> >  	 */
> >  	
> >  	int name;
> > 
> > +	/**
> > +	 * @label:
> > +	 *
> > +	 * Label for this object, should be a human readable string.
> > +	 */
> > +	char *label;
> > +
> > 
> >  	/**
> >  	
> >  	 * @dma_buf:
> >  	 *
> > 
> > diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
> > index 8a5b2f8f8eb9..309c3c091385 100644
> > --- a/include/uapi/drm/drm.h
> > +++ b/include/uapi/drm/drm.h
> > @@ -626,6 +626,25 @@ struct drm_gem_open {
> > 
> >  	__u64 size;
> >  
> >  };
> > 
> > +/** struct drm_dumb_set_label_object - ioctl argument for labelling BOs.
> > + *
> > + * This label's a BO with a userspace label
> > + *
> > + */
> > +struct drm_dumb_set_label_object {
> > +	/** Handle for the object being labelled. */
> > +	__u32 handle;
> > +
> > +	/** Label and label length.
> > +	 *  len includes the trailing NUL.
> > +	 */
> > +	__u32 len;
> > +	__u64 name;
> > +
> > +	/** Flags */
> > +	int flags;
> > +};
> > +
> > 
> >  #define DRM_CAP_DUMB_BUFFER		0x1
> >  #define DRM_CAP_VBLANK_HIGH_CRTC	0x2
> >  #define DRM_CAP_DUMB_PREFERRED_DEPTH	0x3
> > 
> > @@ -946,6 +965,7 @@ extern "C" {
> > 
> >  #define DRM_IOCTL_SYNCOBJ_QUERY		DRM_IOWR(0xCB, struct
> >  drm_syncobj_timeline_array) #define
> >  DRM_IOCTL_SYNCOBJ_TRANSFER	DRM_IOWR(0xCC, struct drm_syncobj_transfer)
> >  #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL	DRM_IOWR(0xCD, struct
> >  drm_syncobj_timeline_array)> 
> > +#define DRM_IOCTL_DUMB_SET_LABEL      DRM_IOWR(0xCE, struct
> > drm_dumb_set_label_object)> 
> >  /**
> >  
> >   * Device specific ioctls should only be in their respective headers
Rohan Garg Oct. 22, 2019, 8:58 a.m. UTC | #8
Hi Thomas
On viernes, 11 de octubre de 2019 19:55:36 (CEST) Thomas Zimmermann wrote:
> Hi
> 
> Am 11.10.19 um 19:09 schrieb Daniel Stone:
> > Hi Rohan,
> > 
> > On Fri, 11 Oct 2019 at 15:30, Rohan Garg <rohan.garg@collabora.com> wrote:
> >> DRM_IOCTL_DUMB_SET_LABEL lets you label GEM objects, making it
> >> easier to debug issues in userspace applications.
> > 
> > I'm not sure if this was pointed out already, but dumb buffers != GEM
> > buffers. GEM buffers _can_ be dumb, but might not be.
> > 
> > Could you please rename to GEM_SET_LABEL?
> 
> This change to build upon dumb buffers was suggested by me, as dumb
> buffers is the closes thing there is to a buffer management interface.
> Drivers with 'smart buffers' would have to add their own ioctl interfaces.
> 
> What I really miss here is a userspace application that uses this
> functionality. It would be much easier to discuss if there was an actual
> example.
> 

I'm currently working on implementing something for Mesa. I'll send a v5 based 
on the lessons learnt from that patchset.

> Best regards
> 
> > Cheers,
> > Daniel
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
Rohan Garg Oct. 22, 2019, 8:58 a.m. UTC | #9
Hey
On viernes, 11 de octubre de 2019 19:09:52 (CEST) Daniel Stone wrote:
> Hi Rohan,
> 
> On Fri, 11 Oct 2019 at 15:30, Rohan Garg <rohan.garg@collabora.com> wrote:
> > DRM_IOCTL_DUMB_SET_LABEL lets you label GEM objects, making it
> > easier to debug issues in userspace applications.
> 
> I'm not sure if this was pointed out already, but dumb buffers != GEM
> buffers. GEM buffers _can_ be dumb, but might not be.
> 
> Could you please rename to GEM_SET_LABEL?
> 

Daniel and I had a opportunity to talk about this in person and we agreed that 
HANDLE_SET_LABEL would be a more sensible name.

Cheers
Rohan Garg
Daniel Vetter Oct. 22, 2019, 9:30 a.m. UTC | #10
On Tue, Oct 22, 2019 at 10:58:02AM +0200, Rohan Garg wrote:
> Hey Daniel
> On lunes, 14 de octubre de 2019 10:59:38 (CEST) Daniel Vetter wrote:
> > On Fri, Oct 11, 2019 at 04:30:09PM +0200, Rohan Garg wrote:
> > > DRM_IOCTL_DUMB_SET_LABEL lets you label GEM objects, making it
> > > easier to debug issues in userspace applications.
> > > 
> > > 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
> > 
> > I still think we should just make this GEM-only and avoid the indirection.
> > Except if your userspace actually does run on vmwgfx, and you absolutely
> > want/need it to run there. Everything else is GEM-only.
> > -Daniel
> >
> 
> The plan for TTM drivers is to call drm_gem_adopt_label internally. So in 
> practice, there really won't be too much TTM specific code.
> 
> This approach also future proof's us to be able to label any handles, not just 
> GEM handle.

I don't expect we'll ever merge any non-gem drivers in the future anymore.
Hence this really only makes sense if vmwgfx wants it, that's the only
use-case for this generic-ism here. If vmwgfx doesn't have a use or jump
on board with this, imo better to just make this specific to gem and be
done.
-Daniel

> For the reasons above, I'd like to stick with my approach.
> 
> Cheers
> Rohan Garg
>  
> > > Signed-off-by: Rohan Garg <rohan.garg@collabora.com>
> > > ---
> > > 
> > >  drivers/gpu/drm/drm_gem.c      | 70 ++++++++++++++++++++++++++++++++++
> > >  drivers/gpu/drm/drm_internal.h |  8 ++++
> > >  drivers/gpu/drm/drm_ioctl.c    |  1 +
> > >  include/drm/drm_drv.h          | 16 ++++++++
> > >  include/drm/drm_gem.h          |  7 ++++
> > >  include/uapi/drm/drm.h         | 20 ++++++++++
> > >  6 files changed, 122 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> > > index 6854f5867d51..0fa4609b2817 100644
> > > --- a/drivers/gpu/drm/drm_gem.c
> > > +++ b/drivers/gpu/drm/drm_gem.c
> > > @@ -941,6 +941,71 @@ drm_gem_release(struct drm_device *dev, struct
> > > drm_file *file_private)> 
> > >  	idr_destroy(&file_private->object_idr);
> > >  
> > >  }
> > > 
> > > +int drm_dumb_set_label_ioctl(struct drm_device *dev,
> > > +				void *data, struct drm_file 
> *file_priv)
> > > +{
> > > +	char *label;
> > > +	struct drm_dumb_set_label_object *args = data;
> > > +	int ret = 0;
> > > +
> > > +	if (!args->len || !args->name)
> > > +		return -EINVAL;
> > > +
> > > +	if (!dev->driver->label)
> > > +		return -EOPNOTSUPP;
> > > +
> > > +	label = strndup_user(u64_to_user_ptr(args->name), args->len);
> > > +
> > > +	if (IS_ERR(label)) {
> > > +		ret = PTR_ERR(label);
> > > +		goto err;
> > > +	}
> > > +
> > > +	ret = dev->driver->label(dev, file_priv, args->handle, label);
> > > +
> > > +err:
> > > +	kfree(label);
> > > +	return ret;
> > > +}
> > > +
> > > +int drm_gem_set_label(struct drm_device *dev,
> > > +		       struct drm_file *file_priv,
> > > +			   uint32_t handle,
> > > +			   const char *label)
> > > +{
> > > +	struct drm_gem_object *gem_obj;
> > > +	int ret = 0;
> > > +
> > > +	gem_obj = drm_gem_object_lookup(file_priv, handle);
> > > +	if (!gem_obj) {
> > > +		DRM_DEBUG("Failed to look up GEM BO %d\n", handle);
> > > +		ret = -ENOENT;
> > > +		goto err;
> > > +	}
> > > +	drm_gem_adopt_label(gem_obj, label);
> > > +
> > > +err:
> > > +	drm_gem_object_put_unlocked(gem_obj);
> > > +	return ret;
> > > +}
> > > +EXPORT_SYMBOL(drm_gem_set_label);
> > > +
> > > +void drm_gem_adopt_label(struct drm_gem_object *gem_obj, const char
> > > *label) +{
> > > +	char *adopted_label = NULL;
> > > +
> > > +	if (label)
> > > +		adopted_label = kstrdup(label, GFP_KERNEL);
> > > +
> > > +	if (gem_obj->label) {
> > > +		kfree(gem_obj->label);
> > > +		gem_obj->label = NULL;
> > > +	}
> > > +
> > > +	gem_obj->label = adopted_label;
> > > +}
> > > +EXPORT_SYMBOL(drm_gem_adopt_label);
> > > +
> > > 
> > >  /**
> > >  
> > >   * drm_gem_object_release - release GEM buffer object resources
> > >   * @obj: GEM buffer object
> > > 
> > > @@ -958,6 +1023,11 @@ drm_gem_object_release(struct drm_gem_object *obj)
> > > 
> > >  	dma_resv_fini(&obj->_resv);
> > >  	drm_gem_free_mmap_offset(obj);
> > > 
> > > +
> > > +	if (obj->label) {
> > > +		kfree(obj->label);
> > > +		obj->label = NULL;
> > > +	}
> > > 
> > >  }
> > >  EXPORT_SYMBOL(drm_gem_object_release);
> > > 
> > > diff --git a/drivers/gpu/drm/drm_internal.h
> > > b/drivers/gpu/drm/drm_internal.h index 51a2055c8f18..cbc3f7b7fb9b 100644
> > > --- a/drivers/gpu/drm/drm_internal.h
> > > +++ b/drivers/gpu/drm/drm_internal.h
> > > @@ -137,6 +137,14 @@ int drm_gem_pin(struct drm_gem_object *obj);
> > > 
> > >  void drm_gem_unpin(struct drm_gem_object *obj);
> > >  void *drm_gem_vmap(struct drm_gem_object *obj);
> > >  void drm_gem_vunmap(struct drm_gem_object *obj, void *vaddr);
> > > 
> > > +int drm_dumb_set_label_ioctl(struct drm_device *dev,
> > > +			void *data,
> > > +			struct drm_file *file_priv);
> > > +int drm_gem_set_label(struct drm_device *dev,
> > > +			struct drm_file *file_priv,
> > > +			uint32_t handle,
> > > +			const char *label);
> > > +void drm_gem_adopt_label(struct drm_gem_object *gem_obj, const char
> > > *label);> 
> > >  /* drm_debugfs.c drm_debugfs_crc.c */
> > >  #if defined(CONFIG_DEBUG_FS)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> > > index fcd728d7cf72..f34e1571d70f 100644
> > > --- a/drivers/gpu/drm/drm_ioctl.c
> > > +++ b/drivers/gpu/drm/drm_ioctl.c
> > > @@ -714,6 +714,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
> > > 
> > >  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, 
> drm_mode_list_lessees_ioctl,
> > >  	DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE,
> > >  	drm_mode_get_lease_ioctl, DRM_MASTER),
> > >  	DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, 
> drm_mode_revoke_lease_ioctl,
> > >  	DRM_MASTER),> 
> > > +	DRM_IOCTL_DEF(DRM_IOCTL_DUMB_SET_LABEL, drm_dumb_set_label_ioctl,
> > > DRM_RENDER_ALLOW),> 
> > >  };
> > >  
> > >  #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
> > > 
> > > diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
> > > index cf13470810a5..501a3924354a 100644
> > > --- a/include/drm/drm_drv.h
> > > +++ b/include/drm/drm_drv.h
> > > @@ -715,6 +715,22 @@ struct drm_driver {
> > > 
> > >  			    struct drm_device *dev,
> > >  			    uint32_t handle);
> > > 
> > > +	/**
> > > +	 * @label:
> > > +	 *
> > > +	 * This label's a buffer object.
> > > +	 *
> > > +	 * Called by the user via ioctl.
> > > +	 *
> > > +	 * Returns:
> > > +	 *
> > > +	 * Zero on success, negative errno on failure.
> > > +	 */
> > > +	int (*label)(struct drm_device *dev,
> > > +				struct drm_file *file_priv,
> > > +				uint32_t handle,
> > > +				char *label);
> > > +
> > > 
> > >  	/**
> > >  	
> > >  	 * @gem_vm_ops: Driver private ops for this object
> > >  	 *
> > > 
> > > diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
> > > index 6aaba14f5972..f801c054e972 100644
> > > --- a/include/drm/drm_gem.h
> > > +++ b/include/drm/drm_gem.h
> > > @@ -237,6 +237,13 @@ struct drm_gem_object {
> > > 
> > >  	 */
> > >  	
> > >  	int name;
> > > 
> > > +	/**
> > > +	 * @label:
> > > +	 *
> > > +	 * Label for this object, should be a human readable string.
> > > +	 */
> > > +	char *label;
> > > +
> > > 
> > >  	/**
> > >  	
> > >  	 * @dma_buf:
> > >  	 *
> > > 
> > > diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
> > > index 8a5b2f8f8eb9..309c3c091385 100644
> > > --- a/include/uapi/drm/drm.h
> > > +++ b/include/uapi/drm/drm.h
> > > @@ -626,6 +626,25 @@ struct drm_gem_open {
> > > 
> > >  	__u64 size;
> > >  
> > >  };
> > > 
> > > +/** struct drm_dumb_set_label_object - ioctl argument for labelling BOs.
> > > + *
> > > + * This label's a BO with a userspace label
> > > + *
> > > + */
> > > +struct drm_dumb_set_label_object {
> > > +	/** Handle for the object being labelled. */
> > > +	__u32 handle;
> > > +
> > > +	/** Label and label length.
> > > +	 *  len includes the trailing NUL.
> > > +	 */
> > > +	__u32 len;
> > > +	__u64 name;
> > > +
> > > +	/** Flags */
> > > +	int flags;
> > > +};
> > > +
> > > 
> > >  #define DRM_CAP_DUMB_BUFFER		0x1
> > >  #define DRM_CAP_VBLANK_HIGH_CRTC	0x2
> > >  #define DRM_CAP_DUMB_PREFERRED_DEPTH	0x3
> > > 
> > > @@ -946,6 +965,7 @@ extern "C" {
> > > 
> > >  #define DRM_IOCTL_SYNCOBJ_QUERY		DRM_IOWR(0xCB, struct
> > >  drm_syncobj_timeline_array) #define
> > >  DRM_IOCTL_SYNCOBJ_TRANSFER	DRM_IOWR(0xCC, struct drm_syncobj_transfer)
> > >  #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL	DRM_IOWR(0xCD, struct
> > >  drm_syncobj_timeline_array)> 
> > > +#define DRM_IOCTL_DUMB_SET_LABEL      DRM_IOWR(0xCE, struct
> > > drm_dumb_set_label_object)> 
> > >  /**
> > >  
> > >   * Device specific ioctls should only be in their respective headers
> 
> 
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
Daniel Stone Oct. 22, 2019, 1:14 p.m. UTC | #11
Hey,

On Tue, 22 Oct 2019 at 11:30, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Tue, Oct 22, 2019 at 10:58:02AM +0200, Rohan Garg wrote:
> > This approach also future proof's us to be able to label any handles, not just
> > GEM handle.
>
> I don't expect we'll ever merge any non-gem drivers in the future anymore.
> Hence this really only makes sense if vmwgfx wants it, that's the only
> use-case for this generic-ism here. If vmwgfx doesn't have a use or jump
> on board with this, imo better to just make this specific to gem and be
> done.

VMware were the exact people who asked it for to be handle-agnostic
and not GEM-specific ...

Given that we already have handle-agnostic calls like FBs in
particular, I think it makes sense to have this one just follow that.
It's not much code and doesn't really imply any heavy change for the
rest of DRM.

Cheers,
Daniel
diff mbox series

Patch

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 6854f5867d51..0fa4609b2817 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -941,6 +941,71 @@  drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
 	idr_destroy(&file_private->object_idr);
 }
 
+int drm_dumb_set_label_ioctl(struct drm_device *dev,
+				void *data, struct drm_file *file_priv)
+{
+	char *label;
+	struct drm_dumb_set_label_object *args = data;
+	int ret = 0;
+
+	if (!args->len || !args->name)
+		return -EINVAL;
+
+	if (!dev->driver->label)
+		return -EOPNOTSUPP;
+
+	label = strndup_user(u64_to_user_ptr(args->name), args->len);
+
+	if (IS_ERR(label)) {
+		ret = PTR_ERR(label);
+		goto err;
+	}
+
+	ret = dev->driver->label(dev, file_priv, args->handle, label);
+
+err:
+	kfree(label);
+	return ret;
+}
+
+int drm_gem_set_label(struct drm_device *dev,
+		       struct drm_file *file_priv,
+			   uint32_t handle,
+			   const char *label)
+{
+	struct drm_gem_object *gem_obj;
+	int ret = 0;
+
+	gem_obj = drm_gem_object_lookup(file_priv, handle);
+	if (!gem_obj) {
+		DRM_DEBUG("Failed to look up GEM BO %d\n", handle);
+		ret = -ENOENT;
+		goto err;
+	}
+	drm_gem_adopt_label(gem_obj, label);
+
+err:
+	drm_gem_object_put_unlocked(gem_obj);
+	return ret;
+}
+EXPORT_SYMBOL(drm_gem_set_label);
+
+void drm_gem_adopt_label(struct drm_gem_object *gem_obj, const char *label)
+{
+	char *adopted_label = NULL;
+
+	if (label)
+		adopted_label = kstrdup(label, GFP_KERNEL);
+
+	if (gem_obj->label) {
+		kfree(gem_obj->label);
+		gem_obj->label = NULL;
+	}
+
+	gem_obj->label = adopted_label;
+}
+EXPORT_SYMBOL(drm_gem_adopt_label);
+
 /**
  * drm_gem_object_release - release GEM buffer object resources
  * @obj: GEM buffer object
@@ -958,6 +1023,11 @@  drm_gem_object_release(struct drm_gem_object *obj)
 
 	dma_resv_fini(&obj->_resv);
 	drm_gem_free_mmap_offset(obj);
+
+	if (obj->label) {
+		kfree(obj->label);
+		obj->label = NULL;
+	}
 }
 EXPORT_SYMBOL(drm_gem_object_release);
 
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 51a2055c8f18..cbc3f7b7fb9b 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -137,6 +137,14 @@  int drm_gem_pin(struct drm_gem_object *obj);
 void drm_gem_unpin(struct drm_gem_object *obj);
 void *drm_gem_vmap(struct drm_gem_object *obj);
 void drm_gem_vunmap(struct drm_gem_object *obj, void *vaddr);
+int drm_dumb_set_label_ioctl(struct drm_device *dev,
+			void *data,
+			struct drm_file *file_priv);
+int drm_gem_set_label(struct drm_device *dev,
+			struct drm_file *file_priv,
+			uint32_t handle,
+			const char *label);
+void drm_gem_adopt_label(struct drm_gem_object *gem_obj, const char *label);
 
 /* drm_debugfs.c drm_debugfs_crc.c */
 #if defined(CONFIG_DEBUG_FS)
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index fcd728d7cf72..f34e1571d70f 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -714,6 +714,7 @@  static const struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_LIST_LESSEES, drm_mode_list_lessees_ioctl, DRM_MASTER),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GET_LEASE, drm_mode_get_lease_ioctl, DRM_MASTER),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_REVOKE_LEASE, drm_mode_revoke_lease_ioctl, DRM_MASTER),
+	DRM_IOCTL_DEF(DRM_IOCTL_DUMB_SET_LABEL, drm_dumb_set_label_ioctl, DRM_RENDER_ALLOW),
 };
 
 #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index cf13470810a5..501a3924354a 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -715,6 +715,22 @@  struct drm_driver {
 			    struct drm_device *dev,
 			    uint32_t handle);
 
+	/**
+	 * @label:
+	 *
+	 * This label's a buffer object.
+	 *
+	 * Called by the user via ioctl.
+	 *
+	 * Returns:
+	 *
+	 * Zero on success, negative errno on failure.
+	 */
+	int (*label)(struct drm_device *dev,
+				struct drm_file *file_priv,
+				uint32_t handle,
+				char *label);
+
 	/**
 	 * @gem_vm_ops: Driver private ops for this object
 	 *
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index 6aaba14f5972..f801c054e972 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -237,6 +237,13 @@  struct drm_gem_object {
 	 */
 	int name;
 
+	/**
+	 * @label:
+	 *
+	 * Label for this object, should be a human readable string.
+	 */
+	char *label;
+
 	/**
 	 * @dma_buf:
 	 *
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 8a5b2f8f8eb9..309c3c091385 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -626,6 +626,25 @@  struct drm_gem_open {
 	__u64 size;
 };
 
+/** struct drm_dumb_set_label_object - ioctl argument for labelling BOs.
+ *
+ * This label's a BO with a userspace label
+ *
+ */
+struct drm_dumb_set_label_object {
+	/** Handle for the object being labelled. */
+	__u32 handle;
+
+	/** Label and label length.
+	 *  len includes the trailing NUL.
+	 */
+	__u32 len;
+	__u64 name;
+
+	/** Flags */
+	int flags;
+};
+
 #define DRM_CAP_DUMB_BUFFER		0x1
 #define DRM_CAP_VBLANK_HIGH_CRTC	0x2
 #define DRM_CAP_DUMB_PREFERRED_DEPTH	0x3
@@ -946,6 +965,7 @@  extern "C" {
 #define DRM_IOCTL_SYNCOBJ_QUERY		DRM_IOWR(0xCB, struct drm_syncobj_timeline_array)
 #define DRM_IOCTL_SYNCOBJ_TRANSFER	DRM_IOWR(0xCC, struct drm_syncobj_transfer)
 #define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL	DRM_IOWR(0xCD, struct drm_syncobj_timeline_array)
+#define DRM_IOCTL_DUMB_SET_LABEL      DRM_IOWR(0xCE, struct drm_dumb_set_label_object)
 
 /**
  * Device specific ioctls should only be in their respective headers