123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- #ifndef __LINUX_FENCE_H
- #define __LINUX_FENCE_H
- #include <linux/err.h>
- #include <linux/wait.h>
- #include <linux/list.h>
- #include <linux/bitops.h>
- #include <linux/kref.h>
- #include <linux/sched.h>
- #include <linux/printk.h>
- #include <linux/rcupdate.h>
- struct fence;
- struct fence_ops;
- struct fence_cb;
- struct fence {
- struct kref refcount;
- const struct fence_ops *ops;
- struct rcu_head rcu;
- struct list_head cb_list;
- spinlock_t *lock;
- u64 context;
- unsigned seqno;
- unsigned long flags;
- ktime_t timestamp;
- int status;
- };
- enum fence_flag_bits {
- FENCE_FLAG_SIGNALED_BIT,
- FENCE_FLAG_ENABLE_SIGNAL_BIT,
- FENCE_FLAG_USER_BITS,
- };
- typedef void (*fence_func_t)(struct fence *fence, struct fence_cb *cb);
- struct fence_cb {
- struct list_head node;
- fence_func_t func;
- };
- struct fence_ops {
- const char * (*get_driver_name)(struct fence *fence);
- const char * (*get_timeline_name)(struct fence *fence);
- bool (*enable_signaling)(struct fence *fence);
- bool (*signaled)(struct fence *fence);
- signed long (*wait)(struct fence *fence, bool intr, signed long timeout);
- void (*release)(struct fence *fence);
- int (*fill_driver_data)(struct fence *fence, void *data, int size);
- void (*fence_value_str)(struct fence *fence, char *str, int size);
- void (*timeline_value_str)(struct fence *fence, char *str, int size);
- };
- void fence_init(struct fence *fence, const struct fence_ops *ops,
- spinlock_t *lock, u64 context, unsigned seqno);
- void fence_release(struct kref *kref);
- void fence_free(struct fence *fence);
- static inline struct fence *fence_get(struct fence *fence)
- {
- if (fence)
- kref_get(&fence->refcount);
- return fence;
- }
- static inline struct fence *fence_get_rcu(struct fence *fence)
- {
- if (kref_get_unless_zero(&fence->refcount))
- return fence;
- else
- return NULL;
- }
- static inline void fence_put(struct fence *fence)
- {
- if (fence)
- kref_put(&fence->refcount, fence_release);
- }
- int fence_signal(struct fence *fence);
- int fence_signal_locked(struct fence *fence);
- signed long fence_default_wait(struct fence *fence, bool intr, signed long timeout);
- int fence_add_callback(struct fence *fence, struct fence_cb *cb,
- fence_func_t func);
- bool fence_remove_callback(struct fence *fence, struct fence_cb *cb);
- void fence_enable_sw_signaling(struct fence *fence);
- static inline bool
- fence_is_signaled_locked(struct fence *fence)
- {
- if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags))
- return true;
- if (fence->ops->signaled && fence->ops->signaled(fence)) {
- fence_signal_locked(fence);
- return true;
- }
- return false;
- }
- static inline bool
- fence_is_signaled(struct fence *fence)
- {
- if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags))
- return true;
- if (fence->ops->signaled && fence->ops->signaled(fence)) {
- fence_signal(fence);
- return true;
- }
- return false;
- }
- static inline bool fence_is_later(struct fence *f1, struct fence *f2)
- {
- if (WARN_ON(f1->context != f2->context))
- return false;
- return (int)(f1->seqno - f2->seqno) > 0;
- }
- static inline struct fence *fence_later(struct fence *f1, struct fence *f2)
- {
- if (WARN_ON(f1->context != f2->context))
- return NULL;
-
- if (fence_is_later(f1, f2))
- return fence_is_signaled(f1) ? NULL : f1;
- else
- return fence_is_signaled(f2) ? NULL : f2;
- }
- signed long fence_wait_timeout(struct fence *, bool intr, signed long timeout);
- signed long fence_wait_any_timeout(struct fence **fences, uint32_t count,
- bool intr, signed long timeout);
- static inline signed long fence_wait(struct fence *fence, bool intr)
- {
- signed long ret;
-
- ret = fence_wait_timeout(fence, intr, MAX_SCHEDULE_TIMEOUT);
- return ret < 0 ? ret : 0;
- }
- u64 fence_context_alloc(unsigned num);
- #define FENCE_TRACE(f, fmt, args...) \
- do { \
- struct fence *__ff = (f); \
- if (IS_ENABLED(CONFIG_FENCE_TRACE)) \
- pr_info("f %llu#%u: " fmt, \
- __ff->context, __ff->seqno, ##args); \
- } while (0)
- #define FENCE_WARN(f, fmt, args...) \
- do { \
- struct fence *__ff = (f); \
- pr_warn("f %llu#%u: " fmt, __ff->context, __ff->seqno, \
- ##args); \
- } while (0)
- #define FENCE_ERR(f, fmt, args...) \
- do { \
- struct fence *__ff = (f); \
- pr_err("f %llu#%u: " fmt, __ff->context, __ff->seqno, \
- ##args); \
- } while (0)
- #endif
|