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

Commit 2a30c8fb authored by Arun Menon's avatar Arun Menon
Browse files

msm: vidc: Avoid deadlock in dcvs during scale clocks



There is a deadlock condition in dcvs when driver
tries to queue a buffer which it held, on receipt of
release reference event from the firmware. The driver
tries to acquire the registeredbufs.lock, which it has
already acquired in the same thread in handle_event_change().
Avoid this condition by removing the need to acquire the
lock, by computing the number of buffers held in the driver
whenever the buffer references are incremented\decremented.

Change-Id: Ic985f0672adc1e2c9e8a37f3d72883ef234d1b72
Signed-off-by: default avatarArun Menon <avmenon@codeaurora.org>
parent f81d0b1f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1489,6 +1489,9 @@ int buf_ref_get(struct msm_vidc_inst *inst, struct buffer_info *binfo)
		dprintk(VIDC_DBG, "%s: invalid ref_cnt: %d\n", __func__, cnt);
		cnt = -EINVAL;
	}
	if (cnt == 2)
		inst->buffers_held_in_driver++;

	dprintk(VIDC_DBG, "REF_GET[%d] fd[0] = %d\n", cnt, binfo->fd[0]);

	return cnt;
@@ -1536,6 +1539,7 @@ int buf_ref_put(struct msm_vidc_inst *inst, struct buffer_info *binfo)
			binfo->fd[0]);
		binfo->pending_deletion = true;
	} else if (qbuf_again) {
		inst->buffers_held_in_driver--;
		rc = qbuf_dynamic_buf(inst, binfo);
		if (!rc)
			return rc;
+1 −12
Original line number Diff line number Diff line
@@ -126,19 +126,8 @@ static inline int get_pending_bufs_fw(struct msm_vidc_inst *inst)

	if (inst->state >= MSM_VIDC_OPEN_DONE &&
		inst->state < MSM_VIDC_STOP_DONE) {
		struct buffer_info *temp = NULL;

		fw_out_qsize = inst->count.ftb - inst->count.fbd;

		mutex_lock(&inst->registeredbufs.lock);
		list_for_each_entry(temp, &inst->registeredbufs.list, list) {
			if (temp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
				!temp->inactive &&
				atomic_read(&temp->ref_count) == 2) {
				buffers_in_driver++;
			}
		}
		mutex_unlock(&inst->registeredbufs.lock);
		buffers_in_driver = inst->buffers_held_in_driver;
	}

	return fw_out_qsize + buffers_in_driver;
+1 −0
Original line number Diff line number Diff line
@@ -298,6 +298,7 @@ struct msm_vidc_inst {
	enum msm_vidc_pixel_depth bit_depth;
	struct kref kref;
	unsigned long instant_bitrate;
	u32 buffers_held_in_driver;
};

extern struct msm_vidc_drv *vidc_driver;