When vdec_start_streaming() fails, the error path clears buffers from both
the source and destination queues unconditionally. If one queue was already
streaming successfully from a prior invocation, flushing its buffers behind
its back leaves videobuf2 deadlocked waiting for completions.

Fix this by only sweeping buffers from the specific queue type container
that failed to initialize.

Cc: Nicolas Dufresne <[email protected]>
Reported-by: Sashiko <[email protected]>
Closes: https://lore.kernel.org/all/[email protected]/
Fixes: 3e7f51bd9607 ("media: meson: add v4l2 m2m video decoder driver")
Signed-off-by: Anand Moon <[email protected]>
---
 drivers/staging/media/meson/vdec/vdec.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/media/meson/vdec/vdec.c 
b/drivers/staging/media/meson/vdec/vdec.c
index 8a5bf1a96830..698a95566ad2 100644
--- a/drivers/staging/media/meson/vdec/vdec.c
+++ b/drivers/staging/media/meson/vdec/vdec.c
@@ -386,15 +386,15 @@ static int vdec_start_streaming(struct vb2_queue *q, 
unsigned int count)
        sess->status = STATUS_STOPPED;
        mutex_unlock(&core->lock);
 
-       while ((buf = v4l2_m2m_src_buf_remove(sess->m2m_ctx)))
-               v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED);
-       while ((buf = v4l2_m2m_dst_buf_remove(sess->m2m_ctx)))
-               v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED);
-
-       if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+       if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
                sess->streamon_out = 0;
-       else
+               while ((buf = v4l2_m2m_src_buf_remove(sess->m2m_ctx)))
+                       v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED);
+       } else {
                sess->streamon_cap = 0;
+               while ((buf = v4l2_m2m_dst_buf_remove(sess->m2m_ctx)))
+                       v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED);
+       }
 
        return ret;
 }
-- 
2.50.1

Reply via email to