diff options
Diffstat (limited to 'drivers/dma-buf/dma-fence.c')
-rw-r--r-- | drivers/dma-buf/dma-fence.c | 32 |
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 | */ |
344 | signed long | 343 | signed long |
345 | dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout) | 344 | dma_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: | |||
403 | EXPORT_SYMBOL(dma_fence_default_wait); | 402 | EXPORT_SYMBOL(dma_fence_default_wait); |
404 | 403 | ||
405 | static bool | 404 | static bool |
406 | dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count) | 405 | dma_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 | */ |
434 | signed long | 439 | signed long |
435 | dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, | 440 | dma_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); |