浏览代码

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
Christian König 8 年之前
父节点
当前提交
b88fa004e8
共有 1 个文件被更改,包括 15 次插入18 次删除
  1. 15 18
      drivers/dma-buf/reservation.c

+ 15 - 18
drivers/dma-buf/reservation.c

@@ -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 @@ 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();
 	rcu_read_unlock();
 	if (fence) {
 	if (fence) {
 		if (read_seqcount_retry(&obj->seq, seq)) {
 		if (read_seqcount_retry(&obj->seq, seq)) {