From: "monk.liu" <monk.liu@xxxxxxx> Return the index of the first signaled fence. This information is useful in some APIs like Vulkan. v2: rebase on drm-next (fence -> dma_fence) Signed-off-by: monk.liu <monk.liu at amd.com> Signed-off-by: Alex Deucher <alexander.deucher at amd.com> Cc: Sumit Semwal <sumit.semwal at linaro.org> --- This is the same patch set I send out yesterday, I just squashed the amdgpu patches together and rebased everything on the fence -> dma_fence renaming. This is used by our VK driver and we are planning to use it in mesa as well. drivers/dma-buf/dma-fence.c | 20 +++++++++++++++----- include/linux/dma-fence.h | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 9ef3c2f..dd00990 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -402,14 +402,18 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout) EXPORT_SYMBOL(dma_fence_default_wait); static bool -dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count) +dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count, + uint32_t *idx) { int i; for (i = 0; i < count; ++i) { struct dma_fence *fence = fences[i]; - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { + if (idx) + *idx = i; return true; + } } return false; } @@ -421,6 +425,7 @@ dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count) * @count: [in] number of fences to wait on * @intr: [in] if true, do an interruptible wait * @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT + * @idx: [out] the first signaled fence index, meaninful only on Returns positive * * Returns -EINVAL on custom fence wait implementation, -ERESTARTSYS if * interrupted, 0 if the wait timed out, or the remaining timeout in jiffies @@ -432,7 +437,7 @@ dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count) */ signed long dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, - bool intr, signed long timeout) + bool intr, signed long timeout, uint32_t *idx) { struct default_wait_cb *cb; signed long ret = timeout; @@ -443,8 +448,11 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, if (timeout == 0) { for (i = 0; i < count; ++i) - if (dma_fence_is_signaled(fences[i])) + if (dma_fence_is_signaled(fences[i])) { + if (idx) + *idx = i; return 1; + } return 0; } @@ -467,6 +475,8 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, if (dma_fence_add_callback(fence, &cb[i].base, dma_fence_default_wait_cb)) { /* This fence is already signaled */ + if (idx) + *idx = i; goto fence_rm_cb; } } @@ -477,7 +487,7 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, else set_current_state(TASK_UNINTERRUPTIBLE); - if (dma_fence_test_signaled_any(fences, count)) + if (dma_fence_test_signaled_any(fences, count, idx)) break; ret = schedule_timeout(ret); diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h index ba60c04..e578fe7 100644 --- a/include/linux/dma-fence.h +++ b/include/linux/dma-fence.h @@ -382,7 +382,7 @@ signed long dma_fence_wait_timeout(struct dma_fence *, bool intr, signed long timeout); signed long dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, - bool intr, signed long timeout); + bool intr, signed long timeout, uint32_t *idx); /** * dma_fence_wait - sleep until the fence gets signaled -- 2.5.5