<div dir="ltr">Would one of you mind pushing?  I don't have drm-misc commit bits.<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Aug 12, 2019 at 9:22 AM Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">This patch only brings the syncobj documentation up-to-date for the<br>
original form of syncobj.  It does not contain any information about the<br>
design of timeline syncobjs.<br>
<br>
v2: Incorporate feedback from Lionel and Christian:<br>
 - Mention actual ioctl and flag names<br>
 - Better language around reference counting<br>
 - Misc. language cleanups<br>
<br>
Signed-off-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>><br>
Reviewed-by: Lionel Landwerlin <<a href="mailto:lionel.g.landwerlin@intel.com" target="_blank">lionel.g.landwerlin@intel.com</a>><br>
Acked-by: Christian König <<a href="mailto:christian.koenig@amd.com" target="_blank">christian.koenig@amd.com</a>><br>
---<br>
 drivers/gpu/drm/drm_syncobj.c | 98 +++++++++++++++++++++++++++++++----<br>
 1 file changed, 87 insertions(+), 11 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c<br>
index 1438dcb3ebb1..4b5c7b0ed714 100644<br>
--- a/drivers/gpu/drm/drm_syncobj.c<br>
+++ b/drivers/gpu/drm/drm_syncobj.c<br>
@@ -29,21 +29,97 @@<br>
 /**<br>
  * DOC: Overview<br>
  *<br>
- * DRM synchronisation objects (syncobj, see struct &drm_syncobj) are<br>
- * persistent objects that contain an optional fence. The fence can be updated<br>
- * with a new fence, or be NULL.<br>
+ * DRM synchronisation objects (syncobj, see struct &drm_syncobj) provide a<br>
+ * container for a synchronization primitive which can be used by userspace<br>
+ * to explicitly synchronize GPU commands, can be shared between userspace<br>
+ * processes, and can be shared between different DRM drivers.<br>
+ * Their primary use-case is to implement Vulkan fences and semaphores.<br>
+ * The syncobj userspace API provides ioctls for several operations:<br>
  *<br>
- * syncobj's can be waited upon, where it will wait for the underlying<br>
- * fence.<br>
+ *  - Creation and destruction of syncobjs<br>
+ *  - Import and export of syncobjs to/from a syncobj file descriptor<br>
+ *  - Import and export a syncobj's underlying fence to/from a sync file<br>
+ *  - Reset a syncobj (set its fence to NULL)<br>
+ *  - Signal a syncobj (set a trivially signaled fence)<br>
+ *  - Wait for a syncobj's fence to appear and be signaled<br>
  *<br>
- * syncobj's can be export to fd's and back, these fd's are opaque and<br>
- * have no other use case, except passing the syncobj between processes.<br>
+ * At it's core, a syncobj is simply a wrapper around a pointer to a struct<br>
+ * &dma_fence which may be NULL.<br>
+ * When a syncobj is first created, its pointer is either NULL or a pointer<br>
+ * to an already signaled fence depending on whether the<br>
+ * &DRM_SYNCOBJ_CREATE_SIGNALED flag is passed to<br>
+ * &DRM_IOCTL_SYNCOBJ_CREATE.<br>
+ * When GPU work which signals a syncobj is enqueued in a DRM driver,<br>
+ * the syncobj fence is replaced with a fence which will be signaled by the<br>
+ * completion of that work.<br>
+ * When GPU work which waits on a syncobj is enqueued in a DRM driver, the<br>
+ * driver retrieves syncobj's current fence at the time the work is enqueued<br>
+ * waits on that fence before submitting the work to hardware.<br>
+ * If the syncobj's fence is NULL, the enqueue operation is expected to fail.<br>
+ * All manipulation of the syncobjs's fence happens in terms of the current<br>
+ * fence at the time the ioctl is called by userspace regardless of whether<br>
+ * that operation is an immediate host-side operation (signal or reset) or<br>
+ * or an operation which is enqueued in some driver queue.<br>
+ * &DRM_IOCTL_SYNCOBJ_RESET and &DRM_IOCTL_SYNCOBJ_SIGNAL can be used to<br>
+ * manipulate a syncobj from the host by resetting its pointer to NULL or<br>
+ * setting its pointer to a fence which is already signaled.<br>
  *<br>
- * Their primary use-case is to implement Vulkan fences and semaphores.<br>
  *<br>
- * syncobj have a kref reference count, but also have an optional file.<br>
- * The file is only created once the syncobj is exported.<br>
- * The file takes a reference on the kref.<br>
+ * Host-side wait on syncobjs<br>
+ * --------------------------<br>
+ *<br>
+ * &DRM_IOCTL_SYNCOBJ_WAIT takes an array of syncobj handles and does a<br>
+ * host-side wait on all of the syncobj fences simultaneously.<br>
+ * If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL is set, the wait ioctl will wait on<br>
+ * all of the syncobj fences to be signaled before it returns.<br>
+ * Otherwise, it returns once at least one syncobj fence has been signaled<br>
+ * and the index of a signaled fence is written back to the client.<br>
+ *<br>
+ * Unlike the enqueued GPU work dependencies which fail if they see a NULL<br>
+ * fence in a syncobj, if &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is set,<br>
+ * the host-side wait will first wait for the syncobj to receive a non-NULL<br>
+ * fence and then wait on that fence.<br>
+ * If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is not set and any one of the<br>
+ * syncobjs in the array has a NULL fence, -EINVAL will be returned.<br>
+ * Assuming the syncobj starts off with a NULL fence, this allows a client<br>
+ * to do a host wait in one thread (or process) which waits on GPU work<br>
+ * submitted in another thread (or process) without having to manually<br>
+ * synchronize between the two.<br>
+ * This requirement is inherited from the Vulkan fence API.<br>
+ *<br>
+ *<br>
+ * Import/export of syncobjs<br>
+ * -------------------------<br>
+ *<br>
+ * &DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE and &DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD<br>
+ * provide two mechanisms for import/export of syncobjs.<br>
+ *<br>
+ * The first lets the client import or export an entire syncobj to a file<br>
+ * descriptor.<br>
+ * These fd's are opaque and have no other use case, except passing the<br>
+ * syncobj between processes.<br>
+ * All exported file descriptors and any syncobj handles created as a<br>
+ * result of importing those file descriptors own a reference to the<br>
+ * same underlying struct &drm_syncobj and the syncobj can be used<br>
+ * persistently across all the processes with which it is shared.<br>
+ * The syncobj is freed only once the last reference is dropped.<br>
+ * Unlike dma-buf, importing a syncobj creates a new handle (with its own<br>
+ * reference) for every import instead of de-duplicating.<br>
+ * The primary use-case of this persistent import/export is for shared<br>
+ * Vulkan fences and semaphores.<br>
+ *<br>
+ * The second import/export mechanism, which is indicated by<br>
+ * &DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE or<br>
+ * &DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE lets the client<br>
+ * import/export the syncobj's current fence from/to a &sync_file.<br>
+ * When a syncobj is exported to a sync file, that sync file wraps the<br>
+ * sycnobj's fence at the time of export and any later signal or reset<br>
+ * operations on the syncobj will not affect the exported sync file.<br>
+ * When a sync file is imported into a syncobj, the syncobj's fence is set<br>
+ * to the fence wrapped by that sync file.<br>
+ * Because sync files are immutable, resetting or signaling the syncobj<br>
+ * will not affect any sync files whose fences have been imported into the<br>
+ * syncobj.<br>
  */<br>
<br>
 #include <linux/anon_inodes.h><br>
-- <br>
2.21.0<br>
<br>
</blockquote></div>