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 <[email protected]>
Signed-off-by: Christian König <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Reviewed-by: Chunming Zhou <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
This commit is contained in:
Christian König 2017-08-10 13:01:49 -04:00 • committed by Alex Deucher
commit b88fa004e8

View file

@ -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)) {