1 /* $NetBSD: i915_sw_fence.h,v 1.6 2021/12/19 11:36:08 riastradh Exp $ */ 2 3 /* 4 * SPDX-License-Identifier: MIT 5 * 6 * i915_sw_fence.h - library routines for N:M synchronisation points 7 * 8 * Copyright (C) 2016 Intel Corporation 9 */ 10 11 #ifndef _I915_SW_FENCE_H_ 12 #define _I915_SW_FENCE_H_ 13 14 #include <linux/dma-fence.h> 15 #include <linux/gfp.h> 16 #include <linux/kref.h> 17 #include <linux/notifier.h> /* for NOTIFY_DONE */ 18 #include <linux/wait.h> 19 20 struct completion; 21 struct dma_resv; 22 23 struct i915_sw_fence_waiter { 24 struct list_head entry; 25 int flags; 26 int (*func)(struct i915_sw_fence_waiter *, unsigned, int, void *); 27 void *private; 28 }; 29 30 struct i915_sw_fence { 31 struct i915_sw_fence_queue { 32 spinlock_t lock; 33 struct list_head head; 34 } wait; 35 unsigned long flags; 36 atomic_t pending; 37 int error; 38 }; 39 40 #define I915_SW_FENCE_CHECKED_BIT 0 /* used internally for DAG checking */ 41 #define I915_SW_FENCE_PRIVATE_BIT 1 /* available for use by owner */ 42 #define I915_SW_FENCE_MASK (~3) 43 44 enum i915_sw_fence_notify { 45 FENCE_COMPLETE, 46 FENCE_FREE 47 }; 48 49 typedef int (*i915_sw_fence_notify_t)(struct i915_sw_fence *, 50 enum i915_sw_fence_notify state); 51 #define __i915_sw_fence_call __aligned(4) 52 53 void __i915_sw_fence_init(struct i915_sw_fence *fence, 54 i915_sw_fence_notify_t fn, 55 const char *name, 56 struct lock_class_key *key); 57 #if IS_ENABLED(CONFIG_LOCKDEP) 58 #define i915_sw_fence_init(fence, fn) \ 59 do { \ 60 static struct lock_class_key __key; \ 61 \ 62 __i915_sw_fence_init((fence), (fn), #fence, &__key); \ 63 } while (0) 64 #else 65 #define i915_sw_fence_init(fence, fn) \ 66 __i915_sw_fence_init((fence), (fn), NULL, NULL) 67 #endif 68 69 void i915_sw_fence_reinit(struct i915_sw_fence *fence); 70 71 void i915_sw_fence_fini(struct i915_sw_fence *fence); 72 73 void i915_sw_fence_commit(struct i915_sw_fence *fence); 74 75 #ifdef __NetBSD__ 76 int i915_sw_fence_await_sw_fence(struct i915_sw_fence *, 77 struct i915_sw_fence *, 78 struct i915_sw_fence_waiter *); 79 #else 80 int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, 81 struct i915_sw_fence *after, 82 wait_queue_entry_t *wq); 83 #endif 84 int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence, 85 struct i915_sw_fence *after, 86 gfp_t gfp); 87 88 struct i915_sw_dma_fence_cb { 89 struct dma_fence_cb base; 90 struct i915_sw_fence *fence; 91 }; 92 93 int __i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, 94 struct dma_fence *dma, 95 struct i915_sw_dma_fence_cb *cb); 96 int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, 97 struct dma_fence *dma, 98 unsigned long timeout, 99 gfp_t gfp); 100 101 int i915_sw_fence_await_reservation(struct i915_sw_fence *fence, 102 struct dma_resv *resv, 103 const struct dma_fence_ops *exclude, 104 bool write, 105 unsigned long timeout, 106 gfp_t gfp); 107 108 void i915_sw_fence_await(struct i915_sw_fence *fence); 109 void i915_sw_fence_complete(struct i915_sw_fence *fence); 110 111 static inline bool i915_sw_fence_signaled(const struct i915_sw_fence *fence) 112 { 113 return atomic_read(&fence->pending) <= 0; 114 } 115 116 static inline bool i915_sw_fence_done(const struct i915_sw_fence *fence) 117 { 118 return atomic_read(&fence->pending) < 0; 119 } 120 121 #ifdef __NetBSD__ 122 void i915_sw_fence_wait(struct i915_sw_fence *); 123 #else 124 static inline void i915_sw_fence_wait(struct i915_sw_fence *fence) 125 { 126 wait_event(fence->wait, i915_sw_fence_done(fence)); 127 } 128 #endif 129 130 static inline void 131 i915_sw_fence_set_error_once(struct i915_sw_fence *fence, int error) 132 { 133 if (unlikely(error)) 134 cmpxchg(&fence->error, 0, error); 135 } 136 137 #endif /* _I915_SW_FENCE_H_ */ 138