msm: vidc: fix lock issue in msm_comm_get_mbs_per_sec()
Forward thread acquired v4l2_ctrl->handler->lock in v4l2_s_ctrl() and waiting for response from response thread. Response thread was blocked on core->lock which was acquired by second forward thread. The second forward thread acquired core->lock and called v4l2_g_ctrl() in msm_comm_get_mbs_per_sec() where it was blocked on same v4l2_ctrl->handler->lock and hence response thread was not unblocked. Resolve the deadlock issue by avoiding v4l2_g_ctrl() call in msm_comm_get_mbs_per_sec(). CRs-Fixed: 1095539 Change-Id: I73c2a74f1bb86f2b0359be54ed4f7675051db7b0 Signed-off-by: Maheshwar Ajja <majja@codeaurora.org>
This commit is contained in:
parent
d43553d47d
commit
076fd7d351
4 changed files with 53 additions and 24 deletions
|
@ -1903,6 +1903,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
|
|||
inst->buffer_mode_set[OUTPUT_PORT] = HAL_BUFFER_MODE_STATIC;
|
||||
inst->buffer_mode_set[CAPTURE_PORT] = HAL_BUFFER_MODE_STATIC;
|
||||
inst->prop.fps = DEFAULT_FPS;
|
||||
inst->operating_rate = 0;
|
||||
memcpy(&inst->fmts[OUTPUT_PORT], &vdec_formats[2],
|
||||
sizeof(struct msm_vidc_format));
|
||||
memcpy(&inst->fmts[CAPTURE_PORT], &vdec_formats[0],
|
||||
|
@ -2501,8 +2502,25 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
|
|||
*/
|
||||
hal_property.enable = !(ctrl->val);
|
||||
pdata = &hal_property;
|
||||
switch (ctrl->val) {
|
||||
case V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE:
|
||||
inst->flags &= ~VIDC_REALTIME;
|
||||
break;
|
||||
case V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE:
|
||||
inst->flags |= VIDC_REALTIME;
|
||||
break;
|
||||
default:
|
||||
dprintk(VIDC_WARN,
|
||||
"inst(%pK) invalid priority ctrl value %#x\n",
|
||||
inst, ctrl->val);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE:
|
||||
dprintk(VIDC_DBG,
|
||||
"inst(%pK) operating rate changed from %d to %d\n",
|
||||
inst, inst->operating_rate >> 16, ctrl->val >> 16);
|
||||
inst->operating_rate = ctrl->val;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -3166,8 +3166,25 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
|
|||
*/
|
||||
enable.enable = !(ctrl->val);
|
||||
pdata = &enable;
|
||||
switch (ctrl->val) {
|
||||
case V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE:
|
||||
inst->flags &= ~VIDC_REALTIME;
|
||||
break;
|
||||
case V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE:
|
||||
inst->flags |= VIDC_REALTIME;
|
||||
break;
|
||||
default:
|
||||
dprintk(VIDC_WARN,
|
||||
"inst(%pK) invalid priority ctrl value %#x\n",
|
||||
inst, ctrl->val);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE:
|
||||
dprintk(VIDC_DBG,
|
||||
"inst(%pK) operating rate changed from %d to %d\n",
|
||||
inst, inst->operating_rate >> 16, ctrl->val >> 16);
|
||||
inst->operating_rate = ctrl->val;
|
||||
break;
|
||||
case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE:
|
||||
{
|
||||
|
@ -3558,6 +3575,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
|
|||
inst->buffer_mode_set[CAPTURE_PORT] = HAL_BUFFER_MODE_STATIC;
|
||||
inst->prop.fps = DEFAULT_FPS;
|
||||
inst->capability.pixelprocess_capabilities = 0;
|
||||
inst->operating_rate = 0;
|
||||
memcpy(&inst->fmts[CAPTURE_PORT], &venc_formats[4],
|
||||
sizeof(struct msm_vidc_format));
|
||||
memcpy(&inst->fmts[OUTPUT_PORT], &venc_formats[0],
|
||||
|
|
|
@ -107,6 +107,11 @@ static inline bool is_low_power_session(struct msm_vidc_inst *inst)
|
|||
return !!(inst->flags & VIDC_LOW_POWER);
|
||||
}
|
||||
|
||||
static inline bool is_realtime_session(struct msm_vidc_inst *inst)
|
||||
{
|
||||
return !!(inst->flags & VIDC_REALTIME);
|
||||
}
|
||||
|
||||
int msm_comm_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
|
||||
{
|
||||
return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
|
||||
|
@ -257,16 +262,6 @@ int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline bool is_non_realtime_session(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
struct v4l2_control ctrl = {
|
||||
.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY
|
||||
};
|
||||
rc = msm_comm_g_ctrl(inst, &ctrl);
|
||||
return (!rc && ctrl.value);
|
||||
}
|
||||
|
||||
enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst)
|
||||
{
|
||||
switch (msm_comm_g_ctrl_for_id(inst,
|
||||
|
@ -282,8 +277,7 @@ enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst)
|
|||
static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int output_port_mbs, capture_port_mbs;
|
||||
int fps, rc;
|
||||
struct v4l2_control ctrl;
|
||||
int fps;
|
||||
|
||||
output_port_mbs = inst->in_reconfig ?
|
||||
NUM_MBS_PER_FRAME(inst->reconfig_width,
|
||||
|
@ -294,18 +288,18 @@ static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst)
|
|||
capture_port_mbs = NUM_MBS_PER_FRAME(inst->prop.width[CAPTURE_PORT],
|
||||
inst->prop.height[CAPTURE_PORT]);
|
||||
|
||||
ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
|
||||
rc = msm_comm_g_ctrl(inst, &ctrl);
|
||||
if (!rc && ctrl.value) {
|
||||
fps = (ctrl.value >> 16) ? ctrl.value >> 16 : 1;
|
||||
if (inst->operating_rate) {
|
||||
fps = (inst->operating_rate >> 16) ?
|
||||
inst->operating_rate >> 16 : 1;
|
||||
/*
|
||||
* Check if operating rate is less than fps.
|
||||
* If Yes, then use fps to scale clocks
|
||||
*/
|
||||
fps = fps > inst->prop.fps ? fps : inst->prop.fps;
|
||||
return max(output_port_mbs, capture_port_mbs) * fps;
|
||||
} else
|
||||
} else {
|
||||
return max(output_port_mbs, capture_port_mbs) * inst->prop.fps;
|
||||
}
|
||||
}
|
||||
|
||||
int msm_comm_get_inst_load(struct msm_vidc_inst *inst,
|
||||
|
@ -344,7 +338,7 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst,
|
|||
* ----------------|----------------------|------------------------|
|
||||
*/
|
||||
|
||||
if (is_non_realtime_session(inst) &&
|
||||
if (!is_realtime_session(inst) &&
|
||||
(quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD)) {
|
||||
if (!inst->prop.fps) {
|
||||
dprintk(VIDC_INFO, "instance:%pK fps = 0\n", inst);
|
||||
|
@ -523,7 +517,6 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core)
|
|||
|
||||
list_for_each_entry(inst, &core->instances, list) {
|
||||
int codec = 0, yuv = 0;
|
||||
struct v4l2_control ctrl;
|
||||
|
||||
codec = inst->session_type == MSM_VIDC_DECODER ?
|
||||
inst->fmts[OUTPUT_PORT].fourcc :
|
||||
|
@ -540,11 +533,9 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core)
|
|||
vote_data[i].height = max(inst->prop.height[CAPTURE_PORT],
|
||||
inst->prop.height[OUTPUT_PORT]);
|
||||
|
||||
ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
|
||||
rc = msm_comm_g_ctrl(inst, &ctrl);
|
||||
if (!rc && ctrl.value)
|
||||
vote_data[i].fps = (ctrl.value >> 16) ?
|
||||
ctrl.value >> 16 : 1;
|
||||
if (inst->operating_rate)
|
||||
vote_data[i].fps = (inst->operating_rate >> 16) ?
|
||||
inst->operating_rate >> 16 : 1;
|
||||
else
|
||||
vote_data[i].fps = inst->prop.fps;
|
||||
|
||||
|
|
|
@ -230,6 +230,7 @@ enum msm_vidc_modes {
|
|||
VIDC_TURBO = BIT(1),
|
||||
VIDC_THUMBNAIL = BIT(2),
|
||||
VIDC_LOW_POWER = BIT(3),
|
||||
VIDC_REALTIME = BIT(4),
|
||||
};
|
||||
|
||||
struct msm_vidc_core {
|
||||
|
@ -298,6 +299,7 @@ struct msm_vidc_inst {
|
|||
atomic_t in_flush;
|
||||
u32 pic_struct;
|
||||
u32 colour_space;
|
||||
u32 operating_rate;
|
||||
};
|
||||
|
||||
extern struct msm_vidc_drv *vidc_driver;
|
||||
|
|
Loading…
Add table
Reference in a new issue