فهرست منبع

video: driver: fix race between driver fd close and ioctl calls

Userspace is allowed to close driver fd at anytime, even in middle
of ongoing session. So it will create a problem, if multiple ioctls
were waiting for &inst->lock() and msm_vidc_close() acquired the
&inst->lock and cleaned up all session specific resources including
vb2 queues, v4l2_fh file handles and all buffers and finally frees
inst itself, as part of put_inst(). So once that is done, other
enties waiting on &inst->lock will get chance, but by that time,
everything is freed. So proceeding that cmd will completely lead to
undefined behaviour and target reset will happen.

Added change to avoid above mentioned scenario by Incrementing inst
refcount everytime before proceeding any ioctls and acquired &inst->lock
to avoid concurrent access between ioctls.

Currently &inst->lock was not acquired except for reqbuf, qbuf, dqbuf
ioctls. But it is good to acquire lock at every ioctl types. This will
help avoid corner cases, such as during ipsc, all port setting were
updated to inst structure, So if userspace attempts any ioctl(like
g_ctrl) without lock, it might get intermittent value, which is wrong.

Change-Id: Ic4bdf562f7036f3796019fe45d1cdc392045878a
Signed-off-by: Govindaraj Rajagopal <[email protected]>
Govindaraj Rajagopal 4 سال پیش
والد
کامیت
5996ceb8d2
4فایلهای تغییر یافته به همراه470 افزوده شده و 136 حذف شده
  1. 27 43
      driver/vidc/src/msm_vidc.c
  2. 7 7
      driver/vidc/src/msm_vidc_driver.c
  3. 428 78
      driver/vidc/src/msm_vidc_v4l2.c
  4. 8 8
      driver/vidc/src/venus_hfi_response.c

+ 27 - 43
driver/vidc/src/msm_vidc.c

@@ -267,10 +267,10 @@ int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
 }
 EXPORT_SYMBOL(msm_vidc_g_fmt);
 
-int msm_vidc_s_selection(void* instance, struct v4l2_selection* s)
+int msm_vidc_s_selection(void *instance, struct v4l2_selection *s)
 {
 	int rc = 0;
-	struct msm_vidc_inst* inst = instance;
+	struct msm_vidc_inst *inst = instance;
 
 	if (!inst || !s) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -286,10 +286,10 @@ int msm_vidc_s_selection(void* instance, struct v4l2_selection* s)
 }
 EXPORT_SYMBOL(msm_vidc_s_selection);
 
-int msm_vidc_g_selection(void* instance, struct v4l2_selection* s)
+int msm_vidc_g_selection(void *instance, struct v4l2_selection *s)
 {
 	int rc = 0;
-	struct msm_vidc_inst* inst = instance;
+	struct msm_vidc_inst *inst = instance;
 
 	if (!inst || !s) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -402,28 +402,25 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
 		return -EINVAL;
 	}
 
-	mutex_lock(&inst->lock);
-
 	if (!msm_vidc_allow_reqbufs(inst, b->type)) {
 		rc = -EBUSY;
-		goto unlock;
+		goto exit;
 	}
 
 	port = v4l2_type_to_driver_port(inst, b->type, __func__);
 	if (port < 0) {
 		rc = -EINVAL;
-		goto unlock;
+		goto exit;
 	}
 
 	rc = vb2_reqbufs(&inst->vb2q[port], b);
 	if (rc) {
 		i_vpr_e(inst, "%s: vb2_reqbufs(%d) failed, %d\n",
 			__func__, b->type, rc);
-		goto unlock;
+		goto exit;
 	}
 
-unlock:
-	mutex_unlock(&inst->lock);
+exit:
 	return rc;
 }
 EXPORT_SYMBOL(msm_vidc_reqbufs);
@@ -440,27 +437,23 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev,
 		return -EINVAL;
 	}
 
-	mutex_lock(&inst->lock);
-
 	if (is_session_error(inst)) {
 		rc = -EBUSY;
-		goto unlock;
+		goto exit;
 	}
 
 	q = msm_vidc_get_vb2q(inst, b->type, __func__);
 	if (!q) {
 		rc = -EINVAL;
-		goto unlock;
+		goto exit;
 	}
