Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e302f861 authored by Paras Nagda's avatar Paras Nagda Committed by Gerrit - the friendly Code Review server
Browse files

msm: vidc: Fix dead lock during long stability run



During long run stability there is a possibility
that first thread (T1) which has acquired sync lock
during streamon, is waiting for ctrl lock to be
released by second thread (T2) and second thread (T2)
while performing a set ctrl, has already acquired ctrl lock
and is waiting for sync lock to be released by T1 there
by creating a deadlock condition.

With this change, ctrl lock is avoided by keeping the
operating rate as part of instance variable and not by
getting it from the control directly.

Change-Id: Ie5e3dbcb9007fb2961c8a01f292fcce193f33c15
Signed-off-by: default avatarParas Nagda <pnagda@codeaurora.org>
parent 5ec06e90
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -1943,6 +1943,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->prop.operating_rate = 0;
	memcpy(&inst->fmts[OUTPUT_PORT], &vdec_formats[2],
						sizeof(struct msm_vidc_format));
	memcpy(&inst->fmts[CAPTURE_PORT], &vdec_formats[0],
@@ -2551,8 +2552,33 @@ 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:
		if ((ctrl->val >> 16) < inst->capability.frame_rate.min ||
			 (ctrl->val >> 16) > inst->capability.frame_rate.max) {
			dprintk(VIDC_ERR, "Invalid operating rate %u\n",
				(ctrl->val >> 16));
			rc = -ENOTSUPP;
		} else {
			dprintk(VIDC_DBG,
				"inst(%pK) operating rate changed from %d to %d\n",
				inst, inst->prop.operating_rate >> 16,
					ctrl->val >> 16);
			inst->prop.operating_rate = ctrl->val;
		}
		break;
	default:
		break;
+26 −0
Original line number Diff line number Diff line
@@ -3625,8 +3625,33 @@ 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:
		if ((ctrl->val >> 16) < inst->capability.frame_rate.min ||
			 (ctrl->val >> 16) > inst->capability.frame_rate.max) {
			dprintk(VIDC_ERR, "Invalid operating rate %u\n",
				(ctrl->val >> 16));
			rc = -ENOTSUPP;
		} else {
			dprintk(VIDC_DBG,
				"inst(%pK) operating rate changed from %d to %d\n",
				inst, inst->prop.operating_rate >> 16,
					ctrl->val >> 16);
			inst->prop.operating_rate = ctrl->val;
		}
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE:
	{
@@ -4067,6 +4092,7 @@ int msm_venc_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->prop.operating_rate = 0;
	inst->capability.pixelprocess_capabilities = 0;
	memcpy(&inst->fmts[CAPTURE_PORT], &venc_formats[4],
						sizeof(struct msm_vidc_format));
+13 −20
Original line number Diff line number Diff line
@@ -258,14 +258,9 @@ int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst)
	return 0;
}

static inline bool is_non_realtime_session(struct msm_vidc_inst *inst)
static inline bool is_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);
	return !!(inst->flags & VIDC_REALTIME);
}

enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst)
@@ -297,17 +292,15 @@ static int msm_comm_get_mbs_per_frame(struct msm_vidc_inst *inst)

static int msm_comm_get_mbs_per_sec(struct msm_vidc_inst *inst)
{
	int rc;
	u32 fps;
	struct v4l2_control ctrl;
	int mb_per_frame;
	u32 oper_rate;

	mb_per_frame = msm_comm_get_mbs_per_frame(inst);
	oper_rate = inst->prop.operating_rate;

	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 (oper_rate) {
		fps = (oper_rate >> 16) ? oper_rate >> 16 : 1;
		/*
		 * Check if operating rate is less than fps.
		 * If Yes, then use fps to scale the clocks
@@ -354,7 +347,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);
@@ -535,7 +528,7 @@ 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;
		u32 oper_rate;

		codec = inst->session_type == MSM_VIDC_DECODER ?
			inst->fmts[OUTPUT_PORT].fourcc :
@@ -552,11 +545,11 @@ 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;
		oper_rate = inst->prop.operating_rate;

		if (oper_rate)
			vote_data[i].fps = (oper_rate >> 16) ?
				oper_rate >> 16 : 1;
		else
			vote_data[i].fps = inst->prop.fps;

+2 −0
Original line number Diff line number Diff line
@@ -164,6 +164,7 @@ struct session_prop {
	u32 height[MAX_PORT_NUM];
	u32 fps;
	u32 bitrate;
	u32 operating_rate;
};

struct buf_queue {
@@ -230,6 +231,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 {