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.
146 * The first lets the client import or export an entire syncobj to a file
149 * syncobj between processes.
150 * All exported file descriptors and any syncobj handles created as a
152 * same underlying struct &drm_syncobj and the syncobj can be used
154 * The syncobj is freed only once the last reference is dropped.
155 * Unlike dma-buf, importing a syncobj creates a new handle (with its own
163 * import/export the syncobj's current fence from/to a &sync_file.
164 * When a syncobj is exported to a sync file, that sync file wraps the
166 * operations on the syncobj will not affect the exported sync file.
167 * When a sync file is imported into a syncobj, the syncobj's fence is set
169 * Because sync files are immutable, resetting or signaling the syncobj
171 * syncobj.
178 * &dma_fence_chain of a syncobj at a given u64 point to another u64 point
179 * into another syncobj.
182 * point on a timeline syncobj from/into a binary syncobj, you can use the
183 * point 0 to mean take/replace the fence in the syncobj.
211 static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
219 * Returns a reference to the syncobj pointed to by handle or NULL. The
225 struct drm_syncobj *syncobj;
230 syncobj = idr_find(&file_private->syncobj_idr, handle);
231 if (syncobj)
232 drm_syncobj_get(syncobj);
236 return syncobj;
240 static void drm_syncobj_fence_add_wait(struct drm_syncobj *syncobj,
248 spin_lock(&syncobj->lock);
253 fence = dma_fence_get(rcu_dereference_protected(syncobj->fence, 1));
256 list_add_tail(&wait->node, &syncobj->cb_list);
262 spin_unlock(&syncobj->lock);
265 static void drm_syncobj_remove_wait(struct drm_syncobj *syncobj,
271 spin_lock(&syncobj->lock);
273 spin_unlock(&syncobj->lock);
277 * drm_syncobj_add_point - add new timeline point to the syncobj
278 * @syncobj: sync object to add timeline point do
283 * Add the chain node as new timeline point to the syncobj.
285 void drm_syncobj_add_point(struct drm_syncobj *syncobj,
295 spin_lock(&syncobj->lock);
297 prev = drm_syncobj_fence_get(syncobj);
302 rcu_assign_pointer(syncobj->fence, &chain->base);
304 list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node)
305 syncobj_wait_syncobj_func(syncobj, cur);
306 spin_unlock(&syncobj->lock);
316 * @syncobj: Sync object to replace fence in
321 void drm_syncobj_replace_fence(struct drm_syncobj *syncobj,
330 spin_lock(&syncobj->lock);
332 old_fence = rcu_dereference_protected(syncobj->fence,
333 lockdep_is_held(&syncobj->lock));
334 rcu_assign_pointer(syncobj->fence, fence);
337 list_for_each_entry_safe(cur, tmp, &syncobj->cb_list, node)
338 syncobj_wait_syncobj_func(syncobj, cur);
341 spin_unlock(&syncobj->lock);
349 * @syncobj: sync object to assign the fence on
353 static void drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
357 drm_syncobj_replace_fence(syncobj, fence);
382 struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
387 if (!syncobj)
390 *fence = drm_syncobj_fence_get(syncobj);
416 drm_syncobj_fence_add_wait(syncobj, &wait);
441 drm_syncobj_remove_wait(syncobj, &wait);
444 drm_syncobj_put(syncobj);
458 struct drm_syncobj *syncobj = container_of(kref,
461 drm_syncobj_replace_fence(syncobj, NULL);
462 kfree(syncobj);
467 * drm_syncobj_create - create a new syncobj
468 * @out_syncobj: returned syncobj
470 * @fence: if non-NULL, the syncobj will represent this fence
481 struct drm_syncobj *syncobj;
483 syncobj = kzalloc(sizeof(struct drm_syncobj), GFP_KERNEL);
484 if (!syncobj)
487 kref_init(&syncobj->refcount);
488 INIT_LIST_HEAD(&syncobj->cb_list);
489 spin_lock_init(&syncobj->lock);
492 drm_syncobj_assign_null_handle(syncobj);
495 drm_syncobj_replace_fence(syncobj, fence);
497 *out_syncobj = syncobj;
503 * drm_syncobj_get_handle - get a handle from a syncobj
505 * @syncobj: Sync object to export
514 struct drm_syncobj *syncobj, u32 *handle)
519 drm_syncobj_get(syncobj);
523 ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT);
529 drm_syncobj_put(syncobj);
542 struct drm_syncobj *syncobj;
544 ret = drm_syncobj_create(&syncobj, flags, NULL);
548 ret = drm_syncobj_get_handle(file_private, syncobj, handle);
549 drm_syncobj_put(syncobj);
556 struct drm_syncobj *syncobj;
559 syncobj = idr_remove(&file_private->syncobj_idr, handle);
562 if (!syncobj)
565 drm_syncobj_put(syncobj);
571 struct drm_syncobj *syncobj = file->private_data;
573 drm_syncobj_put(syncobj);
582 * drm_syncobj_get_fd - get a file descriptor from a syncobj
583 * @syncobj: Sync object to export
590 int drm_syncobj_get_fd(struct drm_syncobj *syncobj, int *p_fd)
601 syncobj, 0);
607 drm_syncobj_get(syncobj);
618 struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle);
621 if (!syncobj)
624 ret = drm_syncobj_get_fd(syncobj, p_fd);
625 drm_syncobj_put(syncobj);
632 struct drm_syncobj *syncobj;
645 syncobj = f.file->private_data;
646 drm_syncobj_get(syncobj);
650 ret = idr_alloc(&file_private->syncobj_idr, syncobj, 1, 0, GFP_NOWAIT);
658 drm_syncobj_put(syncobj);
668 struct drm_syncobj *syncobj;
673 syncobj = drm_syncobj_find(file_private, handle);
674 if (!syncobj) {
679 drm_syncobj_replace_fence(syncobj, fence);
681 drm_syncobj_put(syncobj);
718 * drm_syncobj_open - initalizes syncobj file-private structures at devnode open time
734 struct drm_syncobj *syncobj = ptr;
736 drm_syncobj_put(syncobj);
920 static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj,
925 /* This happens inside the syncobj lock */
926 fence = rcu_dereference_protected(syncobj->fence,
927 lockdep_is_held(&syncobj->lock));
974 * a syncobj with a missing fence and then never have the chance of