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)
downloadlinux-b88fa004e8a349eba38a3df7a3ace9dd1730b6e0.tar.gz
linux-b88fa004e8a349eba38a3df7a3ace9dd1730b6e0.tar.bz2
linux-b88fa004e8a349eba38a3df7a3ace9dd1730b6e0.zip
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,
long ret = timeout ? timeout : 1;
retry:
- fence = NULL;
shared_count = 0;
seq = read_seqcount_begin(&obj->seq);
rcu_read_lock();
- if (wait_all) {
+ fence = rcu_dereference(obj->fence_excl);
+ if (fence && !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
+ if (!dma_fence_get_rcu(fence))
+ goto unlock_retry;
+
+ if (dma_fence_is_signaled(fence)) {
+ dma_fence_put(fence);
+ fence = NULL;
+ }
+
+ } else {
+ fence = NULL;
+ }
+
+ if (!fence && wait_all) {
struct reservation_object_list *fobj =
rcu_dereference(obj->fence);
@@ -463,22 +476,6 @@ retry:
}
}
- if (!shared_count) {
- struct dma_fence *fence_excl = rcu_dereference(obj->fence_excl);
-
- if (fence_excl &&
- !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
- &fence_excl->flags)) {
- if (!dma_fence_get_rcu(fence_excl))
- goto unlock_retry;
-
- if (dma_fence_is_signaled(fence_excl))
- dma_fence_put(fence_excl);
- else
- fence = fence_excl;
- }
- }
-
rcu_read_unlock();
if (fence) {
if (read_seqcount_retry(&obj->seq, seq)) {