dma_fence_chain containers cleanup signaled fences automatically, so filter those out from arrays as well.
v2: fix missing walk over the array
Signed-off-by: Christian König christian.koenig@amd.com --- drivers/dma-buf/dma-fence-unwrap.c | 26 +++++++++++++++++++------- include/linux/dma-fence-unwrap.h | 4 ++-- 2 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c index 711be125428c..c3bedbc5832a 100644 --- a/drivers/dma-buf/dma-fence-unwrap.c +++ b/drivers/dma-buf/dma-fence-unwrap.c @@ -32,8 +32,13 @@ __dma_fence_unwrap_array(struct dma_fence_unwrap *cursor) struct dma_fence *dma_fence_unwrap_first(struct dma_fence *head, struct dma_fence_unwrap *cursor) { + struct dma_fence *tmp; + cursor->chain = dma_fence_get(head); - return __dma_fence_unwrap_array(cursor); + tmp = __dma_fence_unwrap_array(cursor); + if (tmp && dma_fence_is_signaled(tmp)) + tmp = dma_fence_unwrap_next(cursor); + return tmp; } EXPORT_SYMBOL_GPL(dma_fence_unwrap_first);
@@ -48,12 +53,19 @@ struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor) { struct dma_fence *tmp;
- ++cursor->index; - tmp = dma_fence_array_next(cursor->array, cursor->index); - if (tmp) - return tmp; + do { + do { + ++cursor->index; + tmp = dma_fence_array_next(cursor->array, + cursor->index); + if (tmp && !dma_fence_is_signaled(tmp)) + return tmp; + } while (tmp); + + cursor->chain = dma_fence_chain_walk(cursor->chain); + tmp = __dma_fence_unwrap_array(cursor); + } while (tmp && dma_fence_is_signaled(tmp));
- cursor->chain = dma_fence_chain_walk(cursor->chain); - return __dma_fence_unwrap_array(cursor); + return tmp; } EXPORT_SYMBOL_GPL(dma_fence_unwrap_next); diff --git a/include/linux/dma-fence-unwrap.h b/include/linux/dma-fence-unwrap.h index e7c219da4ed7..e9d114637294 100644 --- a/include/linux/dma-fence-unwrap.h +++ b/include/linux/dma-fence-unwrap.h @@ -41,8 +41,8 @@ struct dma_fence *dma_fence_unwrap_next(struct dma_fence_unwrap *cursor); * @head: starting point for the iterator * * Unwrap dma_fence_chain and dma_fence_array containers and deep dive into all - * potential fences in them. If @head is just a normal fence only that one is - * returned. + * potential none signaled fences in them. If @head is just a normal fence only + * that one is returned. */ #define dma_fence_unwrap_for_each(fence, cursor, head) \ for (fence = dma_fence_unwrap_first(head, cursor); fence; \