This patch only brings the syncobj documentation up-to-date for the original form of syncobj. It does not contain any information about the design of timeline syncobjs. --- drivers/gpu/drm/drm_syncobj.c | 81 +++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 1438dcb3ebb1..03cc888744fb 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -29,17 +29,82 @@ /** * DOC: Overview * - * DRM synchronisation objects (syncobj, see struct &drm_syncobj) are - * persistent objects that contain an optional fence. The fence can be updated - * with a new fence, or be NULL. + * DRM synchronisation objects (syncobj, see struct &drm_syncobj) provide a + * synchronization primitive which can be used by userspace to explicitly + * synchronize GPU commands, can be shared between userspace processes, and + * can be shared between different DRM drivers. + * Their primary use-case is to implement Vulkan fences and semaphores. + * The syncobj userspace API provides ioctls for several operations: * - * syncobj's can be waited upon, where it will wait for the underlying - * fence. + * - Creation and destruction of syncobjs + * - Import and export of syncobjs to/from a syncobj file descriptor + * - Import and export a syncobj's underlying fence to/from a sync file + * - Reset a syncobj (set its fence to NULL) + * - Signal a syncobj (set a trivially signaled fence) + * - Wait a syncobj's fence to be signaled * - * syncobj's can be export to fd's and back, these fd's are opaque and - * have no other use case, except passing the syncobj between processes. + * At it's core, a syncobj simply a wrapper around a pointer to a struct + * &dma_fence which may be NULL. + * When GPU work which signals a syncobj is enqueued in a DRM driver, + * the syncobj fence is replaced with a fence which will be signaled by the + * completion of that work. + * When GPU work which waits on a syncobj is enqueued in a DRM driver, the + * driver retrieves syncobj's current fence at the time the work is enqueued + * waits on that fence before submitting the work to hardware. + * If the syncobj's fence is NULL, the enqueue operation is expected to fail. + * All manipulation of the syncobjs's fence happens in terms of the current + * fence at the time the ioctl is called by userspace regardless of whether + * that operation is an immediate host-side operation (signal or reset) or + * or an operation which is enqueued in some driver queue. * - * Their primary use-case is to implement Vulkan fences and semaphores. + * + * Host-side wait on syncobjs + * -------------------------- + * + * The userspace syncobj API provides an ioctl for waiting on a set of + * syncobjs. + * The wait ioctl takes an array of syncobj handles and a flag indicating + * whether it should return immediately once one syncobj has been signaled + * or if it should wait for all the syncobjs to be signaled. + * Unlike the enqueued GPU work dependencies, the host-side wait ioctl + * will also optionally wait for the syncobj to first receive a fence and + * then wait on that fence. + * Assuming the syncobj starts off with a NULL fence, this allows a client + * to do a host wait in one thread (or process) which waits on GPU work + * submitted in another thread (or process) without having to manually + * synchronize between the two. + * This requirement is inherited from the Vulkan fence API. + * + * + * Import/export of syncobjs + * ------------------------- + * + * The userspace syncobj API provides two mechanisms for import/export of + * syncobjs. + * + * The first lets the client import or export an entire syncobj to a file + * descriptor. + * These fd's are opaque and have no other use case, except passing the + * syncobj between processes. + * All syncobj handles which are created as the result of such an import + * operation refer to the same underlying syncobj as was used for the + * export and the syncobj can be used persistently across all the processes + * with which it is shared. + * Unlike dma-buf, importing a syncobj creates a new handle for every + * import instead of de-duplicating. + * The primary use-case of this persistent import/export is for shared + * Vulkan fences and semaphores. + * + * The second import/export mechanism lets the client export the syncobj's + * current fence to/from a &sync_file. + * When a syncobj is exported to a sync file, that sync file wraps the + * sycnobj's fence at the time of export and any later signal or reset + * operations on the syncobj will not affect the exported sync file. + * When a sync file is imported into a syncobj, the syncobj's fence is set + * to the fence wrapped by that sync file. + * Because sync files are immutable, resetting or signaling the syncobj + * will not affect any sync files whose fences have been imported into the + * syncobj. * * syncobj have a kref reference count, but also have an optional file. * The file is only created once the syncobj is exported.
Thanks a lot for writing this :) I now have a canvas to add stuff on!
Just a couple of questions below.
-Lionel
On 02/08/2019 20:40, Jason Ekstrand wrote:
This patch only brings the syncobj documentation up-to-date for the original form of syncobj. It does not contain any information about the design of timeline syncobjs.
drivers/gpu/drm/drm_syncobj.c | 81 +++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 1438dcb3ebb1..03cc888744fb 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -29,17 +29,82 @@ /**
- DOC: Overview
- DRM synchronisation objects (syncobj, see struct &drm_syncobj) are
- persistent objects that contain an optional fence. The fence can be updated
- with a new fence, or be NULL.
- DRM synchronisation objects (syncobj, see struct &drm_syncobj) provide a
- synchronization primitive which can be used by userspace to explicitly
- synchronize GPU commands, can be shared between userspace processes, and
- can be shared between different DRM drivers.
I've been wondering whether we should call it a container for a synchronization primitive rather than a primitive itself.
Sync files are also a container, just we fewer features (no host operations).
It's not really important :)
- Their primary use-case is to implement Vulkan fences and semaphores.
- The syncobj userspace API provides ioctls for several operations:
- syncobj's can be waited upon, where it will wait for the underlying
- fence.
- Creation and destruction of syncobjs
- Import and export of syncobjs to/from a syncobj file descriptor
- Import and export a syncobj's underlying fence to/from a sync file
- Reset a syncobj (set its fence to NULL)
- Signal a syncobj (set a trivially signaled fence)
- Wait a syncobj's fence to be signaled
- syncobj's can be export to fd's and back, these fd's are opaque and
- have no other use case, except passing the syncobj between processes.
- At it's core, a syncobj simply a wrapper around a pointer to a struct
- &dma_fence which may be NULL.
- When GPU work which signals a syncobj is enqueued in a DRM driver,
- the syncobj fence is replaced with a fence which will be signaled by the
- completion of that work.
- When GPU work which waits on a syncobj is enqueued in a DRM driver, the
- driver retrieves syncobj's current fence at the time the work is enqueued
- waits on that fence before submitting the work to hardware.
- If the syncobj's fence is NULL, the enqueue operation is expected to fail.
- All manipulation of the syncobjs's fence happens in terms of the current
- fence at the time the ioctl is called by userspace regardless of whether
- that operation is an immediate host-side operation (signal or reset) or
- or an operation which is enqueued in some driver queue.
- Their primary use-case is to implement Vulkan fences and semaphores.
Maybe add a line about creation (and its signaled flag)?
- Host-side wait on syncobjs
- The userspace syncobj API provides an ioctl for waiting on a set of
- syncobjs.
- The wait ioctl takes an array of syncobj handles and a flag indicating
- whether it should return immediately once one syncobj has been signaled
- or if it should wait for all the syncobjs to be signaled.
- Unlike the enqueued GPU work dependencies, the host-side wait ioctl
- will also optionally wait for the syncobj to first receive a fence and
- then wait on that fence.
- Assuming the syncobj starts off with a NULL fence, this allows a client
- to do a host wait in one thread (or process) which waits on GPU work
- submitted in another thread (or process) without having to manually
- synchronize between the two.
- This requirement is inherited from the Vulkan fence API.
Should we list the flags & ioctl names?
- Import/export of syncobjs
- The userspace syncobj API provides two mechanisms for import/export of
- syncobjs.
- The first lets the client import or export an entire syncobj to a file
- descriptor.
- These fd's are opaque and have no other use case, except passing the
- syncobj between processes.
- All syncobj handles which are created as the result of such an import
- operation refer to the same underlying syncobj as was used for the
- export and the syncobj can be used persistently across all the processes
- with which it is shared.
- Unlike dma-buf, importing a syncobj creates a new handle for every
- import instead of de-duplicating.
- The primary use-case of this persistent import/export is for shared
- Vulkan fences and semaphores.
- The second import/export mechanism lets the client export the syncobj's
- current fence to/from a &sync_file.
- When a syncobj is exported to a sync file, that sync file wraps the
- sycnobj's fence at the time of export and any later signal or reset
- operations on the syncobj will not affect the exported sync file.
- When a sync file is imported into a syncobj, the syncobj's fence is set
- to the fence wrapped by that sync file.
- Because sync files are immutable, resetting or signaling the syncobj
- will not affect any sync files whose fences have been imported into the
- syncobj.
This 3 lines below seem to be redundant now?
Maybe rephrase with something like :
"Sharing a syncobj increases its refcount. The syncobj is destroyed when a client release the last reference."
- syncobj have a kref reference count, but also have an optional file.
- The file is only created once the syncobj is exported.
On Sat, Aug 3, 2019 at 3:19 AM Lionel Landwerlin < lionel.g.landwerlin@intel.com> wrote:
Thanks a lot for writing this :) I now have a canvas to add stuff on!
Just a couple of questions below.
-Lionel
On 02/08/2019 20:40, Jason Ekstrand wrote:
This patch only brings the syncobj documentation up-to-date for the original form of syncobj. It does not contain any information about the design of timeline syncobjs.
drivers/gpu/drm/drm_syncobj.c | 81 +++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/drm_syncobj.c
b/drivers/gpu/drm/drm_syncobj.c
index 1438dcb3ebb1..03cc888744fb 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -29,17 +29,82 @@ /**
- DOC: Overview
- DRM synchronisation objects (syncobj, see struct &drm_syncobj) are
- persistent objects that contain an optional fence. The fence can be
updated
- with a new fence, or be NULL.
- DRM synchronisation objects (syncobj, see struct &drm_syncobj)
provide a
- synchronization primitive which can be used by userspace to
explicitly
- synchronize GPU commands, can be shared between userspace processes,
and
- can be shared between different DRM drivers.
I've been wondering whether we should call it a container for a synchronization primitive rather than a primitive itself.
Sync files are also a container, just we fewer features (no host operations).
It's not really important :)
That's a fun philosophical question and I think the answer entirely depends on which side of the ioctl you're on. :-)
- Their primary use-case is to implement Vulkan fences and semaphores.
- The syncobj userspace API provides ioctls for several operations:
- syncobj's can be waited upon, where it will wait for the underlying
- fence.
- Creation and destruction of syncobjs
- Import and export of syncobjs to/from a syncobj file descriptor
- Import and export a syncobj's underlying fence to/from a sync file
- Reset a syncobj (set its fence to NULL)
- Signal a syncobj (set a trivially signaled fence)
- Wait a syncobj's fence to be signaled
- syncobj's can be export to fd's and back, these fd's are opaque and
- have no other use case, except passing the syncobj between processes.
- At it's core, a syncobj simply a wrapper around a pointer to a struct
- &dma_fence which may be NULL.
- When GPU work which signals a syncobj is enqueued in a DRM driver,
- the syncobj fence is replaced with a fence which will be signaled by
the
- completion of that work.
- When GPU work which waits on a syncobj is enqueued in a DRM driver,
the
- driver retrieves syncobj's current fence at the time the work is
enqueued
- waits on that fence before submitting the work to hardware.
- If the syncobj's fence is NULL, the enqueue operation is expected to
fail.
- All manipulation of the syncobjs's fence happens in terms of the
current
- fence at the time the ioctl is called by userspace regardless of
whether
- that operation is an immediate host-side operation (signal or reset)
or
- or an operation which is enqueued in some driver queue.
- Their primary use-case is to implement Vulkan fences and semaphores.
Maybe add a line about creation (and its signaled flag)?
Sure, I'll also make a comment about reset and signal.
- Host-side wait on syncobjs
- The userspace syncobj API provides an ioctl for waiting on a set of
- syncobjs.
- The wait ioctl takes an array of syncobj handles and a flag
indicating
- whether it should return immediately once one syncobj has been
signaled
- or if it should wait for all the syncobjs to be signaled.
- Unlike the enqueued GPU work dependencies, the host-side wait ioctl
- will also optionally wait for the syncobj to first receive a fence
and
- then wait on that fence.
- Assuming the syncobj starts off with a NULL fence, this allows a
client
- to do a host wait in one thread (or process) which waits on GPU work
- submitted in another thread (or process) without having to manually
- synchronize between the two.
- This requirement is inherited from the Vulkan fence API.
Should we list the flags & ioctl names?
I don't know. Maybe Dave or Daniel can tell me how these things are usually done?
- Import/export of syncobjs
- The userspace syncobj API provides two mechanisms for import/export
of
- syncobjs.
- The first lets the client import or export an entire syncobj to a
file
- descriptor.
- These fd's are opaque and have no other use case, except passing the
- syncobj between processes.
- All syncobj handles which are created as the result of such an import
- operation refer to the same underlying syncobj as was used for the
- export and the syncobj can be used persistently across all the
processes
- with which it is shared.
- Unlike dma-buf, importing a syncobj creates a new handle for every
- import instead of de-duplicating.
- The primary use-case of this persistent import/export is for shared
- Vulkan fences and semaphores.
- The second import/export mechanism lets the client export the
syncobj's
- current fence to/from a &sync_file.
- When a syncobj is exported to a sync file, that sync file wraps the
- sycnobj's fence at the time of export and any later signal or reset
- operations on the syncobj will not affect the exported sync file.
- When a sync file is imported into a syncobj, the syncobj's fence is
set
- to the fence wrapped by that sync file.
- Because sync files are immutable, resetting or signaling the syncobj
- will not affect any sync files whose fences have been imported into
the
- syncobj.
This 3 lines below seem to be redundant now?
Which three lines are you referring to? The thing about krefs? I agree that it feels a bit odd with the rest of the documentation because it's a very internal detail and the rest of what I've written is an overview. Maybe the bit about krefs should go in the top section and the bit about the file should stay here?
Maybe rephrase with something like :
"Sharing a syncobj increases its refcount. The syncobj is destroyed when a client release the last reference."
I don't think we need to describe how reference counting works.
- syncobj have a kref reference count, but also have an optional file.
- The file is only created once the syncobj is exported.
I somehow totally missed that patch, looks like it maybe ended up in the spam folder.
Am 05.08.19 um 19:01 schrieb Jason Ekstrand:
On Sat, Aug 3, 2019 at 3:19 AM Lionel Landwerlin <lionel.g.landwerlin@intel.commailto:lionel.g.landwerlin@intel.com> wrote: Thanks a lot for writing this :) I now have a canvas to add stuff on!
Just a couple of questions below.
-Lionel
On 02/08/2019 20:40, Jason Ekstrand wrote:
This patch only brings the syncobj documentation up-to-date for the original form of syncobj. It does not contain any information about the design of timeline syncobjs.
drivers/gpu/drm/drm_syncobj.c | 81 +++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 1438dcb3ebb1..03cc888744fb 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -29,17 +29,82 @@ /**
- DOC: Overview
- DRM synchronisation objects (syncobj, see struct &drm_syncobj) are
- persistent objects that contain an optional fence. The fence can be updated
- with a new fence, or be NULL.
- DRM synchronisation objects (syncobj, see struct &drm_syncobj) provide a
- synchronization primitive which can be used by userspace to explicitly
- synchronize GPU commands, can be shared between userspace processes, and
- can be shared between different DRM drivers.
I've been wondering whether we should call it a container for a synchronization primitive rather than a primitive itself.
Sync files are also a container, just we fewer features (no host operations).
It's not really important :)
That's a fun philosophical question and I think the answer entirely depends on which side of the ioctl you're on. :-)
Yeah, but this is kernel documentation, not userspace documentation. So I agree that syncobjs are just a container inside the kernel.
- Their primary use-case is to implement Vulkan fences and semaphores.
- The syncobj userspace API provides ioctls for several operations:
- syncobj's can be waited upon, where it will wait for the underlying
- fence.
- Creation and destruction of syncobjs
- Import and export of syncobjs to/from a syncobj file descriptor
- Import and export a syncobj's underlying fence to/from a sync file
- Reset a syncobj (set its fence to NULL)
- Signal a syncobj (set a trivially signaled fence)
- Wait a syncobj's fence to be signaled
Wait for a fence to appear.
- syncobj's can be export to fd's and back, these fd's are opaque and
- have no other use case, except passing the syncobj between processes.
- At it's core, a syncobj simply a wrapper around a pointer to a struct
- &dma_fence which may be NULL.
- When GPU work which signals a syncobj is enqueued in a DRM driver,
- the syncobj fence is replaced with a fence which will be signaled by the
- completion of that work.
- When GPU work which waits on a syncobj is enqueued in a DRM driver, the
- driver retrieves syncobj's current fence at the time the work is enqueued
- waits on that fence before submitting the work to hardware.
- If the syncobj's fence is NULL, the enqueue operation is expected to fail.
- All manipulation of the syncobjs's fence happens in terms of the current
- fence at the time the ioctl is called by userspace regardless of whether
- that operation is an immediate host-side operation (signal or reset) or
- or an operation which is enqueued in some driver queue.
- Their primary use-case is to implement Vulkan fences and semaphores.
Maybe add a line about creation (and its signaled flag)?
Sure, I'll also make a comment about reset and signal.
- Host-side wait on syncobjs
- The userspace syncobj API provides an ioctl for waiting on a set of
- syncobjs.
- The wait ioctl takes an array of syncobj handles and a flag indicating
- whether it should return immediately once one syncobj has been signaled
- or if it should wait for all the syncobjs to be signaled.
- Unlike the enqueued GPU work dependencies, the host-side wait ioctl
- will also optionally wait for the syncobj to first receive a fence and
- then wait on that fence.
- Assuming the syncobj starts off with a NULL fence, this allows a client
- to do a host wait in one thread (or process) which waits on GPU work
- submitted in another thread (or process) without having to manually
- synchronize between the two.
- This requirement is inherited from the Vulkan fence API.
Should we list the flags & ioctl names?
I don't know. Maybe Dave or Daniel can tell me how these things are usually done?
You could & reference the enum/defines of the IOCTL numbers in the first sentence or something like this.
- Import/export of syncobjs
- The userspace syncobj API provides two mechanisms for import/export of
- syncobjs.
- The first lets the client import or export an entire syncobj to a file
- descriptor.
- These fd's are opaque and have no other use case, except passing the
- syncobj between processes.
- All syncobj handles which are created as the result of such an import
- operation refer to the same underlying syncobj as was used for the
- export and the syncobj can be used persistently across all the processes
- with which it is shared.
- Unlike dma-buf, importing a syncobj creates a new handle for every
- import instead of de-duplicating.
- The primary use-case of this persistent import/export is for shared
- Vulkan fences and semaphores.
- The second import/export mechanism lets the client export the syncobj's
- current fence to/from a &sync_file.
- When a syncobj is exported to a sync file, that sync file wraps the
- sycnobj's fence at the time of export and any later signal or reset
- operations on the syncobj will not affect the exported sync file.
- When a sync file is imported into a syncobj, the syncobj's fence is set
- to the fence wrapped by that sync file.
- Because sync files are immutable, resetting or signaling the syncobj
- will not affect any sync files whose fences have been imported into the
- syncobj.
This 3 lines below seem to be redundant now?
Which three lines are you referring to? The thing about krefs? I agree that it feels a bit odd with the rest of the documentation because it's a very internal detail and the rest of what I've written is an overview. Maybe the bit about krefs should go in the top section and the bit about the file should stay here?
Maybe rephrase with something like :
"Sharing a syncobj increases its refcount. The syncobj is destroyed when a client release the last reference."
I don't think we need to describe how reference counting works.
Agreed, we should just mention that things are referenced instead of copied. How this referencing works is out of scope here.
- syncobj have a kref reference count, but also have an optional file.
- The file is only created once the syncobj is exported.
To much detail.
Regards, Christian.
This patch only brings the syncobj documentation up-to-date for the original form of syncobj. It does not contain any information about the design of timeline syncobjs.
v2: Incorporate feedback from Lionel and Christian: - Mention actual ioctl and flag names - Better language around reference counting - Misc. language cleanups
Signed-off-by: Jason Ekstrand jason@jlekstrand.net --- drivers/gpu/drm/drm_syncobj.c | 98 +++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 1438dcb3ebb1..4b5c7b0ed714 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -29,21 +29,97 @@ /** * DOC: Overview * - * DRM synchronisation objects (syncobj, see struct &drm_syncobj) are - * persistent objects that contain an optional fence. The fence can be updated - * with a new fence, or be NULL. + * DRM synchronisation objects (syncobj, see struct &drm_syncobj) provide a + * container for a synchronization primitive which can be used by userspace + * to explicitly synchronize GPU commands, can be shared between userspace + * processes, and can be shared between different DRM drivers. + * Their primary use-case is to implement Vulkan fences and semaphores. + * The syncobj userspace API provides ioctls for several operations: * - * syncobj's can be waited upon, where it will wait for the underlying - * fence. + * - Creation and destruction of syncobjs + * - Import and export of syncobjs to/from a syncobj file descriptor + * - Import and export a syncobj's underlying fence to/from a sync file + * - Reset a syncobj (set its fence to NULL) + * - Signal a syncobj (set a trivially signaled fence) + * - Wait for a syncobj's fence to appear and be signaled * - * syncobj's can be export to fd's and back, these fd's are opaque and - * have no other use case, except passing the syncobj between processes. + * At it's core, a syncobj is simply a wrapper around a pointer to a struct + * &dma_fence which may be NULL. + * When a syncobj is first created, its pointer is either NULL or a pointer + * to an already signaled fence depending on whether the + * &DRM_SYNCOBJ_CREATE_SIGNALED flag is passed to + * &DRM_IOCTL_SYNCOBJ_CREATE. + * When GPU work which signals a syncobj is enqueued in a DRM driver, + * the syncobj fence is replaced with a fence which will be signaled by the + * completion of that work. + * When GPU work which waits on a syncobj is enqueued in a DRM driver, the + * driver retrieves syncobj's current fence at the time the work is enqueued + * waits on that fence before submitting the work to hardware. + * If the syncobj's fence is NULL, the enqueue operation is expected to fail. + * All manipulation of the syncobjs's fence happens in terms of the current + * fence at the time the ioctl is called by userspace regardless of whether + * that operation is an immediate host-side operation (signal or reset) or + * or an operation which is enqueued in some driver queue. + * &DRM_IOCTL_SYNCOBJ_RESET and &DRM_IOCTL_SYNCOBJ_SIGNAL can be used to + * manipulate a syncobj from the host by resetting its pointer to NULL or + * setting its pointer to a fence which is already signaled. * - * Their primary use-case is to implement Vulkan fences and semaphores. * - * syncobj have a kref reference count, but also have an optional file. - * The file is only created once the syncobj is exported. - * The file takes a reference on the kref. + * Host-side wait on syncobjs + * -------------------------- + * + * &DRM_IOCTL_SYNCOBJ_WAIT takes an array of syncobj handles and does a + * host-side wait on all of the syncobj fences simultaneously. + * If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL is set, the wait ioctl will wait on + * all of the syncobj fences to be signaled before it returns. + * Otherwise, it returns once at least one syncobj fence has been signaled + * and the index of a signaled fence is written back to the client. + * + * Unlike the enqueued GPU work dependencies which fail if they see a NULL + * fence in a syncobj, if &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is set, + * the host-side wait will first wait for the syncobj to receive a non-NULL + * fence and then wait on that fence. + * If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is not set and any one of the + * syncobjs in the array has a NULL fence, -EINVAL will be returned. + * Assuming the syncobj starts off with a NULL fence, this allows a client + * to do a host wait in one thread (or process) which waits on GPU work + * submitted in another thread (or process) without having to manually + * synchronize between the two. + * This requirement is inherited from the Vulkan fence API. + * + * + * Import/export of syncobjs + * ------------------------- + * + * &DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE and &DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD + * provide two mechanisms for import/export of syncobjs. + * + * The first lets the client import or export an entire syncobj to a file + * descriptor. + * These fd's are opaque and have no other use case, except passing the + * syncobj between processes. + * All exported file descriptors and any syncobj handles created as a + * result of importing those file descriptors own a reference to the + * same underlying struct &drm_syncobj and the syncobj can be used + * persistently across all the processes with which it is shared. + * The syncobj is freed only once the last reference is dropped. + * Unlike dma-buf, importing a syncobj creates a new handle (with its own + * reference) for every import instead of de-duplicating. + * The primary use-case of this persistent import/export is for shared + * Vulkan fences and semaphores. + * + * The second import/export mechanism, which is indicated by + * &DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE or + * &DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE lets the client + * import/export the syncobj's current fence from/to a &sync_file. + * When a syncobj is exported to a sync file, that sync file wraps the + * sycnobj's fence at the time of export and any later signal or reset + * operations on the syncobj will not affect the exported sync file. + * When a sync file is imported into a syncobj, the syncobj's fence is set + * to the fence wrapped by that sync file. + * Because sync files are immutable, resetting or signaling the syncobj + * will not affect any sync files whose fences have been imported into the + * syncobj. */
#include <linux/anon_inodes.h>
On 06/08/2019 19:19, Jason Ekstrand wrote:
This patch only brings the syncobj documentation up-to-date for the original form of syncobj. It does not contain any information about the design of timeline syncobjs.
v2: Incorporate feedback from Lionel and Christian:
- Mention actual ioctl and flag names
- Better language around reference counting
- Misc. language cleanups
Signed-off-by: Jason Ekstrand jason@jlekstrand.net
Reviewed-by: Lionel Landwerlin lionel.g.landwerlin@intel.com
drivers/gpu/drm/drm_syncobj.c | 98 +++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 1438dcb3ebb1..4b5c7b0ed714 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -29,21 +29,97 @@ /**
- DOC: Overview
- DRM synchronisation objects (syncobj, see struct &drm_syncobj) are
- persistent objects that contain an optional fence. The fence can be updated
- with a new fence, or be NULL.
- DRM synchronisation objects (syncobj, see struct &drm_syncobj) provide a
- container for a synchronization primitive which can be used by userspace
- to explicitly synchronize GPU commands, can be shared between userspace
- processes, and can be shared between different DRM drivers.
- Their primary use-case is to implement Vulkan fences and semaphores.
- The syncobj userspace API provides ioctls for several operations:
- syncobj's can be waited upon, where it will wait for the underlying
- fence.
- Creation and destruction of syncobjs
- Import and export of syncobjs to/from a syncobj file descriptor
- Import and export a syncobj's underlying fence to/from a sync file
- Reset a syncobj (set its fence to NULL)
- Signal a syncobj (set a trivially signaled fence)
- Wait for a syncobj's fence to appear and be signaled
- syncobj's can be export to fd's and back, these fd's are opaque and
- have no other use case, except passing the syncobj between processes.
- At it's core, a syncobj is simply a wrapper around a pointer to a struct
- &dma_fence which may be NULL.
- When a syncobj is first created, its pointer is either NULL or a pointer
- to an already signaled fence depending on whether the
- &DRM_SYNCOBJ_CREATE_SIGNALED flag is passed to
- &DRM_IOCTL_SYNCOBJ_CREATE.
- When GPU work which signals a syncobj is enqueued in a DRM driver,
- the syncobj fence is replaced with a fence which will be signaled by the
- completion of that work.
- When GPU work which waits on a syncobj is enqueued in a DRM driver, the
- driver retrieves syncobj's current fence at the time the work is enqueued
- waits on that fence before submitting the work to hardware.
- If the syncobj's fence is NULL, the enqueue operation is expected to fail.
- All manipulation of the syncobjs's fence happens in terms of the current
- fence at the time the ioctl is called by userspace regardless of whether
- that operation is an immediate host-side operation (signal or reset) or
- or an operation which is enqueued in some driver queue.
- &DRM_IOCTL_SYNCOBJ_RESET and &DRM_IOCTL_SYNCOBJ_SIGNAL can be used to
- manipulate a syncobj from the host by resetting its pointer to NULL or
- setting its pointer to a fence which is already signaled.
- Their primary use-case is to implement Vulkan fences and semaphores.
- syncobj have a kref reference count, but also have an optional file.
- The file is only created once the syncobj is exported.
- The file takes a reference on the kref.
- Host-side wait on syncobjs
- &DRM_IOCTL_SYNCOBJ_WAIT takes an array of syncobj handles and does a
- host-side wait on all of the syncobj fences simultaneously.
- If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL is set, the wait ioctl will wait on
- all of the syncobj fences to be signaled before it returns.
- Otherwise, it returns once at least one syncobj fence has been signaled
- and the index of a signaled fence is written back to the client.
- Unlike the enqueued GPU work dependencies which fail if they see a NULL
- fence in a syncobj, if &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is set,
- the host-side wait will first wait for the syncobj to receive a non-NULL
- fence and then wait on that fence.
- If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is not set and any one of the
- syncobjs in the array has a NULL fence, -EINVAL will be returned.
- Assuming the syncobj starts off with a NULL fence, this allows a client
- to do a host wait in one thread (or process) which waits on GPU work
- submitted in another thread (or process) without having to manually
- synchronize between the two.
- This requirement is inherited from the Vulkan fence API.
- Import/export of syncobjs
- &DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE and &DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD
- provide two mechanisms for import/export of syncobjs.
- The first lets the client import or export an entire syncobj to a file
- descriptor.
- These fd's are opaque and have no other use case, except passing the
- syncobj between processes.
- All exported file descriptors and any syncobj handles created as a
- result of importing those file descriptors own a reference to the
- same underlying struct &drm_syncobj and the syncobj can be used
- persistently across all the processes with which it is shared.
- The syncobj is freed only once the last reference is dropped.
- Unlike dma-buf, importing a syncobj creates a new handle (with its own
- reference) for every import instead of de-duplicating.
- The primary use-case of this persistent import/export is for shared
- Vulkan fences and semaphores.
- The second import/export mechanism, which is indicated by
- &DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE or
- &DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE lets the client
- import/export the syncobj's current fence from/to a &sync_file.
- When a syncobj is exported to a sync file, that sync file wraps the
- sycnobj's fence at the time of export and any later signal or reset
- operations on the syncobj will not affect the exported sync file.
- When a sync file is imported into a syncobj, the syncobj's fence is set
- to the fence wrapped by that sync file.
- Because sync files are immutable, resetting or signaling the syncobj
- will not affect any sync files whose fences have been imported into the
- syncobj.
*/
#include <linux/anon_inodes.h>
Christan, any thoughts on v2?
--Jason
On August 7, 2019 09:06:47 Lionel Landwerlin lionel.g.landwerlin@intel.com wrote:
On 06/08/2019 19:19, Jason Ekstrand wrote:
This patch only brings the syncobj documentation up-to-date for the original form of syncobj. It does not contain any information about the design of timeline syncobjs.
v2: Incorporate feedback from Lionel and Christian:
- Mention actual ioctl and flag names
- Better language around reference counting
- Misc. language cleanups
Signed-off-by: Jason Ekstrand jason@jlekstrand.net
Reviewed-by: Lionel Landwerlin lionel.g.landwerlin@intel.com
drivers/gpu/drm/drm_syncobj.c | 98 +++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 1438dcb3ebb1..4b5c7b0ed714 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -29,21 +29,97 @@ /**
- DOC: Overview
- DRM synchronisation objects (syncobj, see struct &drm_syncobj) are
- persistent objects that contain an optional fence. The fence can be updated
- with a new fence, or be NULL.
- DRM synchronisation objects (syncobj, see struct &drm_syncobj) provide a
- container for a synchronization primitive which can be used by userspace
- to explicitly synchronize GPU commands, can be shared between userspace
- processes, and can be shared between different DRM drivers.
- Their primary use-case is to implement Vulkan fences and semaphores.
- The syncobj userspace API provides ioctls for several operations:
- syncobj's can be waited upon, where it will wait for the underlying
- fence.
- Creation and destruction of syncobjs
- Import and export of syncobjs to/from a syncobj file descriptor
- Import and export a syncobj's underlying fence to/from a sync file
- Reset a syncobj (set its fence to NULL)
- Signal a syncobj (set a trivially signaled fence)
- Wait for a syncobj's fence to appear and be signaled
- syncobj's can be export to fd's and back, these fd's are opaque and
- have no other use case, except passing the syncobj between processes.
- At it's core, a syncobj is simply a wrapper around a pointer to a struct
- &dma_fence which may be NULL.
- When a syncobj is first created, its pointer is either NULL or a pointer
- to an already signaled fence depending on whether the
- &DRM_SYNCOBJ_CREATE_SIGNALED flag is passed to
- &DRM_IOCTL_SYNCOBJ_CREATE.
- When GPU work which signals a syncobj is enqueued in a DRM driver,
- the syncobj fence is replaced with a fence which will be signaled by the
- completion of that work.
- When GPU work which waits on a syncobj is enqueued in a DRM driver, the
- driver retrieves syncobj's current fence at the time the work is enqueued
- waits on that fence before submitting the work to hardware.
- If the syncobj's fence is NULL, the enqueue operation is expected to fail.
- All manipulation of the syncobjs's fence happens in terms of the current
- fence at the time the ioctl is called by userspace regardless of whether
- that operation is an immediate host-side operation (signal or reset) or
- or an operation which is enqueued in some driver queue.
- &DRM_IOCTL_SYNCOBJ_RESET and &DRM_IOCTL_SYNCOBJ_SIGNAL can be used to
- manipulate a syncobj from the host by resetting its pointer to NULL or
- setting its pointer to a fence which is already signaled.
- Their primary use-case is to implement Vulkan fences and semaphores.
- syncobj have a kref reference count, but also have an optional file.
- The file is only created once the syncobj is exported.
- The file takes a reference on the kref.
- Host-side wait on syncobjs
- &DRM_IOCTL_SYNCOBJ_WAIT takes an array of syncobj handles and does a
- host-side wait on all of the syncobj fences simultaneously.
- If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL is set, the wait ioctl will wait on
- all of the syncobj fences to be signaled before it returns.
- Otherwise, it returns once at least one syncobj fence has been signaled
- and the index of a signaled fence is written back to the client.
- Unlike the enqueued GPU work dependencies which fail if they see a NULL
- fence in a syncobj, if &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is set,
- the host-side wait will first wait for the syncobj to receive a non-NULL
- fence and then wait on that fence.
- If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is not set and any one of the
- syncobjs in the array has a NULL fence, -EINVAL will be returned.
- Assuming the syncobj starts off with a NULL fence, this allows a client
- to do a host wait in one thread (or process) which waits on GPU work
- submitted in another thread (or process) without having to manually
- synchronize between the two.
- This requirement is inherited from the Vulkan fence API.
- Import/export of syncobjs
- &DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE and &DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD
- provide two mechanisms for import/export of syncobjs.
- The first lets the client import or export an entire syncobj to a file
- descriptor.
- These fd's are opaque and have no other use case, except passing the
- syncobj between processes.
- All exported file descriptors and any syncobj handles created as a
- result of importing those file descriptors own a reference to the
- same underlying struct &drm_syncobj and the syncobj can be used
- persistently across all the processes with which it is shared.
- The syncobj is freed only once the last reference is dropped.
- Unlike dma-buf, importing a syncobj creates a new handle (with its own
- reference) for every import instead of de-duplicating.
- The primary use-case of this persistent import/export is for shared
- Vulkan fences and semaphores.
- The second import/export mechanism, which is indicated by
- &DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE or
- &DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE lets the client
- import/export the syncobj's current fence from/to a &sync_file.
- When a syncobj is exported to a sync file, that sync file wraps the
- sycnobj's fence at the time of export and any later signal or reset
- operations on the syncobj will not affect the exported sync file.
- When a sync file is imported into a syncobj, the syncobj's fence is set
- to the fence wrapped by that sync file.
- Because sync files are immutable, resetting or signaling the syncobj
- will not affect any sync files whose fences have been imported into the
- syncobj.
*/
#include <linux/anon_inodes.h>
Hi Jason,
this mail also somehow ended up to be rejected by our spam filter and I'm not sure why :(
Anyway, feel free to add my Acked-by. From the technical point I would give an r-b as well, but I'm not a native speaker of English.
Cheers, Christian.
Am 08.08.19 um 06:47 schrieb Jason Ekstrand:
Christan, any thoughts on v2?
--Jason
On August 7, 2019 09:06:47 Lionel Landwerlin lionel.g.landwerlin@intel.com wrote:
On 06/08/2019 19:19, Jason Ekstrand wrote:
This patch only brings the syncobj documentation up-to-date for the original form of syncobj. It does not contain any information about the design of timeline syncobjs.
v2: Incorporate feedback from Lionel and Christian: - Mention actual ioctl and flag names - Better language around reference counting - Misc. language cleanups
Signed-off-by: Jason Ekstrand jason@jlekstrand.net
Reviewed-by: Lionel Landwerlin lionel.g.landwerlin@intel.com
drivers/gpu/drm/drm_syncobj.c | 98 +++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 1438dcb3ebb1..4b5c7b0ed714 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -29,21 +29,97 @@ /** * DOC: Overview *
- DRM synchronisation objects (syncobj, see struct &drm_syncobj) are
- persistent objects that contain an optional fence. The Ok,fence
can be updated
- with a new fence, or be NULL.
- DRM synchronisation objects (syncobj, see struct &drm_syncobj)
provide a
- container for a synchronization primitive which can be used by
userspace
- to explicitly synchronize GPU commands, can be shared between
userspace
- processes, and can be shared between different DRM drivers.
- Their primary use-case is to implement Vulkan fences and
semaphores.
- The syncobj userspace API provides ioctls for several operations:
*
- syncobj's can be waited upon, where it will wait for the underlying
- fence.
- * - Creation and destruction of syncobjs
- * - Import and export of syncobjs to/from a syncobj file descriptor
- * - Import and export a syncobj's underlying fence to/from a sync
file
- * - Reset a syncobj (set its fence to NULL)
- * - Signal a syncobj (set a trivially signaled fence)
- * - Wait for a syncobj's fence to appear and be signaled
*
- syncobj's can be export to fd's and back, these fd's are opaque and
- have no other use case, except passing the syncobj between
processes.
- At it's core, a syncobj is simply a wrapper around a pointer to
a struct
- &dma_fence which may be NULL.
- When a syncobj is first created, its pointer is either NULL or a
pointer
- to an already signaled fence depending on whether the
- &DRM_SYNCOBJ_CREATE_SIGNALED flag is passed to
- &DRM_IOCTL_SYNCOBJ_CREATE.
- When GPU work which signals a syncobj is enqueued in a DRM driver,
- the syncobj fence is replaced with a fence which will be
signaled by the
- completion of that work.
- When GPU work which waits on a syncobj is enqueued in a DRM
driver, the
- driver retrieves syncobj's current fence at the time the work is
enqueued
- waits on that fence before submitting the work to hardware.
- If the syncobj's fence is NULL, the enqueue operation is
expected to fail.
- All manipulation of the syncobjs's fence happens in terms of the
current
- fence at the time the ioctl is called by userspace regardless of
whether
- that operation is an immediate host-side operation (signal or
reset) or
- or an operation which is enqueued in some driver queue.
- &DRM_IOCTL_SYNCOBJ_RESET and &DRM_IOCTL_SYNCOBJ_SIGNAL can be
used to
- manipulate a syncobj from the host by resetting its pointer to
NULL or
- setting its pointer to a fence which is already signaled.
*
- Their primary use-case is to implement Vulkan fences and
semaphores. *
- syncobj have a kref reference count, but also have an optional
file.
- The file is only created once the syncobj is exported.
- The file takes a reference on the kref.
- Host-side wait on syncobjs
- &DRM_IOCTL_SYNCOBJ_WAIT takes an array of syncobj handles and
does a
- host-side wait on all of the syncobj fences simultaneously.
- If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL is set, the wait ioctl will
wait on
- all of the syncobj fences to be signaled before it returns.
- Otherwise, it returns once at least one syncobj fence has been
signaled
- and the index of a signaled fence is written back to the client.
- Unlike the enqueued GPU work dependencies which fail if they see
a NULL
- fence in a syncobj, if &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT
is set,
- the host-side wait will first wait for the syncobj to receive a
non-NULL
- fence and then wait on that fence.
- If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is not set and any
one of the
- syncobjs in the array has a NULL fence, -EINVAL will be returned.
- Assuming the syncobj starts off with a NULL fence, this allows a
client
- to do a host wait in one thread (or process) which waits on GPU
work
- submitted in another thread (or process) without having to manually
- synchronize between the two.
- This requirement is inherited from the Vulkan fence API.
- Import/export of syncobjs
- &DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE and &DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD
- provide two mechanisms for import/export of syncobjs.
- The first lets the client import or export an entire syncobj to
a file
- descriptor.
- These fd's are opaque and have no other use case, except passing
the
- syncobj between processes.
- All exported file descriptors and any syncobj handles created as a
- result of importing those file descriptors own a reference to the
- same underlying struct &drm_syncobj and the syncobj can be used
- persistently across all the processes with which it is shared.
- The syncobj is freed only once the last reference is dropped.
- Unlike dma-buf, importing a syncobj creates a new handle (with
its own
- reference) for every import instead of de-duplicating.
- The primary use-case of this persistent import/export is for shared
- Vulkan fences and semaphores.
- The second import/export mechanism, which is indicated by
- &DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE or
- &DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE lets the client
- import/export the syncobj's current fence from/to a &sync_file.
- When a syncobj is exported to a sync file, that sync file wraps the
- sycnobj's fence at the time of export and any later signal or reset
- operations on the syncobj will not affect the exported sync file.
- When a sync file is imported into a syncobj, the syncobj's fence
is set
- to the fence wrapped by that sync file.
- Because sync files are immutable, resetting or signaling the
syncobj
- will not affect any sync files whose fences have been imported
into the
- syncobj.
*/
#include <linux/anon_inodes.h>
This patch only brings the syncobj documentation up-to-date for the original form of syncobj. It does not contain any information about the design of timeline syncobjs.
v2: Incorporate feedback from Lionel and Christian: - Mention actual ioctl and flag names - Better language around reference counting - Misc. language cleanups
Signed-off-by: Jason Ekstrand jason@jlekstrand.net Reviewed-by: Lionel Landwerlin lionel.g.landwerlin@intel.com Acked-by: Christian König christian.koenig@amd.com --- drivers/gpu/drm/drm_syncobj.c | 98 +++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 1438dcb3ebb1..4b5c7b0ed714 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -29,21 +29,97 @@ /** * DOC: Overview * - * DRM synchronisation objects (syncobj, see struct &drm_syncobj) are - * persistent objects that contain an optional fence. The fence can be updated - * with a new fence, or be NULL. + * DRM synchronisation objects (syncobj, see struct &drm_syncobj) provide a + * container for a synchronization primitive which can be used by userspace + * to explicitly synchronize GPU commands, can be shared between userspace + * processes, and can be shared between different DRM drivers. + * Their primary use-case is to implement Vulkan fences and semaphores. + * The syncobj userspace API provides ioctls for several operations: * - * syncobj's can be waited upon, where it will wait for the underlying - * fence. + * - Creation and destruction of syncobjs + * - Import and export of syncobjs to/from a syncobj file descriptor + * - Import and export a syncobj's underlying fence to/from a sync file + * - Reset a syncobj (set its fence to NULL) + * - Signal a syncobj (set a trivially signaled fence) + * - Wait for a syncobj's fence to appear and be signaled * - * syncobj's can be export to fd's and back, these fd's are opaque and - * have no other use case, except passing the syncobj between processes. + * At it's core, a syncobj is simply a wrapper around a pointer to a struct + * &dma_fence which may be NULL. + * When a syncobj is first created, its pointer is either NULL or a pointer + * to an already signaled fence depending on whether the + * &DRM_SYNCOBJ_CREATE_SIGNALED flag is passed to + * &DRM_IOCTL_SYNCOBJ_CREATE. + * When GPU work which signals a syncobj is enqueued in a DRM driver, + * the syncobj fence is replaced with a fence which will be signaled by the + * completion of that work. + * When GPU work which waits on a syncobj is enqueued in a DRM driver, the + * driver retrieves syncobj's current fence at the time the work is enqueued + * waits on that fence before submitting the work to hardware. + * If the syncobj's fence is NULL, the enqueue operation is expected to fail. + * All manipulation of the syncobjs's fence happens in terms of the current + * fence at the time the ioctl is called by userspace regardless of whether + * that operation is an immediate host-side operation (signal or reset) or + * or an operation which is enqueued in some driver queue. + * &DRM_IOCTL_SYNCOBJ_RESET and &DRM_IOCTL_SYNCOBJ_SIGNAL can be used to + * manipulate a syncobj from the host by resetting its pointer to NULL or + * setting its pointer to a fence which is already signaled. * - * Their primary use-case is to implement Vulkan fences and semaphores. * - * syncobj have a kref reference count, but also have an optional file. - * The file is only created once the syncobj is exported. - * The file takes a reference on the kref. + * Host-side wait on syncobjs + * -------------------------- + * + * &DRM_IOCTL_SYNCOBJ_WAIT takes an array of syncobj handles and does a + * host-side wait on all of the syncobj fences simultaneously. + * If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL is set, the wait ioctl will wait on + * all of the syncobj fences to be signaled before it returns. + * Otherwise, it returns once at least one syncobj fence has been signaled + * and the index of a signaled fence is written back to the client. + * + * Unlike the enqueued GPU work dependencies which fail if they see a NULL + * fence in a syncobj, if &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is set, + * the host-side wait will first wait for the syncobj to receive a non-NULL + * fence and then wait on that fence. + * If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is not set and any one of the + * syncobjs in the array has a NULL fence, -EINVAL will be returned. + * Assuming the syncobj starts off with a NULL fence, this allows a client + * to do a host wait in one thread (or process) which waits on GPU work + * submitted in another thread (or process) without having to manually + * synchronize between the two. + * This requirement is inherited from the Vulkan fence API. + * + * + * Import/export of syncobjs + * ------------------------- + * + * &DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE and &DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD + * provide two mechanisms for import/export of syncobjs. + * + * The first lets the client import or export an entire syncobj to a file + * descriptor. + * These fd's are opaque and have no other use case, except passing the + * syncobj between processes. + * All exported file descriptors and any syncobj handles created as a + * result of importing those file descriptors own a reference to the + * same underlying struct &drm_syncobj and the syncobj can be used + * persistently across all the processes with which it is shared. + * The syncobj is freed only once the last reference is dropped. + * Unlike dma-buf, importing a syncobj creates a new handle (with its own + * reference) for every import instead of de-duplicating. + * The primary use-case of this persistent import/export is for shared + * Vulkan fences and semaphores. + * + * The second import/export mechanism, which is indicated by + * &DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE or + * &DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE lets the client + * import/export the syncobj's current fence from/to a &sync_file. + * When a syncobj is exported to a sync file, that sync file wraps the + * sycnobj's fence at the time of export and any later signal or reset + * operations on the syncobj will not affect the exported sync file. + * When a sync file is imported into a syncobj, the syncobj's fence is set + * to the fence wrapped by that sync file. + * Because sync files are immutable, resetting or signaling the syncobj + * will not affect any sync files whose fences have been imported into the + * syncobj. */
#include <linux/anon_inodes.h>
Would one of you mind pushing? I don't have drm-misc commit bits.
On Mon, Aug 12, 2019 at 9:22 AM Jason Ekstrand jason@jlekstrand.net wrote:
This patch only brings the syncobj documentation up-to-date for the original form of syncobj. It does not contain any information about the design of timeline syncobjs.
v2: Incorporate feedback from Lionel and Christian:
- Mention actual ioctl and flag names
- Better language around reference counting
- Misc. language cleanups
Signed-off-by: Jason Ekstrand jason@jlekstrand.net Reviewed-by: Lionel Landwerlin lionel.g.landwerlin@intel.com Acked-by: Christian König christian.koenig@amd.com
drivers/gpu/drm/drm_syncobj.c | 98 +++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 1438dcb3ebb1..4b5c7b0ed714 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -29,21 +29,97 @@ /**
- DOC: Overview
- DRM synchronisation objects (syncobj, see struct &drm_syncobj) are
- persistent objects that contain an optional fence. The fence can be
updated
- with a new fence, or be NULL.
- DRM synchronisation objects (syncobj, see struct &drm_syncobj) provide
a
- container for a synchronization primitive which can be used by
userspace
- to explicitly synchronize GPU commands, can be shared between userspace
- processes, and can be shared between different DRM drivers.
- Their primary use-case is to implement Vulkan fences and semaphores.
- The syncobj userspace API provides ioctls for several operations:
- syncobj's can be waited upon, where it will wait for the underlying
- fence.
- Creation and destruction of syncobjs
- Import and export of syncobjs to/from a syncobj file descriptor
- Import and export a syncobj's underlying fence to/from a sync file
- Reset a syncobj (set its fence to NULL)
- Signal a syncobj (set a trivially signaled fence)
- Wait for a syncobj's fence to appear and be signaled
- syncobj's can be export to fd's and back, these fd's are opaque and
- have no other use case, except passing the syncobj between processes.
- At it's core, a syncobj is simply a wrapper around a pointer to a
struct
- &dma_fence which may be NULL.
- When a syncobj is first created, its pointer is either NULL or a
pointer
- to an already signaled fence depending on whether the
- &DRM_SYNCOBJ_CREATE_SIGNALED flag is passed to
- &DRM_IOCTL_SYNCOBJ_CREATE.
- When GPU work which signals a syncobj is enqueued in a DRM driver,
- the syncobj fence is replaced with a fence which will be signaled by
the
- completion of that work.
- When GPU work which waits on a syncobj is enqueued in a DRM driver, the
- driver retrieves syncobj's current fence at the time the work is
enqueued
- waits on that fence before submitting the work to hardware.
- If the syncobj's fence is NULL, the enqueue operation is expected to
fail.
- All manipulation of the syncobjs's fence happens in terms of the
current
- fence at the time the ioctl is called by userspace regardless of
whether
- that operation is an immediate host-side operation (signal or reset) or
- or an operation which is enqueued in some driver queue.
- &DRM_IOCTL_SYNCOBJ_RESET and &DRM_IOCTL_SYNCOBJ_SIGNAL can be used to
- manipulate a syncobj from the host by resetting its pointer to NULL or
- setting its pointer to a fence which is already signaled.
- Their primary use-case is to implement Vulkan fences and semaphores.
- syncobj have a kref reference count, but also have an optional file.
- The file is only created once the syncobj is exported.
- The file takes a reference on the kref.
- Host-side wait on syncobjs
- &DRM_IOCTL_SYNCOBJ_WAIT takes an array of syncobj handles and does a
- host-side wait on all of the syncobj fences simultaneously.
- If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL is set, the wait ioctl will wait on
- all of the syncobj fences to be signaled before it returns.
- Otherwise, it returns once at least one syncobj fence has been signaled
- and the index of a signaled fence is written back to the client.
- Unlike the enqueued GPU work dependencies which fail if they see a NULL
- fence in a syncobj, if &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is set,
- the host-side wait will first wait for the syncobj to receive a
non-NULL
- fence and then wait on that fence.
- If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is not set and any one of
the
- syncobjs in the array has a NULL fence, -EINVAL will be returned.
- Assuming the syncobj starts off with a NULL fence, this allows a client
- to do a host wait in one thread (or process) which waits on GPU work
- submitted in another thread (or process) without having to manually
- synchronize between the two.
- This requirement is inherited from the Vulkan fence API.
- Import/export of syncobjs
- &DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE and &DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD
- provide two mechanisms for import/export of syncobjs.
- The first lets the client import or export an entire syncobj to a file
- descriptor.
- These fd's are opaque and have no other use case, except passing the
- syncobj between processes.
- All exported file descriptors and any syncobj handles created as a
- result of importing those file descriptors own a reference to the
- same underlying struct &drm_syncobj and the syncobj can be used
- persistently across all the processes with which it is shared.
- The syncobj is freed only once the last reference is dropped.
- Unlike dma-buf, importing a syncobj creates a new handle (with its own
- reference) for every import instead of de-duplicating.
- The primary use-case of this persistent import/export is for shared
- Vulkan fences and semaphores.
- The second import/export mechanism, which is indicated by
- &DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE or
- &DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE lets the client
- import/export the syncobj's current fence from/to a &sync_file.
- When a syncobj is exported to a sync file, that sync file wraps the
- sycnobj's fence at the time of export and any later signal or reset
- operations on the syncobj will not affect the exported sync file.
- When a sync file is imported into a syncobj, the syncobj's fence is set
- to the fence wrapped by that sync file.
- Because sync files are immutable, resetting or signaling the syncobj
- will not affect any sync files whose fences have been imported into the
*/
- syncobj.
#include <linux/anon_inodes.h>
2.21.0
dri-devel@lists.freedesktop.org