@@ -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);
@@ -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
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@amd.com> --- drivers/dma-buf/dma-fence-unwrap.c | 47 ++++++++++++++++++++++++++++++ include/linux/dma-fence-unwrap.h | 3 ++ 2 files changed, 50 insertions(+)