xref: /linux/include/linux/dma-fence-unwrap.h (revision 245a4a7b531cffb41233a716497c25b06835cf4b)
164a8f92fSChristian König /* SPDX-License-Identifier: GPL-2.0-only */
264a8f92fSChristian König /*
364a8f92fSChristian König  * Copyright (C) 2022 Advanced Micro Devices, Inc.
464a8f92fSChristian König  * Authors:
564a8f92fSChristian König  *	Christian König <christian.koenig@amd.com>
664a8f92fSChristian König  */
764a8f92fSChristian König 
864a8f92fSChristian König #ifndef __LINUX_DMA_FENCE_UNWRAP_H
964a8f92fSChristian König #define __LINUX_DMA_FENCE_UNWRAP_H
1064a8f92fSChristian König 
1101357a5aSChristian König struct dma_fence;
1264a8f92fSChristian König 
1364a8f92fSChristian König /**
1464a8f92fSChristian König  * struct dma_fence_unwrap - cursor into the container structure
1564a8f92fSChristian König  *
1664a8f92fSChristian König  * Should be used with dma_fence_unwrap_for_each() iterator macro.
1764a8f92fSChristian König  */
1864a8f92fSChristian König struct dma_fence_unwrap {
1964a8f92fSChristian König 	/**
2064a8f92fSChristian König 	 * @chain: potential dma_fence_chain, but can be other fence as well
2164a8f92fSChristian König 	 */
2264a8f92fSChristian König 	struct dma_fence *chain;
2364a8f92fSChristian König 	/**
2464a8f92fSChristian König 	 * @array: potential dma_fence_array, but can be other fence as well
2564a8f92fSChristian König 	 */
2664a8f92fSChristian König 	struct dma_fence *array;
2764a8f92fSChristian König 	/**
2864a8f92fSChristian König 	 * @index: last returned index if @array is really a dma_fence_array
2964a8f92fSChristian König 	 */
3064a8f92fSChristian König 	unsigned int index;
3164a8f92fSChristian König };
3264a8f92fSChristian König 
3301357a5aSChristian König struct dma_fence *dma_fence_unwrap_first(struct dma_fence *head,
3401357a5aSChristian König 					 struct dma_fence_unwrap *cursor);
3501357a5aSChristian König struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor);
3664a8f92fSChristian König 
3764a8f92fSChristian König /**
3864a8f92fSChristian König  * dma_fence_unwrap_for_each - iterate over all fences in containers
3964a8f92fSChristian König  * @fence: current fence
4064a8f92fSChristian König  * @cursor: current position inside the containers
4164a8f92fSChristian König  * @head: starting point for the iterator
4264a8f92fSChristian König  *
4364a8f92fSChristian König  * Unwrap dma_fence_chain and dma_fence_array containers and deep dive into all
4464a8f92fSChristian König  * potential fences in them. If @head is just a normal fence only that one is
4564a8f92fSChristian König  * returned.
468f619737SChristian König  *
478f619737SChristian König  * Note that signalled fences are opportunistically filtered out, which
488f619737SChristian König  * means the iteration is potentially over no fence at all.
4964a8f92fSChristian König  */
5064a8f92fSChristian König #define dma_fence_unwrap_for_each(fence, cursor, head)			\
5164a8f92fSChristian König 	for (fence = dma_fence_unwrap_first(head, cursor); fence;	\
528f619737SChristian König 	     fence = dma_fence_unwrap_next(cursor))			\
538f619737SChristian König 		if (!dma_fence_is_signaled(fence))
5464a8f92fSChristian König 
55*245a4a7bSChristian König struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
56*245a4a7bSChristian König 					   struct dma_fence **fences,
57*245a4a7bSChristian König 					   struct dma_fence_unwrap *cursors);
58*245a4a7bSChristian König 
59*245a4a7bSChristian König /**
60*245a4a7bSChristian König  * dma_fence_unwrap_merge - unwrap and merge fences
61*245a4a7bSChristian König  *
62*245a4a7bSChristian König  * All fences given as parameters are unwrapped and merged back together as flat
63*245a4a7bSChristian König  * dma_fence_array. Useful if multiple containers need to be merged together.
64*245a4a7bSChristian König  *
65*245a4a7bSChristian König  * Implemented as a macro to allocate the necessary arrays on the stack and
66*245a4a7bSChristian König  * account the stack frame size to the caller.
67*245a4a7bSChristian König  *
68*245a4a7bSChristian König  * Returns NULL on memory allocation failure, a dma_fence object representing
69*245a4a7bSChristian König  * all the given fences otherwise.
70*245a4a7bSChristian König  */
71*245a4a7bSChristian König #define dma_fence_unwrap_merge(...)					\
72*245a4a7bSChristian König 	({								\
73*245a4a7bSChristian König 		struct dma_fence *__f[] = { __VA_ARGS__ };		\
74*245a4a7bSChristian König 		struct dma_fence_unwrap __c[ARRAY_SIZE(__f)];		\
75*245a4a7bSChristian König 									\
76*245a4a7bSChristian König 		__dma_fence_unwrap_merge(ARRAY_SIZE(__f), __f, __c);	\
77*245a4a7bSChristian König 	})
78*245a4a7bSChristian König 
7964a8f92fSChristian König #endif
80