On Sat Jan 31 22:03:23 2026 +0000, Ziyi Guo wrote:
> Add spin_lock_irqsave()/spin_unlock_irqrestore() around send_eos_event()
> calls in the VB2 buffer queue and streamoff callbacks to fix the missing
> lock protection.
> 
> wave5_vpu_dec_buf_queue_dst() and streamoff_output() call send_eos_event()
> without holding inst->state_spinlock. However, send_eos_event() has
> lockdep_assert_held(&inst->state_spinlock) indicating that callers must
> hold this lock.
> 
> Other callers of send_eos_event() properly acquire the spinlock:
> - wave5_vpu_dec_finish_decode() acquires lock at line 431
> - wave5_vpu_dec_encoder_cmd() acquires lock at line 821
> - wave5_vpu_dec_device_run() acquires lock at line 1592
> 
> Signed-off-by: Ziyi Guo <[email protected]>
> Reviewed-by: Nicolas Dufresne <[email protected]>
> Fixes: 9707a6254a8a6b ("media: chips-media: wave5: Add the v4l2 layer")
> Cc: [email protected]
> Signed-off-by: Nicolas Dufresne <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

---

diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c 
b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
index 80e1831a42e0..18cd1a6a7e1d 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
@@ -1303,13 +1303,17 @@ static void wave5_vpu_dec_buf_queue_dst(struct 
vb2_buffer *vb)
 
        if (vb2_is_streaming(vb->vb2_queue) && 
v4l2_m2m_dst_buf_is_last(m2m_ctx)) {
                unsigned int i;
+               unsigned long flags;
 
                for (i = 0; i < vb->num_planes; i++)
                        vb2_set_plane_payload(vb, i, 0);
 
                vbuf->field = V4L2_FIELD_NONE;
 
+               spin_lock_irqsave(&inst->state_spinlock, flags);
                send_eos_event(inst);
+               spin_unlock_irqrestore(&inst->state_spinlock, flags);
+
                v4l2_m2m_last_buffer_done(m2m_ctx, vbuf);
        } else {
                v4l2_m2m_buf_queue(m2m_ctx, vbuf);
@@ -1462,8 +1466,13 @@ static int streamoff_output(struct vb2_queue *q)
        inst->codec_info->dec_info.stream_rd_ptr = new_rd_ptr;
        inst->codec_info->dec_info.stream_wr_ptr = new_rd_ptr;
 
-       if (v4l2_m2m_has_stopped(m2m_ctx))
+       if (v4l2_m2m_has_stopped(m2m_ctx)) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&inst->state_spinlock, flags);
                send_eos_event(inst);
+               spin_unlock_irqrestore(&inst->state_spinlock, flags);
+       }
 
        /* streamoff on output cancels any draining operation */
        inst->eos = false;
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to