Sfoglia il codice sorgente

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 anni fa
parent
commit
03173f7cc8
1 ha cambiato i file con 11 aggiunte e 1 eliminazioni
  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);
 	}