Allows to filter user fences from a dma_fence_chain and wait for user fences in containers. Signed-off-by: Christian König <christian.koenig@xxxxxxx> --- drivers/dma-buf/dma-fence-unwrap.c | 47 ++++++++++++++++++++++++++++++ include/linux/dma-fence-unwrap.h | 3 ++ 2 files changed, 50 insertions(+) diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c index dd3c43aba8f1..4e9eda0b65c5 100644 --- a/drivers/dma-buf/dma-fence-unwrap.c +++ b/drivers/dma-buf/dma-fence-unwrap.c @@ -157,3 +157,50 @@ struct dma_fence *__dma_fence_merge(unsigned int num_fences, return tmp; } EXPORT_SYMBOL_GPL(__dma_fence_merge); + +/** + * dma_fence_filter_user - filter user fences + * @fence: entry point into the chain + * + * Check @fence and if it's a dma_fence_chain advance it until it doesn't depend + * on any user fence any more. + * + * Returns the advanced fence or NULL if no none user fence could be found. + */ +struct dma_fence *dma_fence_filter_user(struct dma_fence *fence) +{ + + while (fence && test_bit(DMA_FENCE_FLAG_USER, &fence->flags)) + fence = dma_fence_chain_walk(fence); + + return fence; +} +EXPORT_SYMBOL(dma_fence_filter_user); + +/** + * dma_fence_wait_user - wait for all user fences to signal + * @fence: entry point + * @timeout: timeout for the wait + * + * Unwrap the potential container in @fence and wait for all the user fences to + * signal. + * Returns: Either negative error code or the remaining timeout. + */ +long dma_fence_wait_user(struct dma_fence *fence, unsigned long timeout) +{ + struct dma_fence_unwrap iter; + long res; + + dma_fence_unwrap_for_each(fence, &iter, fence) { + if (!test_bit(DMA_FENCE_FLAG_USER, &fence->flags)) + continue; + + res = dma_fence_wait(fence, timeout); + if (res <= 0) + return res; + if (timeout) + timeout = res; + } + return timeout; +} +EXPORT_SYMBOL(dma_fence_wait_user); diff --git a/include/linux/dma-fence-unwrap.h b/include/linux/dma-fence-unwrap.h index 7c0fab318301..2a786f5a7819 100644 --- a/include/linux/dma-fence-unwrap.h +++ b/include/linux/dma-fence-unwrap.h @@ -72,4 +72,7 @@ struct dma_fence *__dma_fence_merge(unsigned int num_fences, __dma_fence_merge(ARRAY_SIZE(__f), __f, __c); \ }) +struct dma_fence *dma_fence_filter_user(struct dma_fence *fence); +long dma_fence_wait_user(struct dma_fence *fence, unsigned long timeout); + #endif -- 2.25.1