[PATCH 1/8] sync_file: add type/flags to sync file object creation.
Daniel Vetter
daniel at ffwll.ch
Tue Apr 4 07:08:57 UTC 2017
On Tue, Apr 04, 2017 at 02:27:26PM +1000, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This allows us to create sync files with different semantics,
> and clearly define the interoperation between them it also
> provides flags to allow for tweaks on those semantics.
>
> This provides a validation interface for drivers that accept
> types from userspace so they can return EINVAL instead of ENOMEM.
>
> This provides an ioctl for userspace to retrieve the type/flags
> of an object it may recieve from somewhere else.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
Since you've bothered to type the docs for the ioctl structs too, please
squash in the below (and double-check that kernel-doc is still happy):
diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst
index 31671b469627..375848c590ce 100644
--- a/Documentation/driver-api/dma-buf.rst
+++ b/Documentation/driver-api/dma-buf.rst
@@ -163,3 +163,8 @@ DMA Fence uABI/Sync File
.. kernel-doc:: include/linux/sync_file.h
:internal:
+Sync File IOCTL Definitions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/uapi/linux/sync_file.h
+ :internal:
With that: Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
One open question: Do we expect the current sync_file_get_fence to only
ever work for a FENCE type sync_file? Might be good to clarify that in the
kernel-doc for sync_file_get_fence().
-Daniel
> ---
> drivers/dma-buf/sw_sync.c | 2 +-
> drivers/dma-buf/sync_file.c | 62 +++++++++++++++++++++++++++++++++++++++---
> drivers/gpu/drm/drm_atomic.c | 2 +-
> include/linux/sync_file.h | 9 +++++-
> include/uapi/linux/sync_file.h | 27 ++++++++++++++++++
> 5 files changed, 95 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
> index 69c5ff3..1c47de6 100644
> --- a/drivers/dma-buf/sw_sync.c
> +++ b/drivers/dma-buf/sw_sync.c
> @@ -315,7 +315,7 @@ static long sw_sync_ioctl_create_fence(struct sync_timeline *obj,
> goto err;
> }
>
> - sync_file = sync_file_create(&pt->base);
> + sync_file = sync_file_create(&pt->base, SYNC_FILE_TYPE_FENCE, 0);
> dma_fence_put(&pt->base);
> if (!sync_file) {
> err = -ENOMEM;
> diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
> index 2321035..b33af9d 100644
> --- a/drivers/dma-buf/sync_file.c
> +++ b/drivers/dma-buf/sync_file.c
> @@ -28,9 +28,32 @@
>
> static const struct file_operations sync_file_fops;
>
> -static struct sync_file *sync_file_alloc(void)
> +/**
> + * sync_file_validate_type_flags - validate type/flags for support
> + * @type: type of sync file object
> + * @flags: flags to sync object.
> + *
> + * Validates the flags are correct so userspace can get a more
> + * detailed error type.
> + */
> +int sync_file_validate_type_flags(uint32_t type, uint32_t flags)
> +{
> + if (flags)
> + return -EINVAL;
> + if (type != SYNC_FILE_TYPE_FENCE)
> + return -EINVAL;
> + return 0;
> +}
> +EXPORT_SYMBOL(sync_file_validate_type_flags);
> +
> +static struct sync_file *sync_file_alloc(uint32_t type, uint32_t flags)
> {
> struct sync_file *sync_file;
> + int ret;
> +
> + ret = sync_file_validate_type_flags(type, flags);
> + if (ret)
> + return NULL;
>
> sync_file = kzalloc(sizeof(*sync_file), GFP_KERNEL);
> if (!sync_file)
> @@ -47,6 +70,8 @@ static struct sync_file *sync_file_alloc(void)
>
> INIT_LIST_HEAD(&sync_file->cb.node);
>
> + sync_file->type = type;
> + sync_file->flags = flags;
> return sync_file;
>
> err:
> @@ -72,11 +97,13 @@ static void fence_check_cb_func(struct dma_fence *f, struct dma_fence_cb *cb)
> * sync_file can be released with fput(sync_file->file). Returns the
> * sync_file or NULL in case of error.
> */
> -struct sync_file *sync_file_create(struct dma_fence *fence)
> +struct sync_file *sync_file_create(struct dma_fence *fence,
> + uint32_t type,
> + uint32_t flags)
> {
> struct sync_file *sync_file;
>
> - sync_file = sync_file_alloc();
> + sync_file = sync_file_alloc(type, flags);
> if (!sync_file)
> return NULL;
>
> @@ -200,7 +227,10 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
> struct dma_fence **fences, **nfences, **a_fences, **b_fences;
> int i, i_a, i_b, num_fences, a_num_fences, b_num_fences;
>
> - sync_file = sync_file_alloc();
> + if (a->type != b->type)
> + return NULL;
> +
> + sync_file = sync_file_alloc(a->type, a->flags);
> if (!sync_file)
> return NULL;
>
> @@ -437,6 +467,27 @@ static long sync_file_ioctl_fence_info(struct sync_file *sync_file,
> return ret;
> }
>
> +static long sync_file_ioctl_type(struct sync_file *sync_file,
> + unsigned long arg)
> +{
> + struct sync_file_type type;
> + int ret;
> + if (copy_from_user(&type, (void __user *)arg, sizeof(type)))
> + return -EFAULT;
> +
> + if (type.flags || type.type)
> + return -EINVAL;
> +
> + type.type = sync_file->type;
> + type.flags = sync_file->flags;
> +
> + if (copy_to_user((void __user *)arg, &type, sizeof(type)))
> + ret = -EFAULT;
> + else
> + ret = 0;
> + return ret;
> +}
> +
> static long sync_file_ioctl(struct file *file, unsigned int cmd,
> unsigned long arg)
> {
> @@ -449,6 +500,9 @@ static long sync_file_ioctl(struct file *file, unsigned int cmd,
> case SYNC_IOC_FILE_INFO:
> return sync_file_ioctl_fence_info(sync_file, arg);
>
> + case SYNC_IOC_TYPE:
> + return sync_file_ioctl_type(sync_file, arg);
> +
> default:
> return -ENOTTY;
> }
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index a567310..bb5a740 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -1917,7 +1917,7 @@ static int setup_out_fence(struct drm_out_fence_state *fence_state,
> if (put_user(fence_state->fd, fence_state->out_fence_ptr))
> return -EFAULT;
>
> - fence_state->sync_file = sync_file_create(fence);
> + fence_state->sync_file = sync_file_create(fence, SYNC_FILE_TYPE_FENCE, 0);
> if (!fence_state->sync_file)
> return -ENOMEM;
>
> diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h
> index 3e3ab84..ede4182 100644
> --- a/include/linux/sync_file.h
> +++ b/include/linux/sync_file.h
> @@ -20,6 +20,8 @@
> #include <linux/spinlock.h>
> #include <linux/dma-fence.h>
> #include <linux/dma-fence-array.h>
> +#include <uapi/linux/sync_file.h>
> +
>
> /**
> * struct sync_file - sync file to export to the userspace
> @@ -30,6 +32,8 @@
> * @wq: wait queue for fence signaling
> * @fence: fence with the fences in the sync_file
> * @cb: fence callback information
> + * @type: sync file type
> + * @flags: flags used to create sync file
> */
> struct sync_file {
> struct file *file;
> @@ -43,11 +47,14 @@ struct sync_file {
>
> struct dma_fence *fence;
> struct dma_fence_cb cb;
> + uint32_t type;
> + uint32_t flags;
> };
>
> #define POLL_ENABLED DMA_FENCE_FLAG_USER_BITS
>
> -struct sync_file *sync_file_create(struct dma_fence *fence);
> +int sync_file_validate_type_flags(uint32_t type, uint32_t flags);
> +struct sync_file *sync_file_create(struct dma_fence *fence, uint32_t type, uint32_t flags);
> struct dma_fence *sync_file_get_fence(int fd);
>
> #endif /* _LINUX_SYNC_H */
> diff --git a/include/uapi/linux/sync_file.h b/include/uapi/linux/sync_file.h
> index 5b287d6..f439cda 100644
> --- a/include/uapi/linux/sync_file.h
> +++ b/include/uapi/linux/sync_file.h
> @@ -69,6 +69,26 @@ struct sync_file_info {
> #define SYNC_IOC_MAGIC '>'
>
> /**
> + * DOC: SYNC_FILE_TYPE_FENCE - fence sync file object
> + *
> + * This sync file is a wrapper around a dma fence or a dma fence array.
> + * It can be merged with another fence sync file object to create a new
> + * merged object.
> + * The fence backing this object cannot be replaced.
> + * This is useful for shared fences.
> + */
> +#define SYNC_FILE_TYPE_FENCE 0
> +
> +/**
> + * struct sync_file_type - data returned from sync file type ioctl
> + * @type: sync_file type
> + * @flags: sync_file creation flags
> + */
> +struct sync_file_type {
> + __u32 type;
> + __u32 flags;
> +};
> +/**
> * Opcodes 0, 1 and 2 were burned during a API change to avoid users of the
> * old API to get weird errors when trying to handling sync_files. The API
> * change happened during the de-stage of the Sync Framework when there was
> @@ -94,4 +114,11 @@ struct sync_file_info {
> */
> #define SYNC_IOC_FILE_INFO _IOWR(SYNC_IOC_MAGIC, 4, struct sync_file_info)
>
> +/**
> + * DOC: SYNC_IOC_TYPE - get creation type and flags of sync_file.
> + *
> + * Takes a struct sync_file_type. Returns the created values of type and flags.
> + */
> +#define SYNC_IOC_TYPE _IOWR(SYNC_IOC_MAGIC, 5, struct sync_file_type)
> +
> #endif /* _UAPI_LINUX_SYNC_H */
> --
> 2.9.3
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
More information about the dri-devel
mailing list