Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

media: chips-media: wave5: add missing spinlock protection for send_eos_event()

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 <n7l8m4@u.northwestern.edu>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Fixes: 9707a6254a8a6b ("media: chips-media: wave5: Add the v4l2 layer")
Cc: stable@vger.kernel.org
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>

authored by

Ziyi Guo and committed by
Hans Verkuil
f4805043 95bd174a

+10 -1
+10 -1
drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
··· 1303 1303 1304 1304 if (vb2_is_streaming(vb->vb2_queue) && v4l2_m2m_dst_buf_is_last(m2m_ctx)) { 1305 1305 unsigned int i; 1306 + unsigned long flags; 1306 1307 1307 1308 for (i = 0; i < vb->num_planes; i++) 1308 1309 vb2_set_plane_payload(vb, i, 0); 1309 1310 1310 1311 vbuf->field = V4L2_FIELD_NONE; 1311 1312 1313 + spin_lock_irqsave(&inst->state_spinlock, flags); 1312 1314 send_eos_event(inst); 1315 + spin_unlock_irqrestore(&inst->state_spinlock, flags); 1316 + 1313 1317 v4l2_m2m_last_buffer_done(m2m_ctx, vbuf); 1314 1318 } else { 1315 1319 v4l2_m2m_buf_queue(m2m_ctx, vbuf); ··· 1466 1462 inst->codec_info->dec_info.stream_rd_ptr = new_rd_ptr; 1467 1463 inst->codec_info->dec_info.stream_wr_ptr = new_rd_ptr; 1468 1464 1469 - if (v4l2_m2m_has_stopped(m2m_ctx)) 1465 + if (v4l2_m2m_has_stopped(m2m_ctx)) { 1466 + unsigned long flags; 1467 + 1468 + spin_lock_irqsave(&inst->state_spinlock, flags); 1470 1469 send_eos_event(inst); 1470 + spin_unlock_irqrestore(&inst->state_spinlock, flags); 1471 + } 1471 1472 1472 1473 /* streamoff on output cancels any draining operation */ 1473 1474 inst->eos = false;