[PATCH] media: uvcvideo: Explicitly return the metadata buffers

Ricardo Ribalda posted 1 patch 2 weeks, 5 days ago
drivers/media/usb/uvc/uvc_queue.c | 10 ++++++++++
1 file changed, 10 insertions(+)
[PATCH] media: uvcvideo: Explicitly return the metadata buffers
Posted by Ricardo Ribalda 2 weeks, 5 days ago
If we keep the metadata node open, while we close the video node, there
is some risk that after reopening the video node the next metadata frame
will contain data from two different runs.

Please note that although the URB callback will usually flush all the
queues when the urbs are poisoned during uvc_video_stop_transfer(),
there might be some situations where this is not triggered.

Fixes: 088ead255245 ("media: uvcvideo: Add a metadata device node")
Cc: stable@vger.kernel.org
Reported-by: Hans de Goede <hansg@kernel.org>
Closes: https://lore.kernel.org/linux-media/CANiDSCuO5aEApqHxy6uqZheza7hgdOkH38sY5YhO_xAxSYAJbg@mail.gmail.com/T/#u
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
 drivers/media/usb/uvc/uvc_queue.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
index 3c002c8f442f..57397fd793c8 100644
--- a/drivers/media/usb/uvc/uvc_queue.c
+++ b/drivers/media/usb/uvc/uvc_queue.c
@@ -196,6 +196,7 @@ static void uvc_stop_streaming_video(struct vb2_queue *vq)
 {
 	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
 	struct uvc_streaming *stream = queue->stream;
+	struct uvc_video_queue *meta_queue = &stream->meta.queue;
 
 	lockdep_assert_irqs_enabled();
 
@@ -204,6 +205,15 @@ static void uvc_stop_streaming_video(struct vb2_queue *vq)
 	uvc_pm_put(stream->dev);
 
 	uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
+
+	/*
+	 * The video node acts as the stream manager, if it stops streaming,
+	 * the metadata node also stops producing frames.
+	 * To avoid metadata buffers partially filled by two runs, we need to
+	 * also flush the metadata queue.
+	 */
+	if (video_is_registered(&meta_queue->vdev))
+		uvc_queue_return_buffers(meta_queue, UVC_BUF_STATE_ERROR);
 }
 
 static void uvc_stop_streaming_meta(struct vb2_queue *vq)

---
base-commit: 8dac27bfa2f994ecb11f01a63641527d17d48fc1
change-id: 20260708-uvc-flush-meta-a5bf63064061

Best regards,
-- 
Ricardo Ribalda <ribalda@chromium.org>