aboutsummaryrefslogtreecommitdiffstats
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)
161 if (WARN_ON(timeout < 0)) 161 if (WARN_ON(timeout < 0))
162 return -EINVAL; 162 return -EINVAL;
163 163
164 if (timeout == 0)
165 return dma_fence_is_signaled(fence);
166
167 trace_dma_fence_wait_start(fence); 164 trace_dma_fence_wait_start(fence);
168 ret = fence->ops->wait(fence, intr, timeout); 165 ret = fence->ops->wait(fence, intr, timeout);
169 trace_dma_fence_wait_end(fence); 166 trace_dma_fence_wait_end(fence);
@@ -339,18 +336,20 @@ dma_fence_default_wait_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
339 * @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT 336 * @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
340 * 337 *
341 * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the 338 * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the
342 * remaining timeout in jiffies on success. 339 * remaining timeout in jiffies on success. If timeout is zero the value one is
340 * returned if the fence is already signaled for consistency with other
341 * functions taking a jiffies timeout.
343 */ 342 */
344signed long 343signed long
345dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout) 344dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
346{ 345{
347 struct default_wait_cb cb; 346 struct default_wait_cb cb;
348 unsigned long flags; 347 unsigned long flags;
349 signed long ret = timeout; 348 signed long ret = timeout ? timeout : 1;
350 bool was_set; 349 bool was_set;
351 350
352 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) 351 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
353 return timeout; 352 return ret;
354 353
355 spin_lock_irqsave(fence->lock, flags); 354 spin_lock_irqsave(fence->lock, flags);
356 355
@@ -403,14 +402,18 @@ out:
403EXPORT_SYMBOL(dma_fence_default_wait); 402EXPORT_SYMBOL(dma_fence_default_wait);
404 403
405static bool 404static bool
406dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count) 405dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count,
406 uint32_t *idx)
407{ 407{
408 int i; 408 int i;
409 409
410 for (i = 0; i < count; ++i) { 410 for (i = 0; i < count; ++i) {
411 struct dma_fence *fence = fences[i]; 411 struct dma_fence *fence = fences[i];
412 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) 412 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
413 if (idx)
414 *idx = i;
413 return true; 415 return true;
416 }
414 } 417 }
415 return false; 418 return false;
416} 419}
@@ -422,6 +425,8 @@ dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count)
422 * @count: [in] number of fences to wait on 425 * @count: [in] number of fences to wait on
423 * @intr: [in] if true, do an interruptible wait 426 * @intr: [in] if true, do an interruptible wait
424 * @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT 427 * @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
428 * @idx: [out] the first signaled fence index, meaningful only on
429 * positive return
425 * 430 *
426 * Returns -EINVAL on custom fence wait implementation, -ERESTARTSYS if 431 * Returns -EINVAL on custom fence wait implementation, -ERESTARTSYS if
427 * interrupted, 0 if the wait timed out, or the remaining timeout in jiffies 432 * 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)
433 */ 438 */
434signed long 439signed long
435dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, 440dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
436 bool intr, signed long timeout) 441 bool intr, signed long timeout, uint32_t *idx)
437{ 442{
438 struct default_wait_cb *cb; 443 struct default_wait_cb *cb;
439 signed long ret = timeout; 444 signed long ret = timeout;
@@ -444,8 +449,11 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
444 449
445 if (timeout == 0) { 450 if (timeout == 0) {
446 for (i = 0; i < count; ++i) 451 for (i = 0; i < count; ++i)
447 if (dma_fence_is_signaled(fences[i])) 452 if (dma_fence_is_signaled(fences[i])) {
453 if (idx)
454 *idx = i;
448 return 1; 455 return 1;
456 }
449 457
450 return 0; 458 return 0;
451 } 459 }
@@ -468,6 +476,8 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
468 if (dma_fence_add_callback(fence, &cb[i].base, 476 if (dma_fence_add_callback(fence, &cb[i].base,
469 dma_fence_default_wait_cb)) { 477 dma_fence_default_wait_cb)) {
470 /* This fence is already signaled */ 478 /* This fence is already signaled */
479 if (idx)
480 *idx = i;
471 goto fence_rm_cb; 481 goto fence_rm_cb;
472 } 482 }
473 } 483 }
@@ -478,7 +488,7 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
478 else 488 else
479 set_current_state(TASK_UNINTERRUPTIBLE); 489 set_current_state(TASK_UNINTERRUPTIBLE);
480 490
481 if (dma_fence_test_signaled_any(fences, count)) 491 if (dma_fence_test_signaled_any(fences, count, idx))
482 break; 492 break;
483 493
484 ret = schedule_timeout(ret); 494 ret = schedule_timeout(ret);