Browse Source

mm-drivers: sync-fence: add changes to serialize fence operations

This change acquires fence_lock to serialize the enable_sw
signalling operation on dma_fence_array. It bails out
safely if the bind operation is called twice on the spec
fence. The error level for bind failure with invalid user fd
is changed to warning as this case can be treated non fatal.

Change-Id: I688cbc84ba3cfb49c54de9b5e1bf8a9ec9d8da3a
Signed-off-by: Narendra Muppalla <[email protected]>
Narendra Muppalla 3 năm trước cách đây
mục cha
commit
03173f7cc8
1 tập tin đã thay đổi với 11 bổ sung1 xóa
  1. 11 1
      sync_fence/src/qcom_sync_file.c

+ 11 - 1
sync_fence/src/qcom_sync_file.c

@@ -276,6 +276,13 @@ static int spec_sync_bind_array(struct fence_bind_data *sync_bind_info)
 		ret = -EINVAL;
 		goto end;
 	}
+
+	if (fence_array->fences) {
+		pr_err("fence array already populated, spec fd:%d status:%d flags:0x%x\n",
+			sync_bind_info->out_bind_fd, dma_fence_get_status(fence), fence->flags);
+		goto end;
+	}
+
 	num_fences = fence_array->num_fences;
 	counter = num_fences;
 
@@ -298,11 +305,12 @@ static int spec_sync_bind_array(struct fence_bind_data *sync_bind_info)
 		goto out;
 	}
 
+	spin_lock(fence->lock);
 	fence_array->fences = fence_list;
 	for (i = 0; i < num_fences; i++) {
 		user_fence = sync_file_get_fence(user_fds[i]);
 		if (!user_fence) {
-			pr_err("bind fences are invalid !! user_fd:%d out_bind_fd:%d\n",
+			pr_warn("bind fences are invalid !! user_fd:%d out_bind_fd:%d\n",
 				user_fds[i], sync_bind_info->out_bind_fd);
 			counter = i;
 			ret = -EINVAL;
@@ -314,6 +322,7 @@ static int spec_sync_bind_array(struct fence_bind_data *sync_bind_info)
 	}
 
 	clear_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags);
+	spin_unlock(fence->lock);
 	dma_fence_enable_sw_signaling(&fence_array->base);
 
 	clear_fence_array_tracker(false);
@@ -327,6 +336,7 @@ bind_invalid:
 		fence_array->fences = NULL;
 		fence_array->num_fences = 0;
 		dma_fence_set_error(fence, -EINVAL);
+		spin_unlock(fence->lock);
 		dma_fence_signal(fence);
 		clear_fence_array_tracker(false);
 	}