XenevaOS
Loading...
Searching...
No Matches
dma-fence.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Fence mechanism for dma-buf to allow for asynchronous dma access
4 *
5 * Copyright (C) 2012 Canonical Ltd
6 * Copyright (C) 2012 Texas Instruments
7 *
8 * Authors:
9 * Rob Clark <robdclark@gmail.com>
10 * Maarten Lankhorst <maarten.lankhorst@canonical.com>
11 */
12
13#ifndef __LINUX_DMA_FENCE_H
14#define __LINUX_DMA_FENCE_H
15
16#include <linux/err.h>
17#include <linux/wait.h>
18#include <linux/list.h>
19#include <linux/bitops.h>
20#include <linux/kref.h>
21#include <linux/sched.h>
22#include <linux/printk.h>
23#include <linux/rcupdate.h>
24#include <linux/timekeeping.h>
25
26struct dma_fence;
27struct dma_fence_ops;
28struct dma_fence_cb;
29struct seq_file;
30
70struct dma_fence {
71 union {
74 };
75 const struct dma_fence_ops __rcu *ops;
76 /*
77 * We clear the callback list on kref_put so that by the time we
78 * release the fence it is unused. No one should be adding to the
79 * cb_list that they don't themselves hold a reference for.
80 *
81 * The lifetime of the timestamp is similarly tied to both the
82 * rcu freelist and the cb_list. The timestamp is only set upon
83 * signaling while simultaneously notifying the cb_list. Ergo, we
84 * only use either the cb_list of timestamp. Upon destruction,
85 * neither are accessible, and so we can use the rcu. This means
86 * that the cb_list is *only* valid until the signal bit is set,
87 * and to read either you *must* hold a reference to the fence,
88 * and not just the rcu_read_lock.
89 *
90 * Listed in chronological order.
91 */
92 union {
93 struct list_head cb_list;
94 /* @cb_list replaced by @timestamp on dma_fence_signal() */
96 /* @timestamp replaced by @rcu on dma_fence_release() */
97 struct rcu_head rcu;
98 };
101 unsigned long flags;
103 int error;
104};
105
115
116typedef void (*dma_fence_func_t)(struct dma_fence *fence,
117 struct dma_fence_cb *cb);
118
131
146 const char * (*get_driver_name)(struct dma_fence *fence);
147
158 const char * (*get_timeline_name)(struct dma_fence *fence);
159
195 bool (*enable_signaling)(struct dma_fence *fence);
196
212 bool (*signaled)(struct dma_fence *fence);
213
234 signed long (*wait)(struct dma_fence *fence,
235 bool intr, signed long timeout);
236
252 void (*release)(struct dma_fence *fence);
253
272 void (*set_deadline)(struct dma_fence *fence, ktime_t deadline);
273};
274
275void dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops,
276 spinlock_t *lock, u64 context, u64 seqno);
277
278void dma_fence_init64(struct dma_fence *fence, const struct dma_fence_ops *ops,
279 spinlock_t *lock, u64 context, u64 seqno);
280
282void dma_fence_free(struct dma_fence *fence);
283void dma_fence_describe(struct dma_fence *fence, struct seq_file *seq);
284
293static inline bool dma_fence_was_initialized(struct dma_fence *fence)
294{
295 return fence && test_bit(DMA_FENCE_FLAG_INITIALIZED_BIT, &fence->flags);
296}
297
302static inline void dma_fence_put(struct dma_fence *fence)
303{
304 if (fence)
305 kref_put(&fence->refcount, dma_fence_release);
306}
307
314static inline struct dma_fence *dma_fence_get(struct dma_fence *fence)
315{
316 if (fence)
317 kref_get(&fence->refcount);
318 return fence;
319}
320
328static inline struct dma_fence *dma_fence_get_rcu(struct dma_fence *fence)
329{
330 if (kref_get_unless_zero(&fence->refcount))
331 return fence;
332 else
333 return NULL;
334}
335
352static inline struct dma_fence *
353dma_fence_get_rcu_safe(struct dma_fence __rcu **fencep)
354{
355 do {
356 struct dma_fence *fence;
357
358 fence = rcu_dereference(*fencep);
359 if (!fence)
360 return NULL;
361
362 if (!dma_fence_get_rcu(fence))
363 continue;
364
365 /* The atomic_inc_not_zero() inside dma_fence_get_rcu()
366 * provides a full memory barrier upon success (such as now).
367 * This is paired with the write barrier from assigning
368 * to the __rcu protected fence pointer so that if that
369 * pointer still matches the current fence, we know we
370 * have successfully acquire a reference to it. If it no
371 * longer matches, we are holding a reference to some other
372 * reallocated pointer. This is possible if the allocator
373 * is using a freelist like SLAB_TYPESAFE_BY_RCU where the
374 * fence remains valid for the RCU grace period, but it
375 * may be reallocated. When using such allocators, we are
376 * responsible for ensuring the reference we get is to
377 * the right fence, as below.
378 */
379 if (fence == rcu_access_pointer(*fencep))
380 return rcu_pointer_handoff(fence);
381
382 dma_fence_put(fence);
383 } while (1);
384}
385
392static inline spinlock_t *dma_fence_spinlock(struct dma_fence *fence)
393{
395 &fence->inline_lock : fence->extern_lock;
396}
397
405#define dma_fence_lock_irqsave(fence, flags) \
406 spin_lock_irqsave(dma_fence_spinlock(fence), flags)
407
415#define dma_fence_unlock_irqrestore(fence, flags) \
416 spin_unlock_irqrestore(dma_fence_spinlock(fence), flags)
417
422#define dma_fence_assert_held(fence) \
423 lockdep_assert_held(dma_fence_spinlock(fence));
424
425#ifdef CONFIG_LOCKDEP
426bool dma_fence_begin_signalling(void);
427void dma_fence_end_signalling(bool cookie);
428void __dma_fence_might_wait(void);
429#else
430static inline bool dma_fence_begin_signalling(void)
431{
432 return true;
433}
434static inline void dma_fence_end_signalling(bool cookie) {}
435static inline void __dma_fence_might_wait(void) {}
436#endif
437
438void dma_fence_signal(struct dma_fence *fence);
444signed long dma_fence_default_wait(struct dma_fence *fence,
445 bool intr, signed long timeout);
447 struct dma_fence_cb *cb,
448 dma_fence_func_t func);
450 struct dma_fence_cb *cb);
452
473const char __rcu *dma_fence_driver_name(struct dma_fence *fence);
474const char __rcu *dma_fence_timeline_name(struct dma_fence *fence);
475
476/*
477 * dma_fence_test_signaled_flag - Only check whether a fence is signaled yet.
478 * @fence: the fence to check
479 *
480 * This function just checks whether @fence is signaled, without interacting
481 * with the fence in any way. The user must, therefore, ensure through other
482 * means that fences get signaled eventually.
483 *
484 * This function uses test_bit(), which is thread-safe. Naturally, this function
485 * should be used opportunistically; a fence could get signaled at any moment
486 * after the check is done.
487 *
488 * Return: true if signaled, false otherwise.
489 */
490static inline bool
491dma_fence_test_signaled_flag(struct dma_fence *fence)
492{
494}
495
510static inline bool
511dma_fence_is_signaled_locked(struct dma_fence *fence)
512{
513 const struct dma_fence_ops *ops;
514
515 if (dma_fence_test_signaled_flag(fence))
516 return true;
517
519 ops = rcu_dereference(fence->ops);
520 if (ops && ops->signaled && ops->signaled(fence)) {
523 return true;
524 }
526
527 return false;
528}
529
546static inline bool
547dma_fence_is_signaled(struct dma_fence *fence)
548{
549 const struct dma_fence_ops *ops;
550
551 if (dma_fence_test_signaled_flag(fence))
552 return true;
553
555 ops = rcu_dereference(fence->ops);
556 if (ops && ops->signaled && ops->signaled(fence)) {
558 dma_fence_signal(fence);
559 return true;
560 }
562
563 return false;
564}
565
575static inline bool __dma_fence_is_later(struct dma_fence *fence, u64 f1, u64 f2)
576{
577 /* This is for backward compatibility with drivers which can only handle
578 * 32bit sequence numbers. Use a 64bit compare when the driver says to
579 * do so.
580 */
582 return f1 > f2;
583
584 return (int)(lower_32_bits(f1) - lower_32_bits(f2)) > 0;
585}
586
595static inline bool dma_fence_is_later(struct dma_fence *f1,
596 struct dma_fence *f2)
597{
598 if (WARN_ON(f1->context != f2->context))
599 return false;
600
601 return __dma_fence_is_later(f1, f1->seqno, f2->seqno);
602}
603
613static inline bool dma_fence_is_later_or_same(struct dma_fence *f1,
614 struct dma_fence *f2)
615{
616 return f1 == f2 || dma_fence_is_later(f1, f2);
617}
618
628static inline struct dma_fence *dma_fence_later(struct dma_fence *f1,
629 struct dma_fence *f2)
630{
631 if (WARN_ON(f1->context != f2->context))
632 return NULL;
633
634 /*
635 * Can't check just DMA_FENCE_FLAG_SIGNALED_BIT here, it may never
636 * have been set if enable_signaling wasn't called, and enabling that
637 * here is overkill.
638 */
639 if (dma_fence_is_later(f1, f2))
640 return dma_fence_is_signaled(f1) ? NULL : f1;
641 else
642 return dma_fence_is_signaled(f2) ? NULL : f2;
643}
644
659static inline int dma_fence_get_status_locked(struct dma_fence *fence)
660{
661 if (dma_fence_is_signaled_locked(fence))
662 return fence->error ?: 1;
663 else
664 return 0;
665}
666
668
686static inline void dma_fence_set_error(struct dma_fence *fence,
687 int error)
688{
689 WARN_ON(test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags));
690 WARN_ON(error >= 0 || error < -MAX_ERRNO);
691
692 fence->error = error;
693}
694
703static inline ktime_t dma_fence_timestamp(struct dma_fence *fence)
704{
705 if (WARN_ON(!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)))
706 return ktime_get();
707
709 cpu_relax();
710
711 return fence->timestamp;
712}
713
715 bool intr, signed long timeout);
716signed long dma_fence_wait_any_timeout(struct dma_fence **fences,
717 uint32_t count,
718 bool intr, signed long timeout,
719 uint32_t *idx);
720
736static inline signed long dma_fence_wait(struct dma_fence *fence, bool intr)
737{
738 signed long ret;
739
740 /* Since dma_fence_wait_timeout cannot timeout with
741 * MAX_SCHEDULE_TIMEOUT, only valid return values are
742 * -ERESTARTSYS and MAX_SCHEDULE_TIMEOUT.
743 */
745
746 return ret < 0 ? ret : 0;
747}
748
749void dma_fence_set_deadline(struct dma_fence *fence, ktime_t deadline);
750
754
755extern const struct dma_fence_ops dma_fence_array_ops;
756extern const struct dma_fence_ops dma_fence_chain_ops;
757
764static inline bool dma_fence_is_array(struct dma_fence *fence)
765{
766 return rcu_access_pointer(fence->ops) == &dma_fence_array_ops;
767}
768
775static inline bool dma_fence_is_chain(struct dma_fence *fence)
776{
777 return rcu_access_pointer(fence->ops) == &dma_fence_chain_ops;
778}
779
788static inline bool dma_fence_is_container(struct dma_fence *fence)
789{
790 return dma_fence_is_array(fence) || dma_fence_is_chain(fence);
791}
792
793#endif /* __LINUX_DMA_FENCE_H */
#define bool
Definition stdbool.h:35
ChFont * f2
DeodhaiXR – The Graphics compositing pipeline Supports three types of input – (1) Mouse (2) Keyboard ...
Definition main.cpp:358
unsigned int uint32_t
Definition acefiex.h:163
#define NULL
Definition actypes.h:561
#define test_bit(nr, addr)
Definition bitops.h:124
#define __rcu
Definition compiler_types.h:72
const struct dma_fence_ops dma_fence_chain_ops
struct dma_fence * dma_fence_allocate_private_stub(ktime_t timestamp)
bool dma_fence_check_and_signal_locked(struct dma_fence *fence)
void dma_fence_describe(struct dma_fence *fence, struct seq_file *seq)
signed long dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, bool intr, signed long timeout, uint32_t *idx)
struct dma_fence * dma_fence_get_stub(void)
void dma_fence_signal(struct dma_fence *fence)
const char __rcu * dma_fence_driver_name(struct dma_fence *fence)
void dma_fence_signal_locked(struct dma_fence *fence)
void dma_fence_signal_timestamp_locked(struct dma_fence *fence, ktime_t timestamp)
bool dma_fence_remove_callback(struct dma_fence *fence, struct dma_fence_cb *cb)
bool dma_fence_check_and_signal(struct dma_fence *fence)
dma_fence_flag_bits
Definition dma-fence.h:106
@ DMA_FENCE_FLAG_SEQNO64_BIT
Definition dma-fence.h:109
@ DMA_FENCE_FLAG_INITIALIZED_BIT
Definition dma-fence.h:107
@ DMA_FENCE_FLAG_SIGNALED_BIT
Definition dma-fence.h:110
@ DMA_FENCE_FLAG_USER_BITS
Definition dma-fence.h:113
@ DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT
Definition dma-fence.h:112
@ DMA_FENCE_FLAG_INLINE_LOCK_BIT
Definition dma-fence.h:108
@ DMA_FENCE_FLAG_TIMESTAMP_BIT
Definition dma-fence.h:111
void dma_fence_set_deadline(struct dma_fence *fence, ktime_t deadline)
void(* dma_fence_func_t)(struct dma_fence *fence, struct dma_fence_cb *cb)
Definition dma-fence.h:116
int dma_fence_get_status(struct dma_fence *fence)
signed long dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
signed long dma_fence_wait_timeout(struct dma_fence *, bool intr, signed long timeout)
const char __rcu * dma_fence_timeline_name(struct dma_fence *fence)
void dma_fence_release(struct kref *kref)
void dma_fence_init(struct dma_fence *fence, const struct dma_fence_ops *ops, spinlock_t *lock, u64 context, u64 seqno)
void dma_fence_enable_sw_signaling(struct dma_fence *fence)
u64 dma_fence_context_alloc(unsigned num)
void dma_fence_free(struct dma_fence *fence)
void dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp)
const struct dma_fence_ops dma_fence_array_ops
void dma_fence_init64(struct dma_fence *fence, const struct dma_fence_ops *ops, spinlock_t *lock, u64 context, u64 seqno)
int dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb, dma_fence_func_t func)
#define lower_32_bits(n)
Definition kernel.h:581
uint64_t u64
Definition kernel.h:17
int64_t ktime_t
Definition kernel.h:404
#define MAX_ERRNO
Definition kernel.h:304
int spinlock_t
Definition kernel.h:44
#define MAX_SCHEDULE_TIMEOUT
Definition sched.h:93
#define cpu_relax()
Definition processor.h:9
#define rcu_dereference(p)
Definition rcupdate.h:41
#define rcu_read_unlock()
Definition rcupdate.h:33
#define rcu_access_pointer(p)
Definition rcupdate.h:47
#define rcu_read_lock()
Definition rcupdate.h:32
#define rcu_pointer_handoff(p)
Definition rcupdate.h:82
Definition dma-fence.h:127
dma_fence_func_t func
Definition dma-fence.h:129
struct list_head node
Definition dma-fence.h:128
Definition dma-fence.h:136
bool(* signaled)(struct dma_fence *fence)
Definition dma-fence.h:212
signed long(* wait)(struct dma_fence *fence, bool intr, signed long timeout)
Definition dma-fence.h:234
void(* set_deadline)(struct dma_fence *fence, ktime_t deadline)
Definition dma-fence.h:272
void(* release)(struct dma_fence *fence)
Definition dma-fence.h:252
bool(* enable_signaling)(struct dma_fence *fence)
Definition dma-fence.h:195
Definition dma-fence.h:70
spinlock_t * extern_lock
Definition dma-fence.h:72
spinlock_t inline_lock
Definition dma-fence.h:73
struct kref refcount
Definition dma-fence.h:102
int error
Definition dma-fence.h:103
unsigned long flags
Definition dma-fence.h:101
const struct dma_fence_ops __rcu * ops
Definition dma-fence.h:75
ktime_t timestamp
Definition dma-fence.h:95
u64 context
Definition dma-fence.h:99
u64 seqno
Definition dma-fence.h:100
Definition kref.h:44
Definition list.h:11
Definition rcupdate.h:18
Definition seq_file.h:47