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.