From: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> 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.ursulin@xxxxxxxxx> --- 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