diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index 0523a6302f..2c8f03ed29 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -519,6 +519,9 @@ bool core_lock_check(struct msm_vidc_core *core, const char *function); void inst_lock(struct msm_vidc_inst *inst, const char *function); void inst_unlock(struct msm_vidc_inst *inst, const char *function); bool inst_lock_check(struct msm_vidc_inst *inst, const char *function); +bool client_lock_check(struct msm_vidc_inst *inst, const char *func); +void client_lock(struct msm_vidc_inst *inst, const char *function); +void client_unlock(struct msm_vidc_inst *inst, const char *function); int msm_vidc_update_bitstream_buffer_size(struct msm_vidc_inst *inst); int msm_vidc_update_meta_port_settings(struct msm_vidc_inst *inst); int msm_vidc_update_buffer_count(struct msm_vidc_inst *inst, u32 port); diff --git a/driver/vidc/inc/msm_vidc_inst.h b/driver/vidc/inc/msm_vidc_inst.h index 6c1371567c..cac6126da0 100644 --- a/driver/vidc/inc/msm_vidc_inst.h +++ b/driver/vidc/inc/msm_vidc_inst.h @@ -98,6 +98,7 @@ struct msm_vidc_inst { struct list_head list; struct mutex lock; struct mutex request_lock; + struct mutex client_lock; enum msm_vidc_inst_state state; enum msm_vidc_domain_type domain; enum msm_vidc_codec_type codec; diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index 262515f4d1..a682a71f3a 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -899,6 +899,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type) kref_init(&inst->kref); mutex_init(&inst->lock); mutex_init(&inst->request_lock); + mutex_init(&inst->client_lock); msm_vidc_update_debug_str(inst); i_vpr_h(inst, "Opening video instance: %d\n", session_type); @@ -1035,6 +1036,7 @@ int msm_vidc_close(void *instance) core = inst->core; i_vpr_h(inst, "%s()\n", __func__); + client_lock(inst, __func__); inst_lock(inst, __func__); /* print final stats */ msm_vidc_print_stats(inst); @@ -1042,6 +1044,7 @@ int msm_vidc_close(void *instance) msm_vidc_remove_session(inst); msm_vidc_destroy_buffers(inst); inst_unlock(inst, __func__); + client_unlock(inst, __func__); cancel_response_work_sync(inst); cancel_stability_work_sync(inst); cancel_stats_work_sync(inst); diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index 277d663fe6..080ae29909 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -5620,6 +5620,7 @@ static void msm_vidc_close_helper(struct kref *kref) if (inst->response_workq) destroy_workqueue(inst->response_workq); msm_vidc_remove_dangling_session(inst); + mutex_destroy(&inst->client_lock); mutex_destroy(&inst->request_lock); mutex_destroy(&inst->lock); kfree(inst->capabilities); @@ -5712,6 +5713,21 @@ void inst_unlock(struct msm_vidc_inst *inst, const char *function) mutex_unlock(&inst->lock); } +bool client_lock_check(struct msm_vidc_inst *inst, const char *func) +{ + return mutex_is_locked(&inst->client_lock); +} + +void client_lock(struct msm_vidc_inst *inst, const char *function) +{ + mutex_lock(&inst->client_lock); +} + +void client_unlock(struct msm_vidc_inst *inst, const char *function) +{ + mutex_unlock(&inst->client_lock); +} + int msm_vidc_update_bitstream_buffer_size(struct msm_vidc_inst *inst) { struct msm_vidc_core *core; diff --git a/driver/vidc/src/msm_vidc_v4l2.c b/driver/vidc/src/msm_vidc_v4l2.c index 809c1627ce..61943a6880 100644 --- a/driver/vidc/src/msm_vidc_v4l2.c +++ b/driver/vidc/src/msm_vidc_v4l2.c @@ -76,6 +76,7 @@ int msm_v4l2_querycap(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_querycap((void *)inst, cap); if (rc) @@ -83,6 +84,7 @@ int msm_v4l2_querycap(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -100,6 +102,7 @@ int msm_v4l2_enum_fmt(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_enum_fmt((void *)inst, f); if (rc) @@ -107,6 +110,7 @@ int msm_v4l2_enum_fmt(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -123,6 +127,7 @@ int msm_v4l2_try_fmt(struct file *filp, void *fh, struct v4l2_format *f) return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); if (is_session_error(inst)) { i_vpr_e(inst, "%s: inst in error state\n", __func__); @@ -135,6 +140,7 @@ int msm_v4l2_try_fmt(struct file *filp, void *fh, struct v4l2_format *f) unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -152,6 +158,7 @@ int msm_v4l2_s_fmt(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); if (is_session_error(inst)) { i_vpr_e(inst, "%s: inst in error state\n", __func__); @@ -164,6 +171,7 @@ int msm_v4l2_s_fmt(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -181,6 +189,7 @@ int msm_v4l2_g_fmt(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_g_fmt((void *)inst, f); if (rc) @@ -188,6 +197,7 @@ int msm_v4l2_g_fmt(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -205,6 +215,7 @@ int msm_v4l2_s_selection(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); if (is_session_error(inst)) { i_vpr_e(inst, "%s: inst in error state\n", __func__); @@ -217,6 +228,7 @@ int msm_v4l2_s_selection(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -234,6 +246,7 @@ int msm_v4l2_g_selection(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_g_selection((void *)inst, s); if (rc) @@ -241,6 +254,7 @@ int msm_v4l2_g_selection(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -258,6 +272,7 @@ int msm_v4l2_s_parm(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); if (is_session_error(inst)) { i_vpr_e(inst, "%s: inst in error state\n", __func__); @@ -270,6 +285,7 @@ int msm_v4l2_s_parm(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -287,6 +303,7 @@ int msm_v4l2_g_parm(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_g_param((void *)inst, a); if (rc) @@ -294,6 +311,7 @@ int msm_v4l2_g_parm(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -311,6 +329,7 @@ int msm_v4l2_reqbufs(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_reqbufs((void *)inst, b); if (rc) @@ -318,6 +337,7 @@ int msm_v4l2_reqbufs(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -335,6 +355,7 @@ int msm_v4l2_querybuf(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_querybuf((void *)inst, b); if (rc) @@ -342,6 +363,7 @@ int msm_v4l2_querybuf(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -360,12 +382,14 @@ int msm_v4l2_create_bufs(struct file *filp, void *fh, } inst_lock(inst, __func__); + client_lock(inst, __func__); rc = msm_vidc_create_bufs((void *)inst, b); if (rc) goto unlock; unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -384,6 +408,7 @@ int msm_v4l2_prepare_buf(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_prepare_buf((void *)inst, vdev->v4l2_dev->mdev, b); if (rc) @@ -391,6 +416,7 @@ int msm_v4l2_prepare_buf(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -439,6 +465,7 @@ int msm_v4l2_dqbuf(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_dqbuf(inst, b); if (rc) @@ -446,6 +473,7 @@ int msm_v4l2_dqbuf(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -508,6 +536,7 @@ int msm_v4l2_subscribe_event(struct v4l2_fh *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); if (is_session_error(inst)) { i_vpr_e(inst, "%s: inst in error state\n", __func__); @@ -520,6 +549,7 @@ int msm_v4l2_subscribe_event(struct v4l2_fh *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -538,6 +568,7 @@ int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_unsubscribe_event((void *)inst, sub); if (rc) @@ -545,6 +576,7 @@ int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -562,6 +594,7 @@ int msm_v4l2_try_decoder_cmd(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); if (is_session_error(inst)) { i_vpr_e(inst, "%s: inst in error state\n", __func__); @@ -574,6 +607,7 @@ int msm_v4l2_try_decoder_cmd(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -591,6 +625,7 @@ int msm_v4l2_decoder_cmd(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); if (is_session_error(inst)) { i_vpr_e(inst, "%s: inst in error state\n", __func__); @@ -603,6 +638,7 @@ int msm_v4l2_decoder_cmd(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -620,6 +656,7 @@ int msm_v4l2_try_encoder_cmd(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); if (is_session_error(inst)) { i_vpr_e(inst, "%s: inst in error state\n", __func__); @@ -632,6 +669,7 @@ int msm_v4l2_try_encoder_cmd(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -649,6 +687,7 @@ int msm_v4l2_encoder_cmd(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); if (is_session_error(inst)) { i_vpr_e(inst, "%s: inst in error state\n", __func__); @@ -661,6 +700,7 @@ int msm_v4l2_encoder_cmd(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -678,6 +718,7 @@ int msm_v4l2_enum_framesizes(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_enum_framesizes((void *)inst, fsize); if (rc) @@ -685,6 +726,7 @@ int msm_v4l2_enum_framesizes(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -702,6 +744,7 @@ int msm_v4l2_enum_frameintervals(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_enum_frameintervals((void *)inst, fival); if (rc) @@ -709,6 +752,7 @@ int msm_v4l2_enum_frameintervals(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -726,6 +770,7 @@ int msm_v4l2_queryctrl(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_query_ctrl((void *)inst, ctrl); if (rc) @@ -733,6 +778,7 @@ int msm_v4l2_queryctrl(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; @@ -750,6 +796,7 @@ int msm_v4l2_querymenu(struct file *filp, void *fh, return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); rc = msm_vidc_query_menu((void *)inst, qmenu); if (rc) @@ -757,6 +804,7 @@ int msm_v4l2_querymenu(struct file *filp, void *fh, unlock: inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; diff --git a/driver/vidc/src/msm_vidc_vb2.c b/driver/vidc/src/msm_vidc_vb2.c index e3d6ddb980..5aeef1b791 100644 --- a/driver/vidc/src/msm_vidc_vb2.c +++ b/driver/vidc/src/msm_vidc_vb2.c @@ -204,6 +204,7 @@ int msm_vidc_start_streaming(struct vb2_queue *q, unsigned int count) return -EINVAL; } + client_lock(inst, __func__); inst_lock(inst, __func__); if (is_session_error(inst)) { i_vpr_e(inst, "%s: inst in error state\n", __func__); @@ -337,6 +338,7 @@ unlock: msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__); } inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return rc; } @@ -358,6 +360,7 @@ void msm_vidc_stop_streaming(struct vb2_queue *q) return; } + client_lock(inst, __func__); inst_lock(inst, __func__); if (q->type == INPUT_META_PLANE || q->type == OUTPUT_META_PLANE) { i_vpr_h(inst, "%s: nothing to stop on %s\n", @@ -420,6 +423,7 @@ unlock: msm_vidc_change_inst_state(inst, MSM_VIDC_ERROR, __func__); } inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); return; } @@ -443,6 +447,7 @@ void msm_vidc_buf_queue(struct vb2_buffer *vb2) return; } + client_lock(inst, __func__); inst_lock(inst, __func__); if (is_session_error(inst)) { i_vpr_e(inst, "%s: inst in error state\n", __func__); @@ -525,6 +530,7 @@ unlock: vb2_buffer_done(vb2, VB2_BUF_STATE_ERROR); } inst_unlock(inst, __func__); + client_unlock(inst, __func__); put_inst(inst); }