Lines Matching +full:sync +full:- +full:1
1 // SPDX-License-Identifier: MIT
8 #include <linux/dma-fence-array.h>
38 mmdrop(ufence->mm); in user_fence_destroy()
44 kref_get(&ufence->refcount); in user_fence_get()
49 kref_put(&ufence->refcount, user_fence_destroy); in user_fence_put()
61 ufence->xe = xe; in user_fence_create()
62 kref_init(&ufence->refcount); in user_fence_create()
63 ufence->addr = u64_to_user_ptr(addr); in user_fence_create()
64 ufence->value = value; in user_fence_create()
65 ufence->mm = current->mm; in user_fence_create()
66 mmgrab(ufence->mm); in user_fence_create()
75 if (mmget_not_zero(ufence->mm)) { in user_fence_worker()
76 kthread_use_mm(ufence->mm); in user_fence_worker()
77 if (copy_to_user(ufence->addr, &ufence->value, sizeof(ufence->value))) in user_fence_worker()
79 kthread_unuse_mm(ufence->mm); in user_fence_worker()
80 mmput(ufence->mm); in user_fence_worker()
83 wake_up_all(&ufence->xe->ufence_wq); in user_fence_worker()
84 WRITE_ONCE(ufence->signalled, 1); in user_fence_worker()
90 INIT_WORK(&ufence->worker, user_fence_worker); in kick_ufence()
91 queue_work(ufence->xe->ordered_wq, &ufence->worker); in kick_ufence()
103 struct xe_sync_entry *sync, in xe_sync_entry_parse() argument
115 return -EFAULT; in xe_sync_entry_parse()
118 XE_IOCTL_DBG(xe, sync_in.reserved[0] || sync_in.reserved[1])) in xe_sync_entry_parse()
119 return -EINVAL; in xe_sync_entry_parse()
125 return -EOPNOTSUPP; in xe_sync_entry_parse()
128 return -EINVAL; in xe_sync_entry_parse()
130 sync->syncobj = drm_syncobj_find(xef->drm, sync_in.handle); in xe_sync_entry_parse()
131 if (XE_IOCTL_DBG(xe, !sync->syncobj)) in xe_sync_entry_parse()
132 return -ENOENT; in xe_sync_entry_parse()
135 sync->fence = drm_syncobj_fence_get(sync->syncobj); in xe_sync_entry_parse()
136 if (XE_IOCTL_DBG(xe, !sync->fence)) in xe_sync_entry_parse()
137 return -EINVAL; in xe_sync_entry_parse()
143 return -EOPNOTSUPP; in xe_sync_entry_parse()
146 return -EINVAL; in xe_sync_entry_parse()
149 return -EINVAL; in xe_sync_entry_parse()
151 sync->syncobj = drm_syncobj_find(xef->drm, sync_in.handle); in xe_sync_entry_parse()
152 if (XE_IOCTL_DBG(xe, !sync->syncobj)) in xe_sync_entry_parse()
153 return -ENOENT; in xe_sync_entry_parse()
156 sync->chain_fence = dma_fence_chain_alloc(); in xe_sync_entry_parse()
157 if (!sync->chain_fence) in xe_sync_entry_parse()
158 return -ENOMEM; in xe_sync_entry_parse()
160 sync->fence = drm_syncobj_fence_get(sync->syncobj); in xe_sync_entry_parse()
161 if (XE_IOCTL_DBG(xe, !sync->fence)) in xe_sync_entry_parse()
162 return -EINVAL; in xe_sync_entry_parse()
164 err = dma_fence_chain_find_seqno(&sync->fence, in xe_sync_entry_parse()
173 return -EOPNOTSUPP; in xe_sync_entry_parse()
176 return -EOPNOTSUPP; in xe_sync_entry_parse()
179 return -EINVAL; in xe_sync_entry_parse()
182 sync->addr = sync_in.addr; in xe_sync_entry_parse()
184 sync->ufence = user_fence_create(xe, sync_in.addr, in xe_sync_entry_parse()
186 if (XE_IOCTL_DBG(xe, !sync->ufence)) in xe_sync_entry_parse()
187 return -ENOMEM; in xe_sync_entry_parse()
193 return -EINVAL; in xe_sync_entry_parse()
196 sync->type = sync_in.type; in xe_sync_entry_parse()
197 sync->flags = sync_in.flags; in xe_sync_entry_parse()
198 sync->timeline_value = sync_in.timeline_value; in xe_sync_entry_parse()
203 int xe_sync_entry_wait(struct xe_sync_entry *sync) in xe_sync_entry_wait() argument
205 if (sync->fence) in xe_sync_entry_wait()
206 dma_fence_wait(sync->fence, true); in xe_sync_entry_wait()
211 int xe_sync_entry_add_deps(struct xe_sync_entry *sync, struct xe_sched_job *job) in xe_sync_entry_add_deps() argument
215 if (sync->fence) { in xe_sync_entry_add_deps()
216 err = drm_sched_job_add_dependency(&job->drm, in xe_sync_entry_add_deps()
217 dma_fence_get(sync->fence)); in xe_sync_entry_add_deps()
219 dma_fence_put(sync->fence); in xe_sync_entry_add_deps()
227 void xe_sync_entry_signal(struct xe_sync_entry *sync, struct xe_sched_job *job, in xe_sync_entry_signal() argument
230 if (!(sync->flags & DRM_XE_SYNC_FLAG_SIGNAL)) in xe_sync_entry_signal()
233 if (sync->chain_fence) { in xe_sync_entry_signal()
234 drm_syncobj_add_point(sync->syncobj, sync->chain_fence, in xe_sync_entry_signal()
235 fence, sync->timeline_value); in xe_sync_entry_signal()
240 sync->chain_fence = NULL; in xe_sync_entry_signal()
241 } else if (sync->syncobj) { in xe_sync_entry_signal()
242 drm_syncobj_replace_fence(sync->syncobj, fence); in xe_sync_entry_signal()
243 } else if (sync->ufence) { in xe_sync_entry_signal()
247 user_fence_get(sync->ufence); in xe_sync_entry_signal()
248 err = dma_fence_add_callback(fence, &sync->ufence->cb, in xe_sync_entry_signal()
250 if (err == -ENOENT) { in xe_sync_entry_signal()
251 kick_ufence(sync->ufence, fence); in xe_sync_entry_signal()
254 user_fence_put(sync->ufence); in xe_sync_entry_signal()
257 } else if (sync->type == DRM_XE_SYNC_TYPE_USER_FENCE) { in xe_sync_entry_signal()
258 job->user_fence.used = true; in xe_sync_entry_signal()
259 job->user_fence.addr = sync->addr; in xe_sync_entry_signal()
260 job->user_fence.value = sync->timeline_value; in xe_sync_entry_signal()
264 void xe_sync_entry_cleanup(struct xe_sync_entry *sync) in xe_sync_entry_cleanup() argument
266 if (sync->syncobj) in xe_sync_entry_cleanup()
267 drm_syncobj_put(sync->syncobj); in xe_sync_entry_cleanup()
268 if (sync->fence) in xe_sync_entry_cleanup()
269 dma_fence_put(sync->fence); in xe_sync_entry_cleanup()
270 if (sync->chain_fence) in xe_sync_entry_cleanup()
271 dma_fence_put(&sync->chain_fence->base); in xe_sync_entry_cleanup()
272 if (sync->ufence) in xe_sync_entry_cleanup()
273 user_fence_put(sync->ufence); in xe_sync_entry_cleanup()
277 * xe_sync_in_fence_get() - Get a fence from syncs, exec queue, and VM
278 * @sync: input syncs
283 * Get a fence from syncs, exec queue, and VM. If syncs contain in-fences create
284 * and return a composite fence of all in-fences + last fence. If no in-fences
288 * Return: fence on success, ERR_PTR(-ENOMEM) on failure
291 xe_sync_in_fence_get(struct xe_sync_entry *sync, int num_sync, in xe_sync_in_fence_get() argument
299 lockdep_assert_held(&vm->lock); in xe_sync_in_fence_get()
301 /* Count in-fences */ in xe_sync_in_fence_get()
303 if (sync[i].fence) { in xe_sync_in_fence_get()
305 fence = sync[i].fence; in xe_sync_in_fence_get()
316 fences = kmalloc_array(num_in_fence + 1, sizeof(*fences), GFP_KERNEL); in xe_sync_in_fence_get()
318 return ERR_PTR(-ENOMEM); in xe_sync_in_fence_get()
320 if (sync[i].fence) { in xe_sync_in_fence_get()
321 dma_fence_get(sync[i].fence); in xe_sync_in_fence_get()
322 fences[current_fence++] = sync[i].fence; in xe_sync_in_fence_get()
327 vm->composite_fence_ctx, in xe_sync_in_fence_get()
328 vm->composite_fence_seqno++, in xe_sync_in_fence_get()
331 --vm->composite_fence_seqno; in xe_sync_in_fence_get()
335 return &cf->base; in xe_sync_in_fence_get()
339 dma_fence_put(fences[--current_fence]); in xe_sync_in_fence_get()
343 return ERR_PTR(-ENOMEM); in xe_sync_in_fence_get()
347 * xe_sync_ufence_get() - Get user fence from sync
348 * @sync: input sync
350 * Get a user fence reference from sync.
354 struct xe_user_fence *xe_sync_ufence_get(struct xe_sync_entry *sync) in xe_sync_ufence_get() argument
356 user_fence_get(sync->ufence); in xe_sync_ufence_get()
358 return sync->ufence; in xe_sync_ufence_get()
362 * xe_sync_ufence_put() - Put user fence reference
372 * xe_sync_ufence_get_status() - Get user fence status
375 * Return: 1 if signalled, 0 not signalled, <0 on error
379 return READ_ONCE(ufence->signalled); in xe_sync_ufence_get_status()