From: "monk.liu" <monk....@amd.com>

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>
---
 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

Reply via email to