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.
217 static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
224 struct drm_syncobj *syncobj;
231 syncobj_eventfd_entry_func(struct drm_syncobj *syncobj,
239 * Returns a reference to the syncobj pointed to by handle or NULL. The
245 struct drm_syncobj *syncobj;
250 syncobj = idr_find(&file_private->syncobj_idr, handle);
251 if (syncobj)
252 drm_syncobj_get(syncobj);
256 return syncobj;
260 static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj,
268 spin_lock(&syncobj->lock);
273 fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, 1));
276 list_add_tail(&wait->node, &syncobj->cb_list);
282 spin_unlock(&syncobj->lock);
285 static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj,
291 spin_lock(&syncobj->lock);
293 spin_unlock(&syncobj->lock);
301 /* This happens either inside the syncobj lock, or after the node has
309 drm_syncobj_add_eventfd(struct drm_syncobj *syncobj,
312 spin_lock(&syncobj->lock);
313 list_add_tail(&entry->node, &syncobj->ev_fd_list);
314 syncobj_eventfd_entry_func(syncobj, entry);
315 spin_unlock(&syncobj->lock);
319 * drm_syncobj_add_point - add new timeline point to the syncobj
320 * @syncobj: sync object to add timeline point do
325 * Add the chain node as new timeline point to the syncobj.
327 void drm_syncobj_add_point(struct drm_syncobj *syncobj,
338 spin_lock(&syncobj->lock);
340 prev = drm_syncobj_fence_get(syncobj);
345 rcu_assign_pointer(syncobj->fence, &chain->base);
347 list_for_each_entry_safe(wait_cur, wait_tmp, &syncobj->cb_list, node)
348 syncobj_wait_syncobj_func(syncobj, wait_cur);
349 list_for_each_entry_safe(ev_fd_cur, ev_fd_tmp, &syncobj->ev_fd_list, node)
350 syncobj_eventfd_entry_func(syncobj, ev_fd_cur);
351 spin_unlock(&syncobj->lock);
361 * @syncobj: Sync object to replace fence in
366 void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
376 spin_lock(&syncobj->lock);
378 old_fence = rcu_dereference_protected(syncobj->fence,
379 lockdep_is_held(&syncobj->lock));
380 rcu_assign_pointer(syncobj->fence, fence);
383 list_for_each_entry_safe(wait_cur, wait_tmp, &syncobj->cb_list, node)
384 syncobj_wait_syncobj_func(syncobj, wait_cur);
385 list_for_each_entry_safe(ev_fd_cur, ev_fd_tmp, &syncobj->ev_fd_list, node)
386 syncobj_eventfd_entry_func(syncobj, ev_fd_cur);
389 spin_unlock(&syncobj->lock);
397 * @syncobj: sync object to assign the fence on
401 static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
408 drm_syncobj_replace_fence(syncobj, fence);
434 struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
439 if (!syncobj)
451 *fence = drm_syncobj_fence_get(syncobj);
477 drm_syncobj_fence_add_wait(syncobj, &wait);
502 drm_syncobj_remove_wait(syncobj, &wait);
505 drm_syncobj_put(syncobj);
519 struct drm_syncobj *syncobj = container_of(kref,
524 drm_syncobj_replace_fence(syncobj, NULL);
526 list_for_each_entry_safe(ev_fd_cur, ev_fd_tmp, &syncobj->ev_fd_list, node)
529 kfree(syncobj);
534 * drm_syncobj_create - create a new syncobj
535 * @out_syncobj: returned syncobj
537 * @fence: if non-NULL, the syncobj will represent this fence
549 struct drm_syncobj *syncobj;
551 syncobj = kzalloc(sizeof(struct drm_syncobj), GFP_KERNEL);
552 if (!syncobj)
555 kref_init(&syncobj->refcount);
556 INIT_LIST_HEAD(&syncobj->cb_list);
557 INIT_LIST_HEAD(&syncobj->ev_fd_list);
558 spin_lock_init(&syncobj->lock);
561 ret = drm_syncobj_assign_null_handle(syncobj);
563 drm_syncobj_put(syncobj);
569 drm_syncobj_replace_fence(syncobj, fence);
571 *out_syncobj = syncobj;
577 * drm_syncobj_get_handle - get a handle from a syncobj
579 * @syncobj: Sync object to export
588 struct drm_syncobj *syncobj, u32 *handle)
593 drm_syncobj_get(syncobj);
597 ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT);
603 drm_syncobj_put(syncobj);
616 struct drm_syncobj *syncobj;
618 ret = drm_syncobj_create(&syncobj, flags, NULL);
622 ret = drm_syncobj_get_handle(file_private, syncobj, handle);
623 drm_syncobj_put(syncobj);
630 struct drm_syncobj *syncobj;
633 syncobj = idr_remove(&file_private->syncobj_idr, handle);
636 if (!syncobj)
639 drm_syncobj_put(syncobj);
645 struct drm_syncobj *syncobj = file->private_data;
647 drm_syncobj_put(syncobj);
656 * drm_syncobj_get_fd - get a file descriptor from a syncobj
657 * @syncobj: Sync object to export
664 int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd)
675 syncobj, 0);
681 drm_syncobj_get(syncobj);
692 struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
695 if (!syncobj)
698 ret = drm_syncobj_get_fd(syncobj, p_fd);
699 drm_syncobj_put(syncobj);
706 struct drm_syncobj *syncobj;
719 syncobj = f.file->private_data;
720 drm_syncobj_get(syncobj);
724 ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT);
732 drm_syncobj_put(syncobj);
742 struct drm_syncobj *syncobj;
747 syncobj = drm_syncobj_find(file_private, handle);
748 if (!syncobj) {
753 drm_syncobj_replace_fence(syncobj, fence);
755 drm_syncobj_put(syncobj);
792 * drm_syncobj_open - initializes syncobj file-private structures at devnode open time
808 struct drm_syncobj *syncobj = ptr;
810 drm_syncobj_put(syncobj);
1003 static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
1008 /* This happens inside the syncobj lock */
1009 fence = rcu_dereference_protected(syncobj->fence,
1010 lockdep_is_held(&syncobj->lock));
1061 * a syncobj with a missing fence and then never have the chance of
1375 syncobj_eventfd_entry_func(struct drm_syncobj *syncobj,
1381 /* This happens inside the syncobj lock */
1382 fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, 1));
1421 struct drm_syncobj *syncobj;
1434 syncobj = drm_syncobj_find(file_private, args->handle);
1435 if (!syncobj)
1447 entry->syncobj = syncobj;
1452 drm_syncobj_add_eventfd(syncobj, entry);
1453 drm_syncobj_put(syncobj);