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@xxxxxxx> Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx> --- 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 4d51f9e..90b7d27 100644 --- a/drivers/dma-buf/fence.c +++ b/drivers/dma-buf/fence.c @@ -398,14 +398,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; } @@ -417,6 +420,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 @@ -428,7 +432,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; @@ -439,8 +443,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; } @@ -463,6 +470,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; } } @@ -473,7 +482,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 8cc719a..2d21113 100644 --- a/include/linux/fence.h +++ b/include/linux/fence.h @@ -325,7 +325,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 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel