浏览代码

video: driver: Create and use single spin lock for dma fence

Create and use single spin lock per session (per fence context)
rather than creating spin locks per dma fence to possibly
resolve flickering in video playback.

Change-Id: I01286ae375dfedc0da26a1be4ded1bd1e02767ba
Signed-off-by: Akshata Sahukar <[email protected]>
Akshata Sahukar 3 年之前
父节点
当前提交
3964fa9159
共有 3 个文件被更改,包括 20 次插入22 次删除
  1. 4 4
      driver/vidc/inc/msm_vidc_internal.h
  2. 14 0
      driver/vidc/src/msm_vidc_driver.c
  3. 2 18
      driver/vidc/src/msm_vidc_fence.c

+ 4 - 4
driver/vidc/inc/msm_vidc_internal.h

@@ -827,16 +827,16 @@ struct msm_vidc_power {
 };
 
 struct msm_vidc_fence_context {
-        char name[MAX_NAME_LENGTH];
-        u64 ctx_num;
-        u64 seq_num;
+	char                      name[MAX_NAME_LENGTH];
+	u64                       ctx_num;
+	u64                       seq_num;
+	spinlock_t                lock;
 };
 
 struct msm_vidc_fence {
 	struct list_head            list;
 	struct dma_fence            dma_fence;
 	char                        name[MAX_NAME_LENGTH];
-	spinlock_t                  lock;
 	struct sync_file            *sync_file;
 	int                         fd;
 };

+ 14 - 0
driver/vidc/src/msm_vidc_driver.c

@@ -2102,6 +2102,18 @@ int msm_vidc_get_fence_fd(struct msm_vidc_inst *inst, int *fence_fd)
 		return -EINVAL;
 	}
 
+	/*
+	 * Acquire inst->lock for fence fd creation
+	 * to avoid sync_file_create() and sync_file_poll()
+	 * race conditions in e2e playback usecase.
+	 */
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	inst_lock(inst, __func__);
+
 	list_for_each_entry_safe(fence, dummy_fence, &inst->fence_list, list) {
 		if (fence->dma_fence.seqno ==
 			(u64)inst->capabilities->cap[FENCE_ID].value) {
@@ -2125,6 +2137,8 @@ int msm_vidc_get_fence_fd(struct msm_vidc_inst *inst, int *fence_fd)
 	*fence_fd = fence->fd;
 
 exit:
+	inst_unlock(inst, __func__);
+	put_inst(inst);
 	return rc;
 }
 

+ 2 - 18
driver/vidc/src/msm_vidc_fence.c

@@ -67,9 +67,8 @@ struct msm_vidc_fence *msm_vidc_fence_create(struct msm_vidc_inst *inst)
 	}
 
 	fence->fd = INVALID_FD;
-	spin_lock_init(&fence->lock);
 	dma_fence_init(&fence->dma_fence, &msm_vidc_dma_fence_ops,
-		&fence->lock, inst->fence_context.ctx_num,
+		&inst->fence_context.lock, inst->fence_context.ctx_num,
 		++inst->fence_context.seq_num);
 	snprintf(fence->name, sizeof(fence->name), "%s: %llu",
 		inst->fence_context.name, inst->fence_context.seq_num);
@@ -95,18 +94,6 @@ int msm_vidc_create_fence_fd(struct msm_vidc_inst *inst,
 		return -EINVAL;
 	}
 
-	/*
-	 * Acquire inst->lock for fence fd creation
-	 * to avoid sync_file_create() and sync_file_poll()
-	 * race conditions in e2e playback usecase.
-	 */
-	inst = get_inst_ref(g_core, inst);
-	if (!inst) {
-		d_vpr_e("%s: invalid params\n", __func__);
-		return -EINVAL;
-	}
-	inst_lock(inst, __func__);
-
 	fence->fd = get_unused_fd_flags(0);
 	if (fence->fd < 0) {
 		i_vpr_e(inst, "%s: getting fd (%d) failed\n", __func__,
@@ -125,15 +112,11 @@ int msm_vidc_create_fence_fd(struct msm_vidc_inst *inst,
 	i_vpr_l(inst, "%s: created fd %d for fence %s\n", __func__,
 		fence->fd, fence->name);
 
-	inst_unlock(inst, __func__);
-	put_inst(inst);
 	return 0;
 
 err_sync_file:
 	put_unused_fd(fence->fd);
 err_fd:
-	inst_unlock(inst, __func__);
-	put_inst(inst);
 	return rc;
 }
 
@@ -236,6 +219,7 @@ void msm_vidc_fence_deinit(struct msm_vidc_inst *inst)
 	}
 	i_vpr_h(inst, "%s: %s\n", __func__, inst->fence_context.name);
 	inst->fence_context.ctx_num = 0;
+	spin_lock_init(&inst->fence_context.lock);
 	snprintf(inst->fence_context.name, sizeof(inst->fence_context.name),
 		"%s", "");
 }