Commit b88fa004 authored by Christian König's avatar Christian König Committed by Alex Deucher

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: default avatarSumit Semwal <sumit.semwal@linaro.org>
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarChunming Zhou <david1.zhou@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1502384509-10465-3-git-send-email-alexander.deucher@amd.com
parent 7faf952a
...@@ -431,12 +431,25 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj, ...@@ -431,12 +431,25 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
long ret = timeout ? timeout : 1; long ret = timeout ? timeout : 1;
retry: retry:
fence = NULL;
shared_count = 0; shared_count = 0;
seq = read_seqcount_begin(&obj->seq); seq = read_seqcount_begin(&obj->seq);
rcu_read_lock(); 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 = struct reservation_object_list *fobj =
rcu_dereference(obj->fence); rcu_dereference(obj->fence);
...@@ -463,22 +476,6 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj, ...@@ -463,22 +476,6 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
} }
} }
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(); rcu_read_unlock();
if (fence) { if (fence) {
if (read_seqcount_retry(&obj->seq, seq)) { if (read_seqcount_retry(&obj->seq, seq)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment