From: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxxx> Add a dma_fence_unwrap_merge_context() helper which works exactly the same as the existing dma_fence_unwrap_merge() apart that instead of always allocating a new fence context it allows the caller to specify it. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxxx> Cc: Christian König <christian.koenig@xxxxxxx> Cc: Danilo Krummrich <dakr@xxxxxxxxxx> Cc: Matthew Brost <matthew.brost@xxxxxxxxx> Cc: Philipp Stanner <pstanner@xxxxxxxxxx> --- drivers/dma-buf/dma-fence-unwrap.c | 8 ++++---- include/linux/dma-fence-unwrap.h | 31 ++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c index 2a059ac0ed27..fd9813a50532 100644 --- a/drivers/dma-buf/dma-fence-unwrap.c +++ b/drivers/dma-buf/dma-fence-unwrap.c @@ -80,7 +80,8 @@ static int fence_cmp(const void *_a, const void *_b) } /* Implementation for the dma_fence_merge() marco, don't use directly */ -struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences, +struct dma_fence *__dma_fence_unwrap_merge(u64 context, + unsigned int num_fences, struct dma_fence **fences, struct dma_fence_unwrap *iter) { @@ -156,9 +157,8 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences, count = ++j; if (count > 1) { - result = dma_fence_array_create(count, array, - dma_fence_context_alloc(1), - 1, false); + result = dma_fence_array_create(count, array, context, 1, + false); if (!result) { for (i = 0; i < count; i++) dma_fence_put(array[i]); diff --git a/include/linux/dma-fence-unwrap.h b/include/linux/dma-fence-unwrap.h index 66b1e56fbb81..12e8c43848ce 100644 --- a/include/linux/dma-fence-unwrap.h +++ b/include/linux/dma-fence-unwrap.h @@ -8,6 +8,8 @@ #ifndef __LINUX_DMA_FENCE_UNWRAP_H #define __LINUX_DMA_FENCE_UNWRAP_H +#include <linux/types.h> + struct dma_fence; /** @@ -48,7 +50,8 @@ struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor); for (fence = dma_fence_unwrap_first(head, cursor); fence; \ fence = dma_fence_unwrap_next(cursor)) -struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences, +struct dma_fence *__dma_fence_unwrap_merge(u64 context, + unsigned int num_fences, struct dma_fence **fences, struct dma_fence_unwrap *cursors); @@ -69,7 +72,31 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences, struct dma_fence *__f[] = { __VA_ARGS__ }; \ struct dma_fence_unwrap __c[ARRAY_SIZE(__f)]; \ \ - __dma_fence_unwrap_merge(ARRAY_SIZE(__f), __f, __c); \ + __dma_fence_unwrap_merge(dma_fence_context_alloc(1), \ + ARRAY_SIZE(__f), __f, __c); \ + }) + +/** + * dma_fence_unwrap_merge_context - unwrap and merge fences with context + * + * All fences given as parameters are unwrapped and merged back together as flat + * dma_fence_array. Useful if multiple containers need to be merged together. + * + * Implemented as a macro to allocate the necessary arrays on the stack and + * account the stack frame size to the caller. + * + * Fence context is passed in and not automatically allocated. + * + * Returns NULL on memory allocation failure, a dma_fence object representing + * all the given fences otherwise. + */ +#define dma_fence_unwrap_merge_context(context, ...) \ + ({ \ + struct dma_fence *__f[] = { __VA_ARGS__ }; \ + struct dma_fence_unwrap __c[ARRAY_SIZE(__f)]; \ + \ + __dma_fence_unwrap_merge((context), \ + ARRAY_SIZE(__f), __f, __c); \ }) #endif -- 2.47.1