[PATCH 5/8] sync_file: add support for a semaphore object
Daniel Vetter
daniel at ffwll.ch
Tue Apr 4 07:59:31 UTC 2017
On Tue, Apr 04, 2017 at 02:27:30PM +1000, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This object can be used to implement the Vulkan semaphores.
>
> The object behaviour differs from fence, in that you can
> replace the underlying fence, and you cannot merge semaphores.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
Since you're going to all the trouble of having distinct types of
sync_file:
- I think we should reject non-TYPE_FENCE sync_file in
sync_file_get_fence. This is to make sure no one can pull existing
userspace over the table. Fence vs. sema also have different semantics,
so I expect we'll have separate cs flags anyway.
- Already mentioned in the drm_syncobj patch, but I'd reorder that one
after this one here and restrict drm_syncobj to only TYPE_SEMA. At least
I can't see any reason why you'd want to make a plain fence persistent
using an idr, they're kinda ephemeral.
A few more minor nits below. Patch itself looks good, but I want to figure
the type confusion semantics out first.
Cheers, Daniel
> ---
> drivers/dma-buf/sync_file.c | 36 +++++++++++++++++++++++++++++++++++-
> include/linux/sync_file.h | 2 ++
> include/uapi/linux/sync_file.h | 14 ++++++++++++++
> 3 files changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
> index 6376f6f..a82f6d8 100644
> --- a/drivers/dma-buf/sync_file.c
> +++ b/drivers/dma-buf/sync_file.c
> @@ -44,7 +44,7 @@ int sync_file_validate_type_flags(uint32_t type, uint32_t flags)
> {
> if (flags)
> return -EINVAL;
> - if (type != SYNC_FILE_TYPE_FENCE)
> + if (type != SYNC_FILE_TYPE_FENCE && type != SYNC_FILE_TYPE_SEMAPHORE)
> return -EINVAL;
> return 0;
> }
> @@ -200,6 +200,38 @@ sync_file_get_fence_locked(struct sync_file *sync_file)
> sync_file_held(sync_file));
> }
>
> +/**
> + * sync_file_replace_fence - replace the fence related to the sync_file
> + * @sync_file: sync file to replace fence in
> + * @fence: fence to replace with (or NULL for no fence).
Maybe mention here that this is only valid for TYPE_SEMA?
> + * Returns previous fence.
> + */
> +struct dma_fence *sync_file_replace_fence(struct sync_file *sync_file,
> + struct dma_fence *fence)
> +{
> + struct dma_fence *ret_fence = NULL;
> +
> + if (sync_file->type != SYNC_FILE_TYPE_SEMAPHORE)
I think this could hide bugs, should we wrap it into a if(WARN_ON())?
> + return NULL;
> +
> + if (fence)
> + dma_fence_get(fence);
> +
> + mutex_lock(&sync_file->lock);
> +
> + ret_fence = sync_file_get_fence_locked(sync_file);
> + if (ret_fence) {
> + if (test_bit(POLL_ENABLED, &ret_fence->flags))
> + dma_fence_remove_callback(ret_fence, &sync_file->cb);
> + }
> +
> + RCU_INIT_POINTER(sync_file->fence, fence);
> +
> + mutex_unlock(&sync_file->lock);
> + return ret_fence;
> +}
> +EXPORT_SYMBOL(sync_file_replace_fence);
> +
> static int sync_file_set_fence(struct sync_file *sync_file,
> struct dma_fence **fences, int num_fences)
> {
> @@ -278,6 +310,8 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
>
> if (a->type != b->type)
> return NULL;
> + if (a->type != SYNC_FILE_TYPE_FENCE)
> + return NULL;
>
> if (!rcu_access_pointer(a->fence) ||
> !rcu_access_pointer(b->fence))
> diff --git a/include/linux/sync_file.h b/include/linux/sync_file.h
> index 4bf661b..245c7da 100644
> --- a/include/linux/sync_file.h
> +++ b/include/linux/sync_file.h
> @@ -62,4 +62,6 @@ struct sync_file *sync_file_alloc(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);
> struct sync_file *sync_file_fdget(int fd);
> +struct dma_fence *sync_file_replace_fence(struct sync_file *sync_file,
> + struct dma_fence *fence);
> #endif /* _LINUX_SYNC_H */
> diff --git a/include/uapi/linux/sync_file.h b/include/uapi/linux/sync_file.h
> index f439cda..5f266e0 100644
> --- a/include/uapi/linux/sync_file.h
> +++ b/include/uapi/linux/sync_file.h
> @@ -80,6 +80,20 @@ struct sync_file_info {
> #define SYNC_FILE_TYPE_FENCE 0
>
> /**
> + * DOC: SYNC_FILE_TYPE_SEMAPHORE - semaphore sync file object
Iirc you don't need the DOC: - kerneldoc should pick up #defines as-is.
You can iirc reference them from within kernel-doc using %DEFINED_THING.
> + *
> + * This is a sync file that operates like a Vulkan semaphore.
> + * The object should just be imported/exported but not use the
> + * sync file ioctls (except info).
> + * This object can have it's backing fence replaced multiple times.
> + * Each signal operation assigns a backing fence.
> + * Each wait operation waits on the current fence, and removes it.
> + * These operations should happen via driver command submission interfaces.
> + * This is useful for shared vulkan semaphores.
> + */
> +#define SYNC_FILE_TYPE_SEMAPHORE 1
> +
> +/**
> * struct sync_file_type - data returned from sync file type ioctl
> * @type: sync_file type
> * @flags: sync_file creation flags
> --
> 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