Message ID | 20190806161905.30769-1-jason@jlekstrand.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/syncobj: Add better overview documentation for syncobj (v2) | expand |
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> > > >
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>
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(-)