-
 	inst->last_qbuf_time_ns = ktime_get_ns();
 
 	rc = vb2_qbuf(q, mdev, b);
 	if (rc)
 		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
 
-unlock:
-	mutex_unlock(&inst->lock);
+exit:
 	return rc;
 }
 EXPORT_SYMBOL(msm_vidc_qbuf);
@@ -476,24 +469,21 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
 		return -EINVAL;
 	}
 
-	mutex_lock(&inst->lock);
-
 	q = msm_vidc_get_vb2q(inst, b->type, __func__);
 	if (!q) {
 		rc = -EINVAL;
-		goto unlock;
+		goto exit;
 	}
 
 	rc = vb2_dqbuf(q, b, true);
 	if (rc == -EAGAIN) {
-		goto unlock;
+		goto exit;
 	} else if (rc) {
 		i_vpr_l(inst, "%s: failed with %d\n", __func__, rc);
-		goto unlock;
+		goto exit;
 	}
 
-unlock:
-	mutex_unlock(&inst->lock);
+exit:
 	return rc;
 }
 EXPORT_SYMBOL(msm_vidc_dqbuf);
@@ -509,20 +499,18 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type)
 		return -EINVAL;
 	}
 
-	mutex_lock(&inst->lock);
-
 	if (!msm_vidc_allow_streamon(inst, type)) {
 		rc = -EBUSY;
-		goto unlock;
+		goto exit;
 	}
 	rc = msm_vidc_state_change_streamon(inst, type);
 	if (rc)
-		goto unlock;
+		goto exit;
 
 	port = v4l2_type_to_driver_port(inst, type, __func__);
 	if (port < 0) {
 		rc = -EINVAL;
-		goto unlock;
+		goto exit;
 	}
 
 	rc = vb2_streamon(&inst->vb2q[port], type);
@@ -530,11 +518,10 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type type)
 		i_vpr_e(inst, "%s: vb2_streamon(%d) failed, %d\n",
 			__func__, type, rc);
 		msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
-		goto unlock;
+		goto exit;
 	}
 
-unlock:
-	mutex_unlock(&inst->lock);
+exit:
 	return rc;
 }
 EXPORT_SYMBOL(msm_vidc_streamon);
@@ -550,20 +537,18 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type)
 		return -EINVAL;
 	}
 
-	mutex_lock(&inst->lock);
-
 	if (!msm_vidc_allow_streamoff(inst, type)) {
 		rc = -EBUSY;
-		goto unlock;
+		goto exit;
 	}
 	rc = msm_vidc_state_change_streamoff(inst, type);
 	if (rc)
-		goto unlock;
+		goto exit;
 
 	port = v4l2_type_to_driver_port(inst, type, __func__);
 	if (port < 0) {
 		rc = -EINVAL;
-		goto unlock;
+		goto exit;
 	}
 
 	rc = vb2_streamoff(&inst->vb2q[port], type);
@@ -571,11 +556,10 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type type)
 		i_vpr_e(inst, "%s: vb2_streamoff(%d) failed, %d\n",
 			__func__, type, rc);
 		msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__);
-		goto unlock;
+		goto exit;
 	}
 
-unlock:
-	mutex_unlock(&inst->lock);
+exit:
 	return rc;
 }
 EXPORT_SYMBOL(msm_vidc_streamoff);
@@ -915,11 +899,11 @@ int msm_vidc_close(void *instance)
 	core = inst->core;
 
 	i_vpr_h(inst, "%s()\n", __func__);
-	mutex_lock(&inst->lock);
+	inst_lock(inst, __func__);
 	msm_vidc_session_close(inst);
 	msm_vidc_remove_session(inst);
 	msm_vidc_destroy_buffers(inst);
-	mutex_unlock(&inst->lock);
+	inst_unlock(inst, __func__);
 	msm_vidc_show_stats(inst);
 	put_inst(inst);
 	msm_vidc_schedule_core_deinit(core);

+ 7 - 7
driver/vidc/src/msm_vidc_driver.c

