diff mbox series

[07/15] dma-buf: add user fence utility functions

Message ID 20220502163722.3957-8-christian.koenig@amd.com
State New
Headers show
Series [01/15] dma-buf: rename DMA_FENCE_FLAG_USER_BITS to _DEVICE | expand

Commit Message

Christian König May 2, 2022, 4:37 p.m. UTC
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(+)
diff mbox series

Patch

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