.. | .. |
---|
1 | 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ |
---|
2 | 2 | /* |
---|
3 | 3 | * |
---|
4 | | - * (C) COPYRIGHT 2010-2018, 2020-2021 ARM Limited. All rights reserved. |
---|
| 4 | + * (C) COPYRIGHT 2010-2023 ARM Limited. All rights reserved. |
---|
5 | 5 | * |
---|
6 | 6 | * This program is free software and is provided to you under the terms of the |
---|
7 | 7 | * GNU General Public License version 2 as published by the Free Software |
---|
.. | .. |
---|
23 | 23 | #define _KBASE_FENCE_H_ |
---|
24 | 24 | |
---|
25 | 25 | /* |
---|
26 | | - * mali_kbase_fence.[hc] has common fence code used by both |
---|
27 | | - * - CONFIG_MALI_BIFROST_DMA_FENCE - implicit DMA fences |
---|
28 | | - * - CONFIG_SYNC_FILE - explicit fences beginning with 4.9 kernel |
---|
| 26 | + * mali_kbase_fence.[hc] has fence code used only by |
---|
| 27 | + * - CONFIG_SYNC_FILE - explicit fences |
---|
29 | 28 | */ |
---|
30 | 29 | |
---|
31 | | -#if defined(CONFIG_MALI_BIFROST_DMA_FENCE) || defined(CONFIG_SYNC_FILE) |
---|
| 30 | +#if IS_ENABLED(CONFIG_SYNC_FILE) |
---|
32 | 31 | |
---|
33 | 32 | #include <linux/list.h> |
---|
34 | 33 | #include "mali_kbase_fence_defs.h" |
---|
35 | 34 | #include "mali_kbase.h" |
---|
| 35 | +#include "mali_kbase_refcount_defs.h" |
---|
| 36 | + |
---|
| 37 | +#if MALI_USE_CSF |
---|
| 38 | +/* Maximum number of characters in DMA fence timeline name. */ |
---|
| 39 | +#define MAX_TIMELINE_NAME (32) |
---|
| 40 | + |
---|
| 41 | +/** |
---|
| 42 | + * struct kbase_kcpu_dma_fence_meta - Metadata structure for dma fence objects containing |
---|
| 43 | + * information about KCPU queue. One instance per KCPU |
---|
| 44 | + * queue. |
---|
| 45 | + * |
---|
| 46 | + * @refcount: Atomic value to keep track of number of references to an instance. |
---|
| 47 | + * An instance can outlive the KCPU queue itself. |
---|
| 48 | + * @kbdev: Pointer to Kbase device. |
---|
| 49 | + * @kctx_id: Kbase context ID. |
---|
| 50 | + * @timeline_name: String of timeline name for associated fence object. |
---|
| 51 | + */ |
---|
| 52 | +struct kbase_kcpu_dma_fence_meta { |
---|
| 53 | + kbase_refcount_t refcount; |
---|
| 54 | + struct kbase_device *kbdev; |
---|
| 55 | + int kctx_id; |
---|
| 56 | + char timeline_name[MAX_TIMELINE_NAME]; |
---|
| 57 | +}; |
---|
| 58 | + |
---|
| 59 | +/** |
---|
| 60 | + * struct kbase_kcpu_dma_fence - Structure which extends a dma fence object to include a |
---|
| 61 | + * reference to metadata containing more informaiton about it. |
---|
| 62 | + * |
---|
| 63 | + * @base: Fence object itself. |
---|
| 64 | + * @metadata: Pointer to metadata structure. |
---|
| 65 | + */ |
---|
| 66 | +struct kbase_kcpu_dma_fence { |
---|
| 67 | +#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE) |
---|
| 68 | + struct fence base; |
---|
| 69 | +#else |
---|
| 70 | + struct dma_fence base; |
---|
| 71 | +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0) */ |
---|
| 72 | + struct kbase_kcpu_dma_fence_meta *metadata; |
---|
| 73 | +}; |
---|
| 74 | +#endif |
---|
36 | 75 | |
---|
37 | 76 | #if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE) |
---|
38 | 77 | extern const struct fence_ops kbase_fence_ops; |
---|
.. | .. |
---|
41 | 80 | #endif |
---|
42 | 81 | |
---|
43 | 82 | /** |
---|
44 | | -* struct kbase_fence_cb - Mali dma-fence callback data struct |
---|
45 | | -* @fence_cb: Callback function |
---|
46 | | -* @katom: Pointer to katom that is waiting on this callback |
---|
47 | | -* @fence: Pointer to the fence object on which this callback is waiting |
---|
48 | | -* @node: List head for linking this callback to the katom |
---|
49 | | -*/ |
---|
50 | | -struct kbase_fence_cb { |
---|
51 | | -#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE) |
---|
52 | | - struct fence_cb fence_cb; |
---|
53 | | - struct fence *fence; |
---|
54 | | -#else |
---|
55 | | - struct dma_fence_cb fence_cb; |
---|
56 | | - struct dma_fence *fence; |
---|
57 | | -#endif |
---|
58 | | - struct kbase_jd_atom *katom; |
---|
59 | | - struct list_head node; |
---|
60 | | -}; |
---|
61 | | - |
---|
62 | | -/** |
---|
63 | 83 | * kbase_fence_out_new() - Creates a new output fence and puts it on the atom |
---|
64 | 84 | * @katom: Atom to create an output fence for |
---|
65 | 85 | * |
---|
66 | | - * return: A new fence object on success, NULL on failure. |
---|
| 86 | + * Return: A new fence object on success, NULL on failure. |
---|
67 | 87 | */ |
---|
68 | 88 | #if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE) |
---|
69 | 89 | struct fence *kbase_fence_out_new(struct kbase_jd_atom *katom); |
---|
.. | .. |
---|
71 | 91 | struct dma_fence *kbase_fence_out_new(struct kbase_jd_atom *katom); |
---|
72 | 92 | #endif |
---|
73 | 93 | |
---|
74 | | -#if defined(CONFIG_SYNC_FILE) |
---|
| 94 | +#if IS_ENABLED(CONFIG_SYNC_FILE) |
---|
75 | 95 | /** |
---|
76 | 96 | * kbase_fence_fence_in_set() - Assign input fence to atom |
---|
77 | 97 | * @katom: Atom to assign input fence to |
---|
.. | .. |
---|
102 | 122 | } |
---|
103 | 123 | } |
---|
104 | 124 | |
---|
105 | | -#if defined(CONFIG_SYNC_FILE) |
---|
| 125 | +#if IS_ENABLED(CONFIG_SYNC_FILE) |
---|
106 | 126 | /** |
---|
107 | | - * kbase_fence_out_remove() - Removes the input fence from atom |
---|
| 127 | + * kbase_fence_in_remove() - Removes the input fence from atom |
---|
108 | 128 | * @katom: Atom to remove input fence for |
---|
109 | 129 | * |
---|
110 | 130 | * This will also release the reference to this fence which the atom keeps |
---|
.. | .. |
---|
153 | 173 | return dma_fence_signal(katom->dma_fence.fence); |
---|
154 | 174 | } |
---|
155 | 175 | |
---|
156 | | -/** |
---|
157 | | - * kbase_fence_add_callback() - Add callback on @fence to block @katom |
---|
158 | | - * @katom: Pointer to katom that will be blocked by @fence |
---|
159 | | - * @fence: Pointer to fence on which to set up the callback |
---|
160 | | - * @callback: Pointer to function to be called when fence is signaled |
---|
161 | | - * |
---|
162 | | - * Caller needs to hold a reference to @fence when calling this function, and |
---|
163 | | - * the caller is responsible for releasing that reference. An additional |
---|
164 | | - * reference to @fence will be taken when the callback was successfully set up |
---|
165 | | - * and @fence needs to be kept valid until the callback has been called and |
---|
166 | | - * cleanup have been done. |
---|
167 | | - * |
---|
168 | | - * Return: 0 on success: fence was either already signaled, or callback was |
---|
169 | | - * set up. Negative error code is returned on error. |
---|
170 | | - */ |
---|
171 | | -#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE) |
---|
172 | | -int kbase_fence_add_callback(struct kbase_jd_atom *katom, |
---|
173 | | - struct fence *fence, |
---|
174 | | - fence_func_t callback); |
---|
175 | | -#else |
---|
176 | | -int kbase_fence_add_callback(struct kbase_jd_atom *katom, |
---|
177 | | - struct dma_fence *fence, |
---|
178 | | - dma_fence_func_t callback); |
---|
179 | | -#endif |
---|
180 | | - |
---|
181 | | -/** |
---|
182 | | - * kbase_fence_dep_count_set() - Set dep_count value on atom to specified value |
---|
183 | | - * @katom: Atom to set dep_count for |
---|
184 | | - * @val: value to set dep_count to |
---|
185 | | - * |
---|
186 | | - * The dep_count is available to the users of this module so that they can |
---|
187 | | - * synchronize completion of the wait with cancellation and adding of more |
---|
188 | | - * callbacks. For instance, a user could do the following: |
---|
189 | | - * |
---|
190 | | - * dep_count set to 1 |
---|
191 | | - * callback #1 added, dep_count is increased to 2 |
---|
192 | | - * callback #1 happens, dep_count decremented to 1 |
---|
193 | | - * since dep_count > 0, no completion is done |
---|
194 | | - * callback #2 is added, dep_count is increased to 2 |
---|
195 | | - * dep_count decremented to 1 |
---|
196 | | - * callback #2 happens, dep_count decremented to 0 |
---|
197 | | - * since dep_count now is zero, completion executes |
---|
198 | | - * |
---|
199 | | - * The dep_count can also be used to make sure that the completion only |
---|
200 | | - * executes once. This is typically done by setting dep_count to -1 for the |
---|
201 | | - * thread that takes on this responsibility. |
---|
202 | | - */ |
---|
203 | | -static inline void |
---|
204 | | -kbase_fence_dep_count_set(struct kbase_jd_atom *katom, int val) |
---|
205 | | -{ |
---|
206 | | - atomic_set(&katom->dma_fence.dep_count, val); |
---|
207 | | -} |
---|
208 | | - |
---|
209 | | -/** |
---|
210 | | - * kbase_fence_dep_count_dec_and_test() - Decrements dep_count |
---|
211 | | - * @katom: Atom to decrement dep_count for |
---|
212 | | - * |
---|
213 | | - * See @kbase_fence_dep_count_set for general description about dep_count |
---|
214 | | - * |
---|
215 | | - * Return: true if value was decremented to zero, otherwise false |
---|
216 | | - */ |
---|
217 | | -static inline bool |
---|
218 | | -kbase_fence_dep_count_dec_and_test(struct kbase_jd_atom *katom) |
---|
219 | | -{ |
---|
220 | | - return atomic_dec_and_test(&katom->dma_fence.dep_count); |
---|
221 | | -} |
---|
222 | | - |
---|
223 | | -/** |
---|
224 | | - * kbase_fence_dep_count_read() - Returns the current dep_count value |
---|
225 | | - * @katom: Pointer to katom |
---|
226 | | - * |
---|
227 | | - * See @kbase_fence_dep_count_set for general description about dep_count |
---|
228 | | - * |
---|
229 | | - * Return: The current dep_count value |
---|
230 | | - */ |
---|
231 | | -static inline int kbase_fence_dep_count_read(struct kbase_jd_atom *katom) |
---|
232 | | -{ |
---|
233 | | - return atomic_read(&katom->dma_fence.dep_count); |
---|
234 | | -} |
---|
235 | | - |
---|
236 | | -/** |
---|
237 | | - * kbase_fence_free_callbacks() - Free dma-fence callbacks on a katom |
---|
238 | | - * @katom: Pointer to katom |
---|
239 | | - * |
---|
240 | | - * This function will free all fence callbacks on the katom's list of |
---|
241 | | - * callbacks. Callbacks that have not yet been called, because their fence |
---|
242 | | - * hasn't yet signaled, will first be removed from the fence. |
---|
243 | | - * |
---|
244 | | - * Locking: katom->dma_fence.callbacks list assumes jctx.lock is held. |
---|
245 | | - * |
---|
246 | | - * Return: true if dep_count reached 0, otherwise false. |
---|
247 | | - */ |
---|
248 | | -bool kbase_fence_free_callbacks(struct kbase_jd_atom *katom); |
---|
249 | | - |
---|
250 | | -#if defined(CONFIG_SYNC_FILE) |
---|
| 176 | +#if IS_ENABLED(CONFIG_SYNC_FILE) |
---|
251 | 177 | /** |
---|
252 | 178 | * kbase_fence_in_get() - Retrieve input fence for atom. |
---|
253 | 179 | * @katom: Atom to get input fence from |
---|
.. | .. |
---|
272 | 198 | #endif /* !MALI_USE_CSF */ |
---|
273 | 199 | |
---|
274 | 200 | /** |
---|
| 201 | + * kbase_fence_get() - Retrieve fence for a KCPUQ fence command. |
---|
| 202 | + * @fence_info: KCPUQ fence command |
---|
| 203 | + * |
---|
| 204 | + * A ref will be taken for the fence, so use @kbase_fence_put() to release it |
---|
| 205 | + * |
---|
| 206 | + * Return: The fence, or NULL if there is no fence for KCPUQ fence command |
---|
| 207 | + */ |
---|
| 208 | +#define kbase_fence_get(fence_info) dma_fence_get((fence_info)->fence) |
---|
| 209 | + |
---|
| 210 | +#if MALI_USE_CSF |
---|
| 211 | +#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE) |
---|
| 212 | +static inline struct kbase_kcpu_dma_fence *kbase_kcpu_dma_fence_get(struct fence *fence) |
---|
| 213 | +#else |
---|
| 214 | +static inline struct kbase_kcpu_dma_fence *kbase_kcpu_dma_fence_get(struct dma_fence *fence) |
---|
| 215 | +#endif |
---|
| 216 | +{ |
---|
| 217 | + if (fence->ops == &kbase_fence_ops) |
---|
| 218 | + return (struct kbase_kcpu_dma_fence *)fence; |
---|
| 219 | + |
---|
| 220 | + return NULL; |
---|
| 221 | +} |
---|
| 222 | + |
---|
| 223 | +static inline void kbase_kcpu_dma_fence_meta_put(struct kbase_kcpu_dma_fence_meta *metadata) |
---|
| 224 | +{ |
---|
| 225 | + if (kbase_refcount_dec_and_test(&metadata->refcount)) { |
---|
| 226 | + atomic_dec(&metadata->kbdev->live_fence_metadata); |
---|
| 227 | + kfree(metadata); |
---|
| 228 | + } |
---|
| 229 | +} |
---|
| 230 | + |
---|
| 231 | +#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE) |
---|
| 232 | +static inline void kbase_kcpu_dma_fence_put(struct fence *fence) |
---|
| 233 | +#else |
---|
| 234 | +static inline void kbase_kcpu_dma_fence_put(struct dma_fence *fence) |
---|
| 235 | +#endif |
---|
| 236 | +{ |
---|
| 237 | + struct kbase_kcpu_dma_fence *kcpu_fence = kbase_kcpu_dma_fence_get(fence); |
---|
| 238 | + |
---|
| 239 | + if (kcpu_fence) |
---|
| 240 | + kbase_kcpu_dma_fence_meta_put(kcpu_fence->metadata); |
---|
| 241 | +} |
---|
| 242 | +#endif /* MALI_USE_CSF */ |
---|
| 243 | + |
---|
| 244 | +/** |
---|
275 | 245 | * kbase_fence_put() - Releases a reference to a fence |
---|
276 | 246 | * @fence: Fence to release reference for. |
---|
277 | 247 | */ |
---|
278 | | -#define kbase_fence_put(fence) dma_fence_put(fence) |
---|
| 248 | +#if (KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE) |
---|
| 249 | +static inline void kbase_fence_put(struct fence *fence) |
---|
| 250 | +#else |
---|
| 251 | +static inline void kbase_fence_put(struct dma_fence *fence) |
---|
| 252 | +#endif |
---|
| 253 | +{ |
---|
| 254 | + dma_fence_put(fence); |
---|
| 255 | +} |
---|
279 | 256 | |
---|
280 | | - |
---|
281 | | -#endif /* CONFIG_MALI_BIFROST_DMA_FENCE || defined(CONFIG_SYNC_FILE */ |
---|
| 257 | +#endif /* IS_ENABLED(CONFIG_SYNC_FILE) */ |
---|
282 | 258 | |
---|
283 | 259 | #endif /* _KBASE_FENCE_H_ */ |
---|