Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/syncobj: Add better overview documentation for syncobj (v2)

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>
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190812142211.15885-1-jason@jlekstrand.net

authored by

Jason Ekstrand and committed by
Lionel Landwerlin
f246ff5c 12db36bc

+89 -13
+89 -13
drivers/gpu/drm/drm_syncobj.c
··· 29 29 /** 30 30 * DOC: Overview 31 31 * 32 - * DRM synchronisation objects (syncobj, see struct &drm_syncobj) are 33 - * persistent objects that contain an optional fence. The fence can be updated 34 - * with a new fence, or be NULL. 35 - * 36 - * syncobj's can be waited upon, where it will wait for the underlying 37 - * fence. 38 - * 39 - * syncobj's can be export to fd's and back, these fd's are opaque and 40 - * have no other use case, except passing the syncobj between processes. 41 - * 32 + * DRM synchronisation objects (syncobj, see struct &drm_syncobj) provide a 33 + * container for a synchronization primitive which can be used by userspace 34 + * to explicitly synchronize GPU commands, can be shared between userspace 35 + * processes, and can be shared between different DRM drivers. 42 36 * Their primary use-case is to implement Vulkan fences and semaphores. 37 + * The syncobj userspace API provides ioctls for several operations: 43 38 * 44 - * syncobj have a kref reference count, but also have an optional file. 45 - * The file is only created once the syncobj is exported. 46 - * The file takes a reference on the kref. 39 + * - Creation and destruction of syncobjs 40 + * - Import and export of syncobjs to/from a syncobj file descriptor 41 + * - Import and export a syncobj's underlying fence to/from a sync file 42 + * - Reset a syncobj (set its fence to NULL) 43 + * - Signal a syncobj (set a trivially signaled fence) 44 + * - Wait for a syncobj's fence to appear and be signaled 45 + * 46 + * At it's core, a syncobj is simply a wrapper around a pointer to a struct 47 + * &dma_fence which may be NULL. 48 + * When a syncobj is first created, its pointer is either NULL or a pointer 49 + * to an already signaled fence depending on whether the 50 + * &DRM_SYNCOBJ_CREATE_SIGNALED flag is passed to 51 + * &DRM_IOCTL_SYNCOBJ_CREATE. 52 + * When GPU work which signals a syncobj is enqueued in a DRM driver, 53 + * the syncobj fence is replaced with a fence which will be signaled by the 54 + * completion of that work. 55 + * When GPU work which waits on a syncobj is enqueued in a DRM driver, the 56 + * driver retrieves syncobj's current fence at the time the work is enqueued 57 + * waits on that fence before submitting the work to hardware. 58 + * If the syncobj's fence is NULL, the enqueue operation is expected to fail. 59 + * All manipulation of the syncobjs's fence happens in terms of the current 60 + * fence at the time the ioctl is called by userspace regardless of whether 61 + * that operation is an immediate host-side operation (signal or reset) or 62 + * or an operation which is enqueued in some driver queue. 63 + * &DRM_IOCTL_SYNCOBJ_RESET and &DRM_IOCTL_SYNCOBJ_SIGNAL can be used to 64 + * manipulate a syncobj from the host by resetting its pointer to NULL or 65 + * setting its pointer to a fence which is already signaled. 66 + * 67 + * 68 + * Host-side wait on syncobjs 69 + * -------------------------- 70 + * 71 + * &DRM_IOCTL_SYNCOBJ_WAIT takes an array of syncobj handles and does a 72 + * host-side wait on all of the syncobj fences simultaneously. 73 + * If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL is set, the wait ioctl will wait on 74 + * all of the syncobj fences to be signaled before it returns. 75 + * Otherwise, it returns once at least one syncobj fence has been signaled 76 + * and the index of a signaled fence is written back to the client. 77 + * 78 + * Unlike the enqueued GPU work dependencies which fail if they see a NULL 79 + * fence in a syncobj, if &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is set, 80 + * the host-side wait will first wait for the syncobj to receive a non-NULL 81 + * fence and then wait on that fence. 82 + * If &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is not set and any one of the 83 + * syncobjs in the array has a NULL fence, -EINVAL will be returned. 84 + * Assuming the syncobj starts off with a NULL fence, this allows a client 85 + * to do a host wait in one thread (or process) which waits on GPU work 86 + * submitted in another thread (or process) without having to manually 87 + * synchronize between the two. 88 + * This requirement is inherited from the Vulkan fence API. 89 + * 90 + * 91 + * Import/export of syncobjs 92 + * ------------------------- 93 + * 94 + * &DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE and &DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD 95 + * provide two mechanisms for import/export of syncobjs. 96 + * 97 + * The first lets the client import or export an entire syncobj to a file 98 + * descriptor. 99 + * These fd's are opaque and have no other use case, except passing the 100 + * syncobj between processes. 101 + * All exported file descriptors and any syncobj handles created as a 102 + * result of importing those file descriptors own a reference to the 103 + * same underlying struct &drm_syncobj and the syncobj can be used 104 + * persistently across all the processes with which it is shared. 105 + * The syncobj is freed only once the last reference is dropped. 106 + * Unlike dma-buf, importing a syncobj creates a new handle (with its own 107 + * reference) for every import instead of de-duplicating. 108 + * The primary use-case of this persistent import/export is for shared 109 + * Vulkan fences and semaphores. 110 + * 111 + * The second import/export mechanism, which is indicated by 112 + * &DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE or 113 + * &DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE lets the client 114 + * import/export the syncobj's current fence from/to a &sync_file. 115 + * When a syncobj is exported to a sync file, that sync file wraps the 116 + * sycnobj's fence at the time of export and any later signal or reset 117 + * operations on the syncobj will not affect the exported sync file. 118 + * When a sync file is imported into a syncobj, the syncobj's fence is set 119 + * to the fence wrapped by that sync file. 120 + * Because sync files are immutable, resetting or signaling the syncobj 121 + * will not affect any sync files whose fences have been imported into the 122 + * syncobj. 47 123 */ 48 124 49 125 #include <linux/anon_inodes.h>