lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251020173332.2271145-1-b-brnich@ti.com>
Date: Mon, 20 Oct 2025 12:33:32 -0500
From: Brandon Brnich <b-brnich@...com>
To: Nas Chung <nas.chung@...psnmedia.com>,
        Jackson Lee
	<jackson.lee@...psnmedia.com>,
        Mauro Carvalho Chehab <mchehab@...nel.org>,
        <linux-media@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
        Nicolas
 Dufresne <nicolas.dufresne@...labora.com>
CC: Darren Etheridge <detheridge@...com>, Brandon Brnich <b-brnich@...com>
Subject: [PATCH] media: chips-media: wave5: Fix Hang in Encoder

Wave5 encoder driver only changed states to PIC_RUN in start streaming by
making the assumption that VIDIOC STREAMON call has already been called.
In frameworks like FFMPEG, this condition has not been met when in the
start streaming function resulting in the application hanging. Therefore,
job_ready and device_run need to be extended to have support for this case.

Signed-off-by: Brandon Brnich <b-brnich@...com>
---
 .../chips-media/wave5/wave5-vpu-enc.c         | 74 +++++++++++++------
 1 file changed, 51 insertions(+), 23 deletions(-)

diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
index a02853d42d61..3a3b585ceb8e 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c
@@ -705,6 +705,11 @@ static int wave5_vpu_enc_encoder_cmd(struct file *file, void *fh, struct v4l2_en
 
 		m2m_ctx->last_src_buf = v4l2_m2m_last_src_buf(m2m_ctx);
 		m2m_ctx->is_draining = true;
+
+		if (v4l2_m2m_num_dst_bufs_ready(m2m_ctx) > 0) {
+			dev_dbg(inst->dev->dev, "Forcing job run for draining\n");
+			v4l2_m2m_try_schedule(m2m_ctx);
+		}
 		break;
 	case V4L2_ENC_CMD_START:
 		break;
@@ -1411,6 +1416,34 @@ static int prepare_fb(struct vpu_instance *inst)
 	return ret;
 }
 
+static int wave5_vpu_enc_prepare_cap_seq(struct vpu_instance *inst)
+{
+	int ret = 0;
+
+	ret = initialize_sequence(inst);
+	if (ret) {
+		dev_warn(inst->dev->dev, "Sequence not found: %d\n", ret);
+		return ret;
+	}
+	ret = switch_state(inst, VPU_INST_STATE_INIT_SEQ);
+	if (ret)
+		return ret;
+
+	/*
+	 * The sequence must be analyzed first to calculate the proper
+	 * size of the auxiliary buffers.
+	 */
+	ret = prepare_fb(inst);
+	if (ret) {
+		dev_warn(inst->dev->dev, "Framebuffer preparation, fail: %d\n", ret);
+		return ret;
+	}
+
+	ret = switch_state(inst, VPU_INST_STATE_PIC_RUN);
+
+	return ret;
+}
+
 static int wave5_vpu_enc_start_streaming(struct vb2_queue *q, unsigned int count)
 {
 	struct vpu_instance *inst = vb2_get_drv_priv(q);
@@ -1453,27 +1486,8 @@ static int wave5_vpu_enc_start_streaming(struct vb2_queue *q, unsigned int count
 		if (ret)
 			goto return_buffers;
 	}
-	if (inst->state == VPU_INST_STATE_OPEN && m2m_ctx->cap_q_ctx.q.streaming) {
-		ret = initialize_sequence(inst);
-		if (ret) {
-			dev_warn(inst->dev->dev, "Sequence not found: %d\n", ret);
-			goto return_buffers;
-		}
-		ret = switch_state(inst, VPU_INST_STATE_INIT_SEQ);
-		if (ret)
-			goto return_buffers;
-		/*
-		 * The sequence must be analyzed first to calculate the proper
-		 * size of the auxiliary buffers.
-		 */
-		ret = prepare_fb(inst);
-		if (ret) {
-			dev_warn(inst->dev->dev, "Framebuffer preparation, fail: %d\n", ret);
-			goto return_buffers;
-		}
-
-		ret = switch_state(inst, VPU_INST_STATE_PIC_RUN);
-	}
+	if (inst->state == VPU_INST_STATE_OPEN && m2m_ctx->cap_q_ctx.q.streaming)
+		ret = wave5_vpu_enc_prepare_cap_seq(inst);
 	if (ret)
 		goto return_buffers;
 
@@ -1598,6 +1612,14 @@ static void wave5_vpu_enc_device_run(void *priv)
 
 	pm_runtime_resume_and_get(inst->dev->dev);
 	switch (inst->state) {
+	case VPU_INST_STATE_OPEN:
+		ret = wave5_vpu_enc_prepare_cap_seq(inst);
+		if (ret) {
+			dev_warn(inst->dev->dev, "Framebuffer preparation, fail: %d\n", ret);
+			switch_state(inst, VPU_INST_STATE_STOP);
+			break;
+		}
+		fallthrough;
 	case VPU_INST_STATE_PIC_RUN:
 		ret = start_encode(inst, &fail_res);
 		if (ret) {
@@ -1633,6 +1655,12 @@ static int wave5_vpu_enc_job_ready(void *priv)
 	case VPU_INST_STATE_NONE:
 		dev_dbg(inst->dev->dev, "Encoder must be open to start queueing M2M jobs!\n");
 		return false;
+	case VPU_INST_STATE_OPEN:
+		if (wave5_vpu_both_queues_are_streaming(inst)) {
+			dev_dbg(inst->dev->dev, "Both queues have been turned on now, M2M job can occur\n");
+			return true;
+		}
+		return false;
 	case VPU_INST_STATE_PIC_RUN:
 		if (m2m_ctx->is_draining || v4l2_m2m_num_src_bufs_ready(m2m_ctx)) {
 			dev_dbg(inst->dev->dev, "Encoder ready for a job, state: %s\n",
@@ -1642,9 +1670,9 @@ static int wave5_vpu_enc_job_ready(void *priv)
 		fallthrough;
 	default:
 		dev_dbg(inst->dev->dev,
-			"Encoder not ready for a job, state: %s, %s draining, %d src bufs ready\n",
+			"Encoder not ready for a job, state: %s, %s draining, %d src bufs ready, %d dst bufs ready\n",
 			state_to_str(inst->state), m2m_ctx->is_draining ? "is" : "is not",
-			v4l2_m2m_num_src_bufs_ready(m2m_ctx));
+			v4l2_m2m_num_src_bufs_ready(m2m_ctx), v4l2_m2m_num_dst_bufs_ready(m2m_ctx));
 		break;
 	}
 	return false;
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