summaryrefslogtreecommitdiffstats
path: root/drivers/dma-buf
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2017-08-10 13:01:49 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-08-14 13:01:25 -0400
commitb88fa004e8a349eba38a3df7a3ace9dd1730b6e0 (patch)
tree5266f2b1ed288dcf70bf5c51bbce37f1d65dc075 /drivers/dma-buf
parent7faf952a3030d304334fe527be339b63e9e2745f (diff)
dma-buf: fix reservation_object_wait_timeout_rcu to wait correctly v2
With hardware resets in mind it is possible that all shared fences are signaled, but the exlusive isn't. Fix waiting for everything in this situation. v2: make sure we always wait for the exclusive fence Acked-by: Sumit Semwal <sumit.semwal@linaro.org> Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Chunming Zhou <david1.zhou@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/1502384509-10465-3-git-send-email-alexander.deucher@amd.com
Diffstat (limited to 'drivers/dma-buf')
-rw-r--r--drivers/dma-buf/reservation.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index d4881f91c43b..dec3a815455d 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -431,12 +431,25 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
431 long ret = timeout ? timeout : 1; 431 long ret = timeout ? timeout : 1;
432 432
433retry: 433retry:
434 fence = NULL;
435 shared_count = 0; 434 shared_count = 0;
436 seq = read_seqcount_begin(&obj->seq); 435 seq = read_seqcount_begin(&obj->seq);
437 rcu_read_lock(); 436 rcu_read_lock();
438 437
439 if (wait_all) { 438 fence = rcu_dereference(obj->fence_excl);
439 if (fence && !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
440 if (!dma_fence_get_rcu(fence))
441 goto unlock_retry;
442
443 if (dma_fence_is_signaled(fence)) {
444 dma_fence_put(fence);
445 fence = NULL;
446 }
447
448 } else {
449 fence = NULL;
450 }
451
452 if (!fence && wait_all) {
440 struct reservation_object_list *fobj = 453 struct reservation_object_list *fobj =
441 rcu_dereference(obj->fence); 454 rcu_dereference(obj->fence);
442 455
@@ -463,22 +476,6 @@ retry:
463 } 476 }
464 } 477 }
465 478
466 if (!shared_count) {
467 struct dma_fence *fence_excl = rcu_dereference(obj->fence_excl);
468
469 if (fence_excl &&
470 !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
471 &fence_excl->flags)) {
472 if (!dma_fence_get_rcu(fence_excl))
473 goto unlock_retry;
474
475 if (dma_fence_is_signaled(fence_excl))
476 dma_fence_put(fence_excl);
477 else
478 fence = fence_excl;
479 }
480 }
481
482 rcu_read_unlock(); 479 rcu_read_unlock();
483 if (fence) { 480 if (fence) {
484 if (read_seqcount_retry(&obj->seq, seq)) { 481 if (read_seqcount_retry(&obj->seq, seq)) {