From: Tvrtko Ursulin <tvrtko.ursu...@intel.com>

As signaling is enabled on the container fence we need to propagate any
external waiting status to individual fences in order to enable owning
drivers see it.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursu...@intel.com>
---
 drivers/dma-buf/dma-fence-chain.c | 22 ++++++++++++++++------
 include/linux/dma-fence-chain.h   |  1 +
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/dma-buf/dma-fence-chain.c 
b/drivers/dma-buf/dma-fence-chain.c
index a0d920576ba6..ef6a5988c8aa 100644
--- a/drivers/dma-buf/dma-fence-chain.c
+++ b/drivers/dma-buf/dma-fence-chain.c
@@ -145,20 +145,30 @@ static void dma_fence_chain_cb(struct dma_fence *f, 
struct dma_fence_cb *cb)
 static bool dma_fence_chain_enable_signaling(struct dma_fence *fence)
 {
        struct dma_fence_chain *head = to_dma_fence_chain(fence);
+       struct dma_fence *callback = NULL;
 
        dma_fence_get(&head->base);
        dma_fence_chain_for_each(fence, &head->base) {
                struct dma_fence *f = dma_fence_chain_contained(fence);
 
-               dma_fence_get(f);
-               if (!dma_fence_add_callback(f, &head->cb, dma_fence_chain_cb)) {
+               if (!callback) {
+                       dma_fence_get(f);
+                       if (!dma_fence_add_callback(f, &head->cb,
+                                                   dma_fence_chain_cb))
+                               callback = f;
+                       else
+                               dma_fence_put(f);
+               } else if (head->base.waitcount && !head->waitcount) {
+                       dma_fence_enable_sw_signaling(f);
+               } else {
                        dma_fence_put(fence);
-                       return true;
+                       break;
                }
-               dma_fence_put(f);
        }
-       dma_fence_put(&head->base);
-       return false;
+       head->waitcount = head->base.waitcount;
+       if (!callback)
+               dma_fence_put(&head->base);
+       return callback;
 }
 
 static bool dma_fence_chain_signaled(struct dma_fence *fence)
diff --git a/include/linux/dma-fence-chain.h b/include/linux/dma-fence-chain.h
index 4bdf0b96da28..349b882d31ea 100644
--- a/include/linux/dma-fence-chain.h
+++ b/include/linux/dma-fence-chain.h
@@ -25,6 +25,7 @@
 struct dma_fence_chain {
        struct dma_fence base;
        struct dma_fence __rcu *prev;
+       bool waitcount;
        u64 prev_seqno;
        struct dma_fence *fence;
        union {
-- 
2.37.2

Reply via email to