summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaheshwar Ajja <majja@codeaurora.org>2016-11-29 13:14:11 -0800
committerMaheshwar Ajja <majja@codeaurora.org>2016-11-30 11:39:49 -0800
commit076fd7d3510e8b954ff4e5ca2ed87a3273bceeb5 (patch)
tree4201d925cff4fa77a78bcf6e38e858d9653af46a
parentd43553d47d6964196c17c7bad0eed1c735a156f2 (diff)
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>
-rw-r--r--drivers/media/platform/msm/vidc/msm_vdec.c18
-rw-r--r--drivers/media/platform/msm/vidc/msm_venc.c18
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.c39
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_internal.h2
4 files changed, 53 insertions, 24 deletions
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index becea0c59521..dc178801fe4f 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -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;
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index 4ec331d121d9..cab5db542b00 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -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],
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 73c52841fd34..7da05112cbf6 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -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;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index ffe4456570e3..3ad85f53a8b0 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -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;