summaryrefslogtreecommitdiff
path: root/drivers/dma-buf/dma-fence.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma-buf/dma-fence.c')
-rw-r--r--drivers/dma-buf/dma-fence.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 3a7bf009c21c..0212af7997d9 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -161,9 +161,6 @@ dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout)
if (WARN_ON(timeout < 0))
return -EINVAL;
- if (timeout == 0)
- return dma_fence_is_signaled(fence);
-
trace_dma_fence_wait_start(fence);
ret = fence->ops->wait(fence, intr, timeout);
trace_dma_fence_wait_end(fence);
@@ -339,18 +336,20 @@ dma_fence_default_wait_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
* @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
*
* Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the
- * remaining timeout in jiffies on success.
+ * remaining timeout in jiffies on success. If timeout is zero the value one is
+ * returned if the fence is already signaled for consistency with other
+ * functions taking a jiffies timeout.
*/
signed long
dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
{
struct default_wait_cb cb;
unsigned long flags;
- signed long ret = timeout;
+ signed long ret = timeout ? timeout : 1;
bool was_set;
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
- return timeout;
+ return ret;
spin_lock_irqsave(fence->lock, flags);
@@ -403,14 +402,18 @@ out:
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;
}
@@ -422,6 +425,8 @@ 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, meaningful only on
+ * positive return
*
* Returns -EINVAL on custom fence wait implementation, -ERESTARTSYS if
* interrupted, 0 if the wait timed out, or the remaining timeout in jiffies
@@ -433,7 +438,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;
@@ -444,8 +449,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;
}
@@ -468,6 +476,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;
}
}
@@ -478,7 +488,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);