linux_dma_fence.c revision 1.15 1 /* $NetBSD: linux_dma_fence.c,v 1.15 2021/12/19 11:09:17 riastradh Exp $ */
2
3 /*-
4 * Copyright (c) 2018 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Taylor R. Campbell.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: linux_dma_fence.c,v 1.15 2021/12/19 11:09:17 riastradh Exp $");
34
35 #include <sys/atomic.h>
36 #include <sys/condvar.h>
37 #include <sys/queue.h>
38
39 #include <linux/atomic.h>
40 #include <linux/dma-fence.h>
41 #include <linux/errno.h>
42 #include <linux/kref.h>
43 #include <linux/sched.h>
44 #include <linux/spinlock.h>
45
46 /*
47 * linux_dma_fence_trace
48 *
49 * True if we print DMA_FENCE_TRACE messages, false if not. These
50 * are extremely noisy, too much even for AB_VERBOSE and AB_DEBUG
51 * in boothowto.
52 */
53 int linux_dma_fence_trace = 0;
54
55 /*
56 * dma_fence_referenced_p(fence)
57 *
58 * True if fence has a positive reference count. True after
59 * dma_fence_init; after the last dma_fence_put, this becomes
60 * false.
61 */
62 static inline bool __diagused
63 dma_fence_referenced_p(struct dma_fence *fence)
64 {
65
66 return kref_referenced_p(&fence->refcount);
67 }
68
69 /*
70 * dma_fence_init(fence, ops, lock, context, seqno)
71 *
72 * Initialize fence. Caller should call dma_fence_destroy when
73 * done, after all references have been released.
74 */
75 void
76 dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
77 spinlock_t *lock, unsigned context, unsigned seqno)
78 {
79
80 kref_init(&fence->refcount);
81 fence->lock = lock;
82 fence->flags = 0;
83 fence->context = context;
84 fence->seqno = seqno;
85 fence->ops = ops;
86 TAILQ_INIT(&fence->f_callbacks);
87 cv_init(&fence->f_cv, "dmafence");
88 }
89
90 /*
91 * dma_fence_destroy(fence)
92 *
93 * Clean up memory initialized with dma_fence_init. This is meant
94 * to be used after a fence release callback.
95 */
96 void
97 dma_fence_destroy(struct dma_fence *fence)
98 {
99
100 KASSERT(!dma_fence_referenced_p(fence));
101
102 KASSERT(TAILQ_EMPTY(&fence->f_callbacks));
103 cv_destroy(&fence->f_cv);
104 }
105
106 static void
107 dma_fence_free_cb(struct rcu_head *rcu)
108 {
109 struct dma_fence *fence = container_of(rcu, struct dma_fence, f_rcu);
110
111 KASSERT(!dma_fence_referenced_p(fence));
112
113 dma_fence_destroy(fence);
114 kfree(fence);
115 }
116
117 /*
118 * dma_fence_free(fence)
119 *
120 * Schedule fence to be destroyed and then freed with kfree after
121 * any pending RCU read sections on all CPUs have completed.
122 * Caller must guarantee all references have been released. This
123 * is meant to be used after a fence release callback.
124 *
125 * NOTE: Callers assume kfree will be used. We don't even use
126 * kmalloc to allocate these -- caller is expected to allocate
127 * memory with kmalloc to be initialized with dma_fence_init.
128 */
129 void
130 dma_fence_free(struct dma_fence *fence)
131 {
132
133 KASSERT(!dma_fence_referenced_p(fence));
134
135 call_rcu(&fence->f_rcu, &dma_fence_free_cb);
136 }
137
138 /*
139 * dma_fence_context_alloc(n)
140 *
141 * Return the first of a contiguous sequence of unique
142 * identifiers, at least until the system wraps around.
143 */
144 unsigned
145 dma_fence_context_alloc(unsigned n)
146 {
147 static volatile unsigned next_context = 0;
148
149 return atomic_add_int_nv(&next_context, n) - n;
150 }
151
152 /*
153 * dma_fence_is_later(a, b)
154 *
155 * True if the sequence number of fence a is later than the
156 * sequence number of fence b. Since sequence numbers wrap
157 * around, we define this to mean that the sequence number of
158 * fence a is no more than INT_MAX past the sequence number of
159 * fence b.
160 *
161 * The two fences must have the same context.
162 */
163 bool
164 dma_fence_is_later(struct dma_fence *a, struct dma_fence *b)
165 {
166
167 KASSERTMSG(a->context == b->context, "incommensurate fences"
168 ": %u @ %p =/= %u @ %p", a->context, a, b->context, b);
169
170 return a->seqno - b->seqno < INT_MAX;
171 }
172
173 /*
174 * dma_fence_get_stub()
175 *
176 * Return a dma fence that is always already signalled.
177 */
178 struct dma_fence *
179 dma_fence_get_stub(void)
180 {
181 /*
182 * XXX This probably isn't good enough -- caller may try
183 * operations on this that require the lock, which will
184 * require us to create and destroy the lock on module
185 * load/unload.
186 */
187 static struct dma_fence fence = {
188 .refcount = {1}, /* always referenced */
189 .flags = 1u << DMA_FENCE_FLAG_SIGNALED_BIT,
190 };
191
192 return dma_fence_get(&fence);
193 }
194
195 /*
196 * dma_fence_get(fence)
197 *
198 * Acquire a reference to fence. The fence must not be being
199 * destroyed. Return the fence.
200 */
201 struct dma_fence *
202 dma_fence_get(struct dma_fence *fence)
203 {
204
205 if (fence)
206 kref_get(&fence->refcount);
207 return fence;
208 }
209
210 /*
211 * dma_fence_get_rcu(fence)
212 *
213 * Attempt to acquire a reference to a fence that may be about to
214 * be destroyed, during a read section. Return the fence on
215 * success, or NULL on failure.
216 */
217 struct dma_fence *
218 dma_fence_get_rcu(struct dma_fence *fence)
219 {
220
221 __insn_barrier();
222 if (!kref_get_unless_zero(&fence->refcount))
223 return NULL;
224 return fence;
225 }
226
227 /*
228 * dma_fence_get_rcu_safe(fencep)
229 *
230 * Attempt to acquire a reference to the fence *fencep, which may
231 * be about to be destroyed, during a read section. If the value
232 * of *fencep changes after we read *fencep but before we
233 * increment its reference count, retry. Return *fencep on
234 * success, or NULL on failure.
235 */
236 struct dma_fence *
237 dma_fence_get_rcu_safe(struct dma_fence *volatile const *fencep)
238 {
239 struct dma_fence *fence, *fence0;
240
241 retry:
242 fence = *fencep;
243
244 /* Load fence only once. */
245 __insn_barrier();
246
247 /* If there's nothing there, give up. */
248 if (fence == NULL)
249 return NULL;
250
251 /* Make sure we don't load stale fence guts. */
252 membar_datadep_consumer();
253
254 /* Try to acquire a reference. If we can't, try again. */
255 if (!dma_fence_get_rcu(fence))
256 goto retry;
257
258 /*
259 * Confirm that it's still the same fence. If not, release it
260 * and retry.
261 */
262 fence0 = *fencep;
263 __insn_barrier();
264 if (fence != fence0) {
265 dma_fence_put(fence);
266 goto retry;
267 }
268
269 /* Success! */
270 return fence;
271 }
272
273 static void
274 dma_fence_release(struct kref *refcount)
275 {
276 struct dma_fence *fence = container_of(refcount, struct dma_fence,
277 refcount);
278
279 KASSERT(!dma_fence_referenced_p(fence));
280
281 if (fence->ops->release)
282 (*fence->ops->release)(fence);
283 else
284 dma_fence_free(fence);
285 }
286
287 /*
288 * dma_fence_put(fence)
289 *
290 * Release a reference to fence. If this was the last one, call
291 * the fence's release callback.
292 */
293 void
294 dma_fence_put(struct dma_fence *fence)
295 {
296
297 if (fence == NULL)
298 return;
299 KASSERT(dma_fence_referenced_p(fence));
300 kref_put(&fence->refcount, &dma_fence_release);
301 }
302
303 /*
304 * dma_fence_ensure_signal_enabled(fence)
305 *
306 * Internal subroutine. If the fence was already signalled,
307 * return -ENOENT. Otherwise, if the enable signalling callback
308 * has not been called yet, call it. If fails, signal the fence
309 * and return -ENOENT. If it succeeds, or if it had already been
310 * called, return zero to indicate success.
311 *
312 * Caller must hold the fence's lock.
313 */
314 static int
315 dma_fence_ensure_signal_enabled(struct dma_fence *fence)
316 {
317
318 KASSERT(dma_fence_referenced_p(fence));
319 KASSERT(spin_is_locked(fence->lock));
320
321 /* If the fence was already signalled, fail with -ENOENT. */
322 if (fence->flags & (1u << DMA_FENCE_FLAG_SIGNALED_BIT))
323 return -ENOENT;
324
325 /*
326 * If the enable signaling callback has been called, success.
327 * Otherwise, set the bit indicating it.
328 */
329 if (test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags))
330 return 0;
331
332 /* Otherwise, note that we've called it and call it. */
333 KASSERT(fence->ops->enable_signaling);
334 if (!(*fence->ops->enable_signaling)(fence)) {
335 /* If it failed, signal and return -ENOENT. */
336 dma_fence_signal_locked(fence);
337 return -ENOENT;
338 }
339
340 /* Success! */
341 return 0;
342 }
343
344 /*
345 * dma_fence_add_callback(fence, fcb, fn)
346 *
347 * If fence has been signalled, return -ENOENT. If the enable
348 * signalling callback hasn't been called yet, call it; if it
349 * fails, return -ENOENT. Otherwise, arrange to call fn(fence,
350 * fcb) when it is signalled, and return 0.
351 *
352 * The fence uses memory allocated by the caller in fcb from the
353 * time of dma_fence_add_callback either to the time of
354 * dma_fence_remove_callback, or just before calling fn.
355 */
356 int
357 dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *fcb,
358 dma_fence_func_t fn)
359 {
360 int ret;
361
362 KASSERT(dma_fence_referenced_p(fence));
363
364 /* Optimistically try to skip the lock if it's already signalled. */
365 if (fence->flags & (1u << DMA_FENCE_FLAG_SIGNALED_BIT)) {
366 ret = -ENOENT;
367 goto out0;
368 }
369
370 /* Acquire the lock. */
371 spin_lock(fence->lock);
372
373 /* Ensure signalling is enabled, or fail if we can't. */
374 ret = dma_fence_ensure_signal_enabled(fence);
375 if (ret)
376 goto out1;
377
378 /* Insert the callback. */
379 fcb->func = fn;
380 TAILQ_INSERT_TAIL(&fence->f_callbacks, fcb, fcb_entry);
381 fcb->fcb_onqueue = true;
382
383 /* Release the lock and we're done. */
384 out1: spin_unlock(fence->lock);
385 out0: return ret;
386 }
387
388 /*
389 * dma_fence_remove_callback(fence, fcb)
390 *
391 * Remove the callback fcb from fence. Return true if it was
392 * removed from the list, or false if it had already run and so
393 * was no longer queued anyway. Caller must have already called
394 * dma_fence_add_callback(fence, fcb).
395 */
396 bool
397 dma_fence_remove_callback(struct dma_fence *fence, struct dma_fence_cb *fcb)
398 {
399 bool onqueue;
400
401 KASSERT(dma_fence_referenced_p(fence));
402
403 spin_lock(fence->lock);
404 onqueue = fcb->fcb_onqueue;
405 if (onqueue) {
406 TAILQ_REMOVE(&fence->f_callbacks, fcb, fcb_entry);
407 fcb->fcb_onqueue = false;
408 }
409 spin_unlock(fence->lock);
410
411 return onqueue;
412 }
413
414 /*
415 * dma_fence_enable_sw_signaling(fence)
416 *
417 * If it hasn't been called yet and the fence hasn't been
418 * signalled yet, call the fence's enable_sw_signaling callback.
419 * If when that happens, the callback indicates failure by
420 * returning false, signal the fence.
421 */
422 void
423 dma_fence_enable_sw_signaling(struct dma_fence *fence)
424 {
425
426 KASSERT(dma_fence_referenced_p(fence));
427
428 spin_lock(fence->lock);
429 (void)dma_fence_ensure_signal_enabled(fence);
430 spin_unlock(fence->lock);
431 }
432
433 /*
434 * dma_fence_is_signaled(fence)
435 *
436 * Test whether the fence has been signalled. If it has been
437 * signalled by dma_fence_signal(_locked), return true. If the
438 * signalled callback returns true indicating that some implicit
439 * external condition has changed, call the callbacks as if with
440 * dma_fence_signal.
441 */
442 bool
443 dma_fence_is_signaled(struct dma_fence *fence)
444 {
445 bool signaled;
446
447 KASSERT(dma_fence_referenced_p(fence));
448
449 spin_lock(fence->lock);
450 signaled = dma_fence_is_signaled_locked(fence);
451 spin_unlock(fence->lock);
452
453 return signaled;
454 }
455
456 /*
457 * dma_fence_is_signaled_locked(fence)
458 *
459 * Test whether the fence has been signalled. Like
460 * dma_fence_is_signaleed, but caller already holds the fence's lock.
461 */
462 bool
463 dma_fence_is_signaled_locked(struct dma_fence *fence)
464 {
465
466 KASSERT(dma_fence_referenced_p(fence));
467 KASSERT(spin_is_locked(fence->lock));
468
469 /* Check whether we already set the signalled bit. */
470 if (fence->flags & (1u << DMA_FENCE_FLAG_SIGNALED_BIT))
471 return true;
472
473 /* If there's a signalled callback, test it. */
474 if (fence->ops->signaled) {
475 if ((*fence->ops->signaled)(fence)) {
476 /*
477 * It's been signalled implicitly by some
478 * external phenomonen. Act as though someone
479 * has called dma_fence_signal.
480 */
481 dma_fence_signal_locked(fence);
482 return true;
483 }
484 }
485
486 return false;
487 }
488
489 /*
490 * dma_fence_set_error(fence, error)
491 *
492 * Set an error code prior to dma_fence_signal for use by a
493 * waiter to learn about success or failure of the fence.
494 */
495 void
496 dma_fence_set_error(struct dma_fence *fence, int error)
497 {
498
499 KASSERT(!(fence->flags & (1u << DMA_FENCE_FLAG_SIGNALED_BIT)));
500 KASSERTMSG(error >= -ELAST, "%d", error);
501 KASSERTMSG(error < 0, "%d", error);
502
503 fence->error = error;
504 }
505
506 /*
507 * dma_fence_get_status(fence)
508 *
509 * Return 0 if fence has yet to be signalled, 1 if it has been
510 * signalled without error, or negative error code if
511 * dma_fence_set_error was used.
512 */
513 int
514 dma_fence_get_status(struct dma_fence *fence)
515 {
516 int ret;
517
518 spin_lock(fence->lock);
519 if (!dma_fence_is_signaled_locked(fence)) {
520 ret = 0;
521 } else if (fence->error) {
522 ret = fence->error;
523 KASSERTMSG(ret < 0, "%d", ret);
524 } else {
525 ret = 1;
526 }
527 spin_unlock(fence->lock);
528
529 return ret;
530 }
531
532 /*
533 * dma_fence_signal(fence)
534 *
535 * Signal the fence. If it has already been signalled, return
536 * -EINVAL. If it has not been signalled, call the enable
537 * signalling callback if it hasn't been called yet, and remove
538 * each registered callback from the queue and call it; then
539 * return 0.
540 */
541 int
542 dma_fence_signal(struct dma_fence *fence)
543 {
544 int ret;
545
546 KASSERT(dma_fence_referenced_p(fence));
547
548 spin_lock(fence->lock);
549 ret = dma_fence_signal_locked(fence);
550 spin_unlock(fence->lock);
551
552 return ret;
553 }
554
555 /*
556 * dma_fence_signal_locked(fence)
557 *
558 * Signal the fence. Like dma_fence_signal, but caller already
559 * holds the fence's lock.
560 */
561 int
562 dma_fence_signal_locked(struct dma_fence *fence)
563 {
564 struct dma_fence_cb *fcb, *next;
565
566 KASSERT(dma_fence_referenced_p(fence));
567 KASSERT(spin_is_locked(fence->lock));
568
569 /* If it's been signalled, fail; otherwise set the signalled bit. */
570 if (test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
571 return -EINVAL;
572
573 /* Wake waiters. */
574 cv_broadcast(&fence->f_cv);
575
576 /* Remove and call the callbacks. */
577 TAILQ_FOREACH_SAFE(fcb, &fence->f_callbacks, fcb_entry, next) {
578 TAILQ_REMOVE(&fence->f_callbacks, fcb, fcb_entry);
579 fcb->fcb_onqueue = false;
580 (*fcb->func)(fence, fcb);
581 }
582
583 /* Success! */
584 return 0;
585 }
586
587 struct wait_any {
588 struct dma_fence_cb fcb;
589 struct wait_any1 {
590 kmutex_t lock;
591 kcondvar_t cv;
592 bool done;
593 uint32_t *ip;
594 struct wait_any *cb;
595 } *common;
596 };
597
598 static void
599 wait_any_cb(struct dma_fence *fence, struct dma_fence_cb *fcb)
600 {
601 struct wait_any *cb = container_of(fcb, struct wait_any, fcb);
602
603 KASSERT(dma_fence_referenced_p(fence));
604
605 mutex_enter(&cb->common->lock);
606 cb->common->done = true;
607 if (cb->common->ip)
608 *cb->common->ip = cb - cb->common->cb;
609 cv_broadcast(&cb->common->cv);
610 mutex_exit(&cb->common->lock);
611 }
612
613 /*
614 * dma_fence_wait_any_timeout(fence, nfences, intr, timeout, ip)
615 *
616 * Wait for any of fences[0], fences[1], fences[2], ...,
617 * fences[nfences-1] to be signalled. If ip is nonnull, set *ip
618 * to the index of the first one.
619 */
620 long
621 dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t nfences,
622 bool intr, long timeout, uint32_t *ip)
623 {
624 struct wait_any1 common;
625 struct wait_any *cb;
626 uint32_t i, j;
627 int start, end;
628 long ret = 0;
629
630 /* Allocate an array of callback records. */
631 cb = kcalloc(nfences, sizeof(cb[0]), GFP_KERNEL);
632 if (cb == NULL) {
633 ret = -ENOMEM;
634 goto out0;
635 }
636
637 /* Initialize a mutex and condvar for the common wait. */
638 mutex_init(&common.lock, MUTEX_DEFAULT, IPL_VM);
639 cv_init(&common.cv, "fence");
640 common.done = false;
641 common.ip = ip;
642 common.cb = cb;
643
644 /* Add a callback to each of the fences, or stop here if we can't. */
645 for (i = 0; i < nfences; i++) {
646 cb[i].common = &common;
647 KASSERT(dma_fence_referenced_p(fences[i]));
648 ret = dma_fence_add_callback(fences[i], &cb[i].fcb,
649 &wait_any_cb);
650 if (ret)
651 goto out1;
652 }
653
654 /*
655 * Test whether any of the fences has been signalled. If they
656 * have, stop here. If the haven't, we are guaranteed to be
657 * notified by one of the callbacks when they have.
658 */
659 for (j = 0; j < nfences; j++) {
660 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fences[j]->flags)) {
661 if (ip)
662 *ip = j;
663 ret = 0;
664 goto out1;
665 }
666 }
667
668 /*
669 * None of them was ready immediately. Wait for one of the
670 * callbacks to notify us when it is done.
671 */
672 mutex_enter(&common.lock);
673 while (timeout > 0 && !common.done) {
674 start = getticks();
675 __insn_barrier();
676 if (intr) {
677 if (timeout != MAX_SCHEDULE_TIMEOUT) {
678 ret = -cv_timedwait_sig(&common.cv,
679 &common.lock, MIN(timeout, /* paranoia */
680 MAX_SCHEDULE_TIMEOUT));
681 } else {
682 ret = -cv_wait_sig(&common.cv, &common.lock);
683 }
684 } else {
685 if (timeout != MAX_SCHEDULE_TIMEOUT) {
686 ret = -cv_timedwait(&common.cv,
687 &common.lock, MIN(timeout, /* paranoia */
688 MAX_SCHEDULE_TIMEOUT));
689 } else {
690 cv_wait(&common.cv, &common.lock);
691 ret = 0;
692 }
693 }
694 end = getticks();
695 __insn_barrier();
696 if (ret) {
697 if (ret == -ERESTART)
698 ret = -ERESTARTSYS;
699 break;
700 }
701 timeout -= MIN(timeout, (unsigned)end - (unsigned)start);
702 }
703 mutex_exit(&common.lock);
704
705 /*
706 * Massage the return code: if we were interrupted, return
707 * ERESTARTSYS; if cv_timedwait timed out, return 0; otherwise
708 * return the remaining time.
709 */
710 if (ret < 0) {
711 if (ret == -EINTR || ret == -ERESTART)
712 ret = -ERESTARTSYS;
713 if (ret == -EWOULDBLOCK)
714 ret = 0;
715 } else {
716 KASSERT(ret == 0);
717 ret = timeout;
718 }
719
720 out1: while (i --> 0)
721 (void)dma_fence_remove_callback(fences[i], &cb[i].fcb);
722 cv_destroy(&common.cv);
723 mutex_destroy(&common.lock);
724 kfree(cb);
725 out0: return ret;
726 }
727
728 /*
729 * dma_fence_wait_timeout(fence, intr, timeout)
730 *
731 * Wait until fence is signalled; or until interrupt, if intr is
732 * true; or until timeout, if positive. Return -ERESTARTSYS if
733 * interrupted, negative error code on any other error, zero on
734 * timeout, or positive number of ticks remaining if the fence is
735 * signalled before the timeout. Works by calling the fence wait
736 * callback.
737 *
738 * The timeout must be nonnegative and less than
739 * MAX_SCHEDULE_TIMEOUT.
740 */
741 long
742 dma_fence_wait_timeout(struct dma_fence *fence, bool intr, long timeout)
743 {
744
745 KASSERT(dma_fence_referenced_p(fence));
746 KASSERT(timeout >= 0);
747 KASSERT(timeout < MAX_SCHEDULE_TIMEOUT);
748
749 if (fence->ops->wait)
750 return (*fence->ops->wait)(fence, intr, timeout);
751 else
752 return dma_fence_default_wait(fence, intr, timeout);
753 }
754
755 /*
756 * dma_fence_wait(fence, intr)
757 *
758 * Wait until fence is signalled; or until interrupt, if intr is
759 * true. Return -ERESTARTSYS if interrupted, negative error code
760 * on any other error, zero on sucess. Works by calling the fence
761 * wait callback with MAX_SCHEDULE_TIMEOUT.
762 */
763 long
764 dma_fence_wait(struct dma_fence *fence, bool intr)
765 {
766 long ret;
767
768 KASSERT(dma_fence_referenced_p(fence));
769
770 if (fence->ops->wait)
771 ret = (*fence->ops->wait)(fence, intr, MAX_SCHEDULE_TIMEOUT);
772 else
773 ret = dma_fence_default_wait(fence, intr,
774 MAX_SCHEDULE_TIMEOUT);
775 KASSERT(ret != 0);
776
777 return (ret < 0 ? ret : 0);
778 }
779
780 /*
781 * dma_fence_default_wait(fence, intr, timeout)
782 *
783 * Default implementation of fence wait callback using a condition
784 * variable. If the fence is already signalled, return timeout,
785 * or 1 if no timeout. If the enable signalling callback hasn't
786 * been called, call it, and if it fails, act as if the fence had
787 * been signalled. Otherwise, wait on the internal condvar. If
788 * timeout is MAX_SCHEDULE_TIMEOUT, treat it as no timeout.
789 */
790 long
791 dma_fence_default_wait(struct dma_fence *fence, bool intr, long timeout)
792 {
793 int starttime = 0, now = 0, deadline = 0; /* XXXGCC */
794 kmutex_t *lock = &fence->lock->sl_lock;
795 long ret = 0;
796
797 KASSERT(dma_fence_referenced_p(fence));
798 KASSERTMSG(timeout >= 0, "timeout %ld", timeout);
799 KASSERTMSG(timeout <= MAX_SCHEDULE_TIMEOUT, "timeout %ld", timeout);
800
801 /* Optimistically try to skip the lock if it's already signalled. */
802 if (fence->flags & (1u << DMA_FENCE_FLAG_SIGNALED_BIT))
803 return (timeout < MAX_SCHEDULE_TIMEOUT ? timeout : 1);
804
805 /* Acquire the lock. */
806 spin_lock(fence->lock);
807
808 /* Ensure signalling is enabled, or fail if we can't. */
809 ret = dma_fence_ensure_signal_enabled(fence);
810 if (ret)
811 goto out;
812
813 /* Find out what our deadline is so we can handle spurious wakeup. */
814 if (timeout < MAX_SCHEDULE_TIMEOUT) {
815 now = getticks();
816 __insn_barrier();
817 starttime = now;
818 deadline = starttime + timeout;
819 }
820
821 /* Wait until the signalled bit is set. */
822 while (!(fence->flags & (1u << DMA_FENCE_FLAG_SIGNALED_BIT))) {
823 /*
824 * If there's a timeout and we've passed the deadline,
825 * give up.
826 */
827 if (timeout < MAX_SCHEDULE_TIMEOUT) {
828 now = getticks();
829 __insn_barrier();
830 if (deadline <= now)
831 break;
832 }
833 if (intr) {
834 if (timeout < MAX_SCHEDULE_TIMEOUT) {
835 ret = -cv_timedwait_sig(&fence->f_cv, lock,
836 deadline - now);
837 } else {
838 ret = -cv_wait_sig(&fence->f_cv, lock);
839 }
840 } else {
841 if (timeout < MAX_SCHEDULE_TIMEOUT) {
842 ret = -cv_timedwait(&fence->f_cv, lock,
843 deadline - now);
844 } else {
845 cv_wait(&fence->f_cv, lock);
846 ret = 0;
847 }
848 }
849 /* If the wait failed, give up. */
850 if (ret) {
851 if (ret == -ERESTART)
852 ret = -ERESTARTSYS;
853 break;
854 }
855 }
856
857 out:
858 /* All done. Release the lock. */
859 spin_unlock(fence->lock);
860
861 /* If cv_timedwait gave up, return 0 meaning timeout. */
862 if (ret == -EWOULDBLOCK) {
863 /* Only cv_timedwait and cv_timedwait_sig can return this. */
864 KASSERT(timeout < MAX_SCHEDULE_TIMEOUT);
865 return 0;
866 }
867
868 /* If there was a timeout and the deadline passed, return 0. */
869 if (timeout < MAX_SCHEDULE_TIMEOUT) {
870 if (deadline <= now)
871 return 0;
872 }
873
874 /* If we were interrupted, return -ERESTARTSYS. */
875 if (ret == -EINTR || ret == -ERESTART)
876 return -ERESTARTSYS;
877
878 /* If there was any other kind of error, fail. */
879 if (ret)
880 return ret;
881
882 /*
883 * Success! Return the number of ticks left, at least 1, or 1
884 * if no timeout.
885 */
886 return (timeout < MAX_SCHEDULE_TIMEOUT ? MIN(deadline - now, 1) : 1);
887 }
888
889 /*
890 * __dma_fence_signal(fence)
891 *
892 * Set fence's signalled bit, without waking waiters yet. Return
893 * true if it was newly set, false if it was already set.
894 */
895 bool
896 __dma_fence_signal(struct dma_fence *fence)
897 {
898
899 if (test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
900 return false;
901
902 return true;
903 }
904
905 /*
906 * __dma_fence_signal_wake(fence)
907 *
908 * Wake fence's waiters. Caller must have previously called
909 * __dma_fence_signal and it must have previously returned true.
910 */
911 void
912 __dma_fence_signal_wake(struct dma_fence *fence, ktime_t timestamp)
913 {
914 struct dma_fence_cb *fcb, *next;
915
916 spin_lock(fence->lock);
917
918 KASSERT(fence->flags & DMA_FENCE_FLAG_SIGNALED_BIT);
919
920 /* Wake waiters. */
921 cv_broadcast(&fence->f_cv);
922
923 /* Remove and call the callbacks. */
924 TAILQ_FOREACH_SAFE(fcb, &fence->f_callbacks, fcb_entry, next) {
925 TAILQ_REMOVE(&fence->f_callbacks, fcb, fcb_entry);
926 fcb->fcb_onqueue = false;
927 (*fcb->func)(fence, fcb);
928 }
929
930 spin_unlock(fence->lock);
931 }
932