Lines Matching refs:syncobj

32  * DRM synchronisation objects (syncobj, see struct &drm_syncobj) provide a
37 * The syncobj userspace API provides ioctls for several operations:
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
46 * The syncobj userspace API also provides operations to manipulate a syncobj
54 * At it's core, a syncobj is simply a wrapper around a pointer to a struct
56 * When a syncobj is first created, its pointer is either NULL or a pointer
61 * If the syncobj is considered as a binary (its state is either signaled or
63 * the syncobj, the syncobj's fence is replaced with a fence which will be
65 * If the syncobj is considered as a timeline primitive, when GPU work is
66 * enqueued in a DRM driver to signal the a given point of the syncobj, a new
68 * pointing to the previous fence that was in the syncobj. The new struct
69 * &dma_fence_chain fence replace the syncobj's fence and will be signaled by
71 * fence previously in the syncobj.
73 * When GPU work which waits on a syncobj is enqueued in a DRM driver, at the
74 * time the work is enqueued, it waits on the syncobj's fence before
77 * - The syncobj's current fence if the syncobj is considered as a binary
79 * - The struct &dma_fence associated with a given point if the syncobj is
82 * If the syncobj's fence is NULL or not present in the syncobj's timeline,
85 * With binary syncobj, all manipulation of the syncobjs's fence happens in
90 * to manipulate a syncobj from the host by resetting its pointer to NULL or
93 * With a timeline syncobj, all manipulation of the synobj's fence happens in
99 * ioctl() when dealing with syncobj considered as timeline. Using a binary
100 * set of ioctl() with a syncobj considered as timeline could result incorrect
101 * synchronization. The use of binary syncobj is supported through the
104 * syncobj's fence when signaling).
110 * &DRM_IOCTL_SYNCOBJ_WAIT takes an array of syncobj handles and does a
111 * host-side wait on all of the syncobj fences simultaneously.
113 * all of the syncobj fences to be signaled before it returns.
114 * Otherwise, it returns once at least one syncobj fence has been signaled
118 * fence in a syncobj, if &DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT is set,
119 * the host-side wait will first wait for the syncobj to receive a non-NULL
123 * Assuming the syncobj starts off with a NULL fence, this allows a client
129 * Similarly, &DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT takes an array of syncobj
131 * of syncobj fences at the given points simultaneously.
140 * blocking: an eventfd will be signaled when the syncobj is. This is useful to
150 * The first lets the client import or export an entire syncobj to a file
153 * syncobj between processes.
154 * All exported file descriptors and any syncobj handles created as a
156 * same underlying struct &drm_syncobj and the syncobj can be used
158 * The syncobj is freed only once the last reference is dropped.
159 * Unlike dma-buf, importing a syncobj creates a new handle (with its own
167 * import/export the syncobj's current fence from/to a &sync_file.
168 * When a syncobj is exported to a sync file, that sync file wraps the
170 * operations on the syncobj will not affect the exported sync file.
171 * When a sync file is imported into a syncobj, the syncobj's fence is set
173 * Because sync files are immutable, resetting or signaling the syncobj
175 * syncobj.
182 * &dma_fence_chain of a syncobj at a given u64 point to another u64 point
183 * into another syncobj.
186 * point on a timeline syncobj from/into a binary syncobj, you can use the
187 * point 0 to mean take/replace the fence in the syncobj.
221 static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
228 struct drm_syncobj *syncobj;
235 syncobj_eventfd_entry_func(struct drm_syncobj *syncobj,
243 * Returns a reference to the syncobj pointed to by handle or NULL. The
249 struct drm_syncobj *syncobj;
254 syncobj = idr_find(&file_private->syncobj_idr, handle);
255 if (syncobj)
256 drm_syncobj_get(syncobj);
260 return syncobj;
264 static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj,
272 spin_lock(&syncobj->lock);
277 fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, 1));
280 list_add_tail(&wait->node, &syncobj->cb_list);
286 spin_unlock(&syncobj->lock);
289 static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj,
295 spin_lock(&syncobj->lock);
297 spin_unlock(&syncobj->lock);
305 /* This happens either inside the syncobj lock, or after the node has
314 drm_syncobj_add_eventfd(struct drm_syncobj *syncobj,
317 spin_lock(&syncobj->lock);
318 list_add_tail(&entry->node, &syncobj->ev_fd_list);
319 syncobj_eventfd_entry_func(syncobj, entry);
320 spin_unlock(&syncobj->lock);
325 * drm_syncobj_add_point - add new timeline point to the syncobj
326 * @syncobj: sync object to add timeline point do
331 * Add the chain node as new timeline point to the syncobj.
333 void drm_syncobj_add_point(struct drm_syncobj *syncobj,
344 spin_lock(&syncobj->lock);
346 prev = drm_syncobj_fence_get(syncobj);
351 rcu_assign_pointer(syncobj->fence, &chain->base);
353 list_for_each_entry_safe(wait_cur, wait_tmp, &syncobj->cb_list, node)
354 syncobj_wait_syncobj_func(syncobj, wait_cur);
355 list_for_each_entry_safe(ev_fd_cur, ev_fd_tmp, &syncobj->ev_fd_list, node)
356 syncobj_eventfd_entry_func(syncobj, ev_fd_cur);
357 spin_unlock(&syncobj->lock);
367 * @syncobj: Sync object to replace fence in
372 void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
382 spin_lock(&syncobj->lock);
384 old_fence = rcu_dereference_protected(syncobj->fence,
385 lockdep_is_held(&syncobj->lock));
386 rcu_assign_pointer(syncobj->fence, fence);
389 list_for_each_entry_safe(wait_cur, wait_tmp, &syncobj->cb_list, node)
390 syncobj_wait_syncobj_func(syncobj, wait_cur);
391 list_for_each_entry_safe(ev_fd_cur, ev_fd_tmp, &syncobj->ev_fd_list, node)
392 syncobj_eventfd_entry_func(syncobj, ev_fd_cur);
395 spin_unlock(&syncobj->lock);
403 * @syncobj: sync object to assign the fence on
407 static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
414 drm_syncobj_replace_fence(syncobj, fence);
440 struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
445 if (!syncobj)
457 *fence = drm_syncobj_fence_get(syncobj);
487 drm_syncobj_fence_add_wait(syncobj, &wait);
512 drm_syncobj_remove_wait(syncobj, &wait);
515 drm_syncobj_put(syncobj);
529 struct drm_syncobj *syncobj = container_of(kref,
534 drm_syncobj_replace_fence(syncobj, NULL);
536 list_for_each_entry_safe(ev_fd_cur, ev_fd_tmp, &syncobj->ev_fd_list, node)
539 kfree(syncobj);
544 * drm_syncobj_create - create a new syncobj
545 * @out_syncobj: returned syncobj
547 * @fence: if non-NULL, the syncobj will represent this fence
559 struct drm_syncobj *syncobj;
561 syncobj = kzalloc(sizeof(struct drm_syncobj), GFP_KERNEL);
562 if (!syncobj)
565 kref_init(&syncobj->refcount);
566 INIT_LIST_HEAD(&syncobj->cb_list);
567 INIT_LIST_HEAD(&syncobj->ev_fd_list);
568 mtx_init(&syncobj->lock, IPL_NONE);
571 ret = drm_syncobj_assign_null_handle(syncobj);
573 drm_syncobj_put(syncobj);
579 drm_syncobj_replace_fence(syncobj, fence);
581 *out_syncobj = syncobj;
587 * drm_syncobj_get_handle - get a handle from a syncobj
589 * @syncobj: Sync object to export
598 struct drm_syncobj *syncobj, u32 *handle)
603 drm_syncobj_get(syncobj);
607 ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT);
613 drm_syncobj_put(syncobj);
626 struct drm_syncobj *syncobj;
628 ret = drm_syncobj_create(&syncobj, flags, NULL);
632 ret = drm_syncobj_get_handle(file_private, syncobj, handle);
633 drm_syncobj_put(syncobj);
640 struct drm_syncobj *syncobj;
643 syncobj = idr_remove(&file_private->syncobj_idr, handle);
646 if (!syncobj)
649 drm_syncobj_put(syncobj);
656 struct drm_syncobj *syncobj = file->private_data;
658 drm_syncobj_put(syncobj);
668 * drm_syncobj_get_fd - get a file descriptor from a syncobj
669 * @syncobj: Sync object to export
676 int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd)
690 syncobj, 0);
696 drm_syncobj_get(syncobj);
708 struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
711 if (!syncobj)
714 ret = drm_syncobj_get_fd(syncobj, p_fd);
715 drm_syncobj_put(syncobj);
725 struct drm_syncobj *syncobj;
738 syncobj = f.file->private_data;
739 drm_syncobj_get(syncobj);
743 ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT);
751 drm_syncobj_put(syncobj);
762 struct drm_syncobj *syncobj;
767 syncobj = drm_syncobj_find(file_private, handle);
768 if (!syncobj) {
773 drm_syncobj_replace_fence(syncobj, fence);
775 drm_syncobj_put(syncobj);
812 * drm_syncobj_open - initializes syncobj file-private structures at devnode open time
828 struct drm_syncobj *syncobj = ptr;
830 drm_syncobj_put(syncobj);
1065 static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
1070 /* This happens inside the syncobj lock */
1071 fence = rcu_dereference_protected(syncobj->fence,
1072 lockdep_is_held(&syncobj->lock));
1123 * a syncobj with a missing fence and then never have the chance of
1441 syncobj_eventfd_entry_func(struct drm_syncobj *syncobj,
1447 /* This happens inside the syncobj lock */
1448 fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, 1));
1489 struct drm_syncobj *syncobj;
1502 syncobj = drm_syncobj_find(file_private, args->handle);
1503 if (!syncobj)
1515 entry->syncobj = syncobj;
1520 drm_syncobj_add_eventfd(syncobj, entry);
1521 drm_syncobj_put(syncobj);