@@ -3711,7 +3711,7 @@ int msm_vidc_session_streamoff(struct msm_vidc_inst *inst,
 	core = inst->core;
 	i_vpr_h(inst, "%s: wait on port: %d for time: %d ms\n",
 		__func__, port, core->capabilities[HW_RESPONSE_TIMEOUT].value);
-	mutex_unlock(&inst->lock);
+	inst_unlock(inst, __func__);
 	rc = wait_for_completion_timeout(
 			&inst->completions[signal_type],
 			msecs_to_jiffies(
@@ -3724,7 +3724,7 @@ int msm_vidc_session_streamoff(struct msm_vidc_inst *inst,
 	} else {
 		rc = 0;
 	}
-	mutex_lock(&inst->lock);
+	inst_lock(inst, __func__);
 
 	if(rc)
 		goto error;
@@ -3775,7 +3775,7 @@ int msm_vidc_session_close(struct msm_vidc_inst *inst)
 	core = inst->core;
 	i_vpr_h(inst, "%s: wait on close for time: %d ms\n",
 		__func__, core->capabilities[HW_RESPONSE_TIMEOUT].value);
-	mutex_unlock(&inst->lock);
+	inst_unlock(inst, __func__);
 	rc = wait_for_completion_timeout(
 			&inst->completions[SIGNAL_CMD_CLOSE],
 			msecs_to_jiffies(
@@ -3788,7 +3788,7 @@ int msm_vidc_session_close(struct msm_vidc_inst *inst)
 		rc = 0;
 		i_vpr_h(inst, "%s: close successful\n", __func__);
 	}
-	mutex_lock(&inst->lock);
+	inst_lock(inst, __func__);
 
 	msm_vidc_remove_session(inst);
 
@@ -4499,7 +4499,7 @@ exit:
 	put_inst(inst);
 }
 
-int msm_vidc_flush_buffers(struct msm_vidc_inst* inst,
+int msm_vidc_flush_buffers(struct msm_vidc_inst *inst,
 		enum msm_vidc_buffer_type type)
 {
 	int rc = 0;
@@ -4766,7 +4766,7 @@ void put_inst(struct msm_vidc_inst *inst)
 	kref_put(&inst->kref, msm_vidc_close_helper);
 }
 
-bool core_lock_check(struct msm_vidc_core *core, const char* func)
+bool core_lock_check(struct msm_vidc_core *core, const char *func)
 {
 	return mutex_is_locked(&core->lock);
 }
@@ -4781,7 +4781,7 @@ void core_unlock(struct msm_vidc_core *core, const char *function)
 	mutex_unlock(&core->lock);
 }
 
-bool inst_lock_check(struct msm_vidc_inst *inst, const char* func)
+bool inst_lock_check(struct msm_vidc_inst *inst, const char *func)
 {
 	return mutex_is_locked(&inst->lock);
 }

+ 428 - 78
driver/vidc/src/msm_vidc_v4l2.c

@@ -8,8 +8,11 @@
 #include "msm_vidc_core.h"
 #include "msm_vidc_inst.h"
 #include "msm_vidc_debug.h"
+#include "msm_vidc_driver.h"
 #include "msm_vidc.h"
 
+extern struct msm_vidc_core *g_core;
+
 static struct msm_vidc_inst *get_vidc_inst(struct file *filp, void *fh)
 {
 	if (!filp || !filp->private_data)
@@ -20,9 +23,9 @@ static struct msm_vidc_inst *get_vidc_inst(struct file *filp, void *fh)
 
 unsigned int msm_v4l2_poll(struct file *filp, struct poll_table_struct *pt)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(filp, NULL);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, NULL);
 
-	return msm_vidc_poll((void *)vidc_inst, filp, pt);
+	return msm_vidc_poll((void *)inst, filp, pt);
 }
 
 int msm_v4l2_open(struct file *filp)
@@ -31,27 +34,27 @@ int msm_v4l2_open(struct file *filp)
 	struct msm_video_device *vid_dev =
 		container_of(vdev, struct msm_video_device, vdev);
 	struct msm_vidc_core *core = video_drvdata(filp);
-	struct msm_vidc_inst *vidc_inst;
+	struct msm_vidc_inst *inst;
 
-	vidc_inst = msm_vidc_open(core, vid_dev->type);
-	if (!vidc_inst) {
+	inst = msm_vidc_open(core, vid_dev->type);
+	if (!inst) {
 		d_vpr_e("Failed to create instance, type = %d\n",
 			vid_dev->type);
 		return -ENOMEM;
 	}
 	clear_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags);
-	filp->private_data = &(vidc_inst->event_handler);
+	filp->private_data = &(inst->event_handler);
 	return 0;
 }
 
 int msm_v4l2_close(struct file *filp)
 {
 	int rc = 0;
-	struct msm_vidc_inst *vidc_inst;
+	struct msm_vidc_inst *inst;
 
-	vidc_inst = get_vidc_inst(filp, NULL);
+	inst = get_vidc_inst(filp, NULL);
 
-	rc = msm_vidc_close(vidc_inst);
+	rc = msm_vidc_close(inst);
 	filp->private_data = NULL;
 	return rc;
 }
@@ -59,182 +62,529 @@ int msm_v4l2_close(struct file *filp)
 int msm_v4l2_querycap(struct file *filp, void *fh,
 			struct v4l2_capability *cap)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(filp, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_querycap((void *)inst, cap);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
 
-	return msm_vidc_querycap((void *)vidc_inst, cap);
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_enum_fmt(struct file *file, void *fh,
+int msm_v4l2_enum_fmt(struct file *filp, void *fh,
 					struct v4l2_fmtdesc *f)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_enum_fmt((void *)inst, f);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
 
-	return msm_vidc_enum_fmt((void *)vidc_inst, f);
+	return rc;
 }
 
-int msm_v4l2_s_fmt(struct file *file, void *fh,
+int msm_v4l2_s_fmt(struct file *filp, void *fh,
 					struct v4l2_format *f)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_s_fmt((void *)inst, f);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
 
-	return msm_vidc_s_fmt((void *)vidc_inst, f);
+	return rc;
 }
 
-int msm_v4l2_g_fmt(struct file *file, void *fh,
+int msm_v4l2_g_fmt(struct file *filp, void *fh,
 					struct v4l2_format *f)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_g_fmt((void *)inst, f);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
 
-	return msm_vidc_g_fmt((void *)vidc_inst, f);
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_s_selection(struct file* file, void* fh,
-					struct v4l2_selection* s)
+int msm_v4l2_s_selection(struct file *filp, void *fh,
+					struct v4l2_selection *s)
 {
-	struct msm_vidc_inst* vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_s_selection((void *)inst, s);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
 
-	return msm_vidc_s_selection((void*)vidc_inst, s);
+	return rc;
 }
 
-int msm_v4l2_g_selection(struct file* file, void* fh,
-					struct v4l2_selection* s)
+int msm_v4l2_g_selection(struct file *filp, void *fh,
+					struct v4l2_selection *s)
 {
-	struct msm_vidc_inst* vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_g_selection((void *)inst, s);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
 
-	return msm_vidc_g_selection((void*)vidc_inst, s);
+	return rc;
 }
 
-int msm_v4l2_s_parm(struct file *file, void *fh,
+int msm_v4l2_s_parm(struct file *filp, void *fh,
 					struct v4l2_streamparm *a)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_s_param((void *)inst, a);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
 
-	return msm_vidc_s_param((void *)vidc_inst, a);
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_g_parm(struct file *file, void *fh,
+int msm_v4l2_g_parm(struct file *filp, void *fh,
 					struct v4l2_streamparm *a)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_g_param((void *)inst, a);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
 
-	return msm_vidc_g_param((void *)vidc_inst, a);
+	return rc;
 }
 
-int msm_v4l2_s_ctrl(struct file *file, void *fh,
+int msm_v4l2_s_ctrl(struct file *filp, void *fh,
 					struct v4l2_control *a)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_s_ctrl((void *)inst, a);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
 
-	return msm_vidc_s_ctrl((void *)vidc_inst, a);
+	return rc;
 }
 
-int msm_v4l2_g_ctrl(struct file *file, void *fh,
+int msm_v4l2_g_ctrl(struct file *filp, void *fh,
 					struct v4l2_control *a)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_g_ctrl((void *)inst, a);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
 
-	return msm_vidc_g_ctrl((void *)vidc_inst, a);
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_reqbufs(struct file *file, void *fh,
+int msm_v4l2_reqbufs(struct file *filp, void *fh,
 				struct v4l2_requestbuffers *b)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
 
-	return msm_vidc_reqbufs((void *)vidc_inst, b);
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_reqbufs((void *)inst, b);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_qbuf(struct file *file, void *fh,
+int msm_v4l2_qbuf(struct file *filp, void *fh,
 				struct v4l2_buffer *b)
 {
-	struct video_device *vdev = video_devdata(file);
-	return msm_vidc_qbuf(get_vidc_inst(file, fh), vdev->v4l2_dev->mdev, b);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	struct video_device *vdev = video_devdata(filp);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_qbuf(inst, vdev->v4l2_dev->mdev, b);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_dqbuf(struct file *file, void *fh,
+int msm_v4l2_dqbuf(struct file *filp, void *fh,
 				struct v4l2_buffer *b)
 {
-	return msm_vidc_dqbuf(get_vidc_inst(file, fh), b);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_dqbuf(inst, b);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_streamon(struct file *file, void *fh,
+int msm_v4l2_streamon(struct file *filp, void *fh,
 				enum v4l2_buf_type i)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
 
-	return msm_vidc_streamon((void *)vidc_inst, i);
+	inst_lock(inst, __func__);
+	rc = msm_vidc_streamon((void *)inst, i);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_streamoff(struct file *file, void *fh,
+int msm_v4l2_streamoff(struct file *filp, void *fh,
 				enum v4l2_buf_type i)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
 
-	return msm_vidc_streamoff((void *)vidc_inst, i);
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_streamoff((void *)inst, i);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
+
+	return rc;
 }
 
 int msm_v4l2_subscribe_event(struct v4l2_fh *fh,
 				const struct v4l2_event_subscription *sub)
 {
-	struct msm_vidc_inst *vidc_inst = container_of(fh,
-			struct msm_vidc_inst, event_handler);
+	struct msm_vidc_inst *inst;
+	int rc = 0;
+
+	inst = container_of(fh, struct msm_vidc_inst, event_handler);
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_subscribe_event((void *)inst, sub);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
 
-	return msm_vidc_subscribe_event((void *)vidc_inst, sub);
+	put_inst(inst);
+
+	return rc;
 }
 
 int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh,
 				const struct v4l2_event_subscription *sub)
 {
-	struct msm_vidc_inst *vidc_inst = container_of(fh,
-			struct msm_vidc_inst, event_handler);
+	struct msm_vidc_inst *inst;
+	int rc = 0;
+
+	inst = container_of(fh, struct msm_vidc_inst, event_handler);
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
 
-	return msm_vidc_unsubscribe_event((void *)vidc_inst, sub);
+	inst_lock(inst, __func__);
+	rc = msm_vidc_unsubscribe_event((void *)inst, sub);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_decoder_cmd(struct file *file, void *fh,
+int msm_v4l2_decoder_cmd(struct file *filp, void *fh,
 				struct v4l2_decoder_cmd *dec)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
 
-	return msm_vidc_cmd((void *)vidc_inst, (union msm_v4l2_cmd *)dec);
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_cmd((void *)inst, (union msm_v4l2_cmd *)dec);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_encoder_cmd(struct file *file, void *fh,
+int msm_v4l2_encoder_cmd(struct file *filp, void *fh,
 				struct v4l2_encoder_cmd *enc)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_cmd((void *)inst, (union msm_v4l2_cmd *)enc);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
 
-	return msm_vidc_cmd((void *)vidc_inst, (union msm_v4l2_cmd *)enc);
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_enum_framesizes(struct file *file, void *fh,
+int msm_v4l2_enum_framesizes(struct file *filp, void *fh,
 				struct v4l2_frmsizeenum *fsize)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
 
-	return msm_vidc_enum_framesizes((void *)vidc_inst, fsize);
+	inst_lock(inst, __func__);
+	rc = msm_vidc_enum_framesizes((void *)inst, fsize);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_enum_frameintervals(struct file *file, void *fh,
+int msm_v4l2_enum_frameintervals(struct file *filp, void *fh,
 				struct v4l2_frmivalenum *fival)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
 
-	return msm_vidc_enum_frameintervals((void *)vidc_inst, fival);
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_enum_frameintervals((void *)inst, fival);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
+
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_queryctrl(struct file *file, void *fh,
+int msm_v4l2_queryctrl(struct file *filp, void *fh,
 	struct v4l2_queryctrl *ctrl)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_query_ctrl((void *)inst, ctrl);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
 
-	return msm_vidc_query_ctrl((void *)vidc_inst, ctrl);
+	put_inst(inst);
+
+	return rc;
 }
 
-int msm_v4l2_querymenu(struct file *file, void *fh,
+int msm_v4l2_querymenu(struct file *filp, void *fh,
 	struct v4l2_querymenu *qmenu)
 {
-	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+	struct msm_vidc_inst *inst = get_vidc_inst(filp, fh);
+	int rc = 0;
+
+	inst = get_inst_ref(g_core, inst);
+	if (!inst) {
+		d_vpr_e("%s: invalid instance\n", __func__);
+		return -EINVAL;
+	}
+
+	inst_lock(inst, __func__);
+	rc = msm_vidc_query_menu((void *)inst, qmenu);
+	if (rc)
+		i_vpr_e(inst, "%s: failed with %d\n", __func__, rc);
+	inst_unlock(inst, __func__);
 
-	return msm_vidc_query_menu((void *)vidc_inst, qmenu);
+	put_inst(inst);
+
+	return rc;
 }

+ 8 - 8
driver/vidc/src/venus_hfi_response.c

@@ -883,13 +883,13 @@ static int handle_output_metadata_buffer(struct msm_vidc_inst *inst,
 	return rc;
 }
 
-static int handle_dequeue_buffers(struct msm_vidc_inst* inst)
+static int handle_dequeue_buffers(struct msm_vidc_inst *inst)
 {
 	int rc = 0;
 	int i;
-	struct msm_vidc_buffers* buffers;
-	struct msm_vidc_buffer* buf;
-	struct msm_vidc_buffer* dummy;
+	struct msm_vidc_buffers *buffers;
+	struct msm_vidc_buffer *buf;
+	struct msm_vidc_buffer *dummy;
 	static const enum msm_vidc_buffer_type buffer_type[] = {
 		MSM_VIDC_BUF_INPUT_META,
 		MSM_VIDC_BUF_INPUT,
@@ -1503,7 +1503,7 @@ void handle_session_response_work_handler(struct work_struct *work)
 		return;
 	}
 
-	mutex_lock(&inst->lock);
+	inst_lock(inst, __func__);
 	list_for_each_entry_safe(resp_work, dummy, &inst->response_works, list) {
 		switch (resp_work->type) {
 		case RESP_WORK_INPUT_PSC:
@@ -1556,7 +1556,7 @@ void handle_session_response_work_handler(struct work_struct *work)
 		kfree(resp_work->data);
 		kfree(resp_work);
 	}
-	mutex_unlock(&inst->lock);
+	inst_unlock(inst, __func__);
 
 	put_inst(inst);
 }
@@ -1603,7 +1603,7 @@ static int handle_session_response(struct msm_vidc_core *core,
 		return -EINVAL;
 	}
 
-	mutex_lock(&inst->lock);
+	inst_lock(inst, __func__);
 	/* search for special pkt */
 	pkt = (u8 *)((u8 *)hdr + sizeof(struct hfi_header));
 	for (i = 0; i < hdr->num_packets; i++) {
@@ -1644,7 +1644,7 @@ static int handle_session_response(struct msm_vidc_core *core,
 		goto exit;
 
 exit:
-	mutex_unlock(&inst->lock);
+	inst_unlock(inst, __func__);
 	put_inst(inst);
 	return rc;
 }