From: "monk.liu" <monk.liu@xxxxxxx> Return the index of the first signaled fence. This information is useful in some APIs like Vulkan. 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> --- drivers/dma-buf/fence.c | 19 ++++++++++++++----- include/linux/fence.h | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c index 64478f9..32fdce1 100644 --- a/drivers/dma-buf/fence.c +++ b/drivers/dma-buf/fence.c @@ -397,14 +397,17 @@ out: EXPORT_SYMBOL(fence_default_wait); static bool -fence_test_signaled_any(struct fence **fences, uint32_t count) +fence_test_signaled_any(struct fence **fences, uint32_t count, uint32_t *idx) { int i; for (i = 0; i < count; ++i) { struct fence *fence = fences[i]; - if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags)) + if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { + if (idx) + *idx = i; return true; + } } return false; } @@ -416,6 +419,7 @@ fence_test_signaled_any(struct 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 @@ -427,7 +431,7 @@ fence_test_signaled_any(struct fence **fences, uint32_t count) */ signed long fence_wait_any_timeout(struct 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; @@ -438,8 +442,11 @@ fence_wait_any_timeout(struct fence **fences, uint32_t count, if (timeout == 0) { for (i = 0; i < count; ++i) - if (fence_is_signaled(fences[i])) + if (fence_is_signaled(fences[i])) { + if (idx) + *idx = i; return 1; + } return 0; } @@ -462,6 +469,8 @@ fence_wait_any_timeout(struct fence **fences, uint32_t count, if (fence_add_callback(fence, &cb[i].base, fence_default_wait_cb)) { /* This fence is already signaled */ + if (idx) + *idx = i; goto fence_rm_cb; } } @@ -472,7 +481,7 @@ fence_wait_any_timeout(struct fence **fences, uint32_t count, else set_current_state(TASK_UNINTERRUPTIBLE); - if (fence_test_signaled_any(fences, count)) + if (fence_test_signaled_any(fences, count, idx)) break; ret = schedule_timeout(ret); diff --git a/include/linux/fence.h b/include/linux/fence.h index 44d945e..6a7e68a 100644 --- a/include/linux/fence.h +++ b/include/linux/fence.h @@ -327,7 +327,7 @@ static inline struct fence *fence_later(struct fence *f1, struct fence *f2) signed long fence_wait_timeout(struct fence *, bool intr, signed long timeout); signed long fence_wait_any_timeout(struct fence **fences, uint32_t count, - bool intr, signed long timeout); + bool intr, signed long timeout, uint32_t *idx); /** * fence_wait - sleep until the fence gets signaled -- 2.5.5