On Wed May 13 08:42:44 2026 +0300, Valery Borovsky wrote:
> pwc_isoc_init() submits its isochronous URBs with
> usb_submit_urb(.., GFP_KERNEL) in a loop. After the first URB is
> submitted, its completion handler pwc_isoc_handler() can run on another
> CPU before the loop finishes:
>
> start_streaming()
> pwc_isoc_init()
> usb_submit_urb(urbs[0], GFP_KERNEL)
> pwc_isoc_handler(urbs[0])
> pdev->fill_buf =
> pwc_get_next_fill_buf(pdev)
> usb_submit_urb(urbs[i>0], ..) -> fails
> pwc_isoc_cleanup(pdev) /* kills URBs */
> return ret;
> pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED)
>
> pwc_get_next_fill_buf() detaches a buffer from pdev->queued_bufs and
> stores it in pdev->fill_buf. The error path in start_streaming() only
> drains pdev->queued_bufs, so the buffer parked in pdev->fill_buf is
> leaked. vb2_start_streaming() then triggers
> WARN_ON(owned_by_drv_count).
>
> stop_streaming() already handles this since commit 80b0963e1698
> ("[media] pwc: fix WARN_ON"), which added the fill_buf drain in the
> teardown path but not in the start_streaming() error path. Mirror that
> handling on failure so start_streaming() returns with no buffer owned
> by the driver.
>
> Issue identified by automated review of the INV-003 series at
> https://sashiko.dev/
>
> Fixes: 885fe18f5542 ("[media] pwc: Replace private buffer management code
> with videobuf2")
> Cc: [email protected]
> Signed-off-by: Valery Borovsky <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>
Patch committed.
Thanks,
Hans Verkuil
drivers/media/usb/pwc/pwc-if.c | 5 +++++
1 file changed, 5 insertions(+)
---
diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c
index 59b99ac8fcb6..e2884b04d952 100644
--- a/drivers/media/usb/pwc/pwc-if.c
+++ b/drivers/media/usb/pwc/pwc-if.c
@@ -730,6 +730,11 @@ static int start_streaming(struct vb2_queue *vq, unsigned
int count)
pwc_camera_power(pdev, 0);
/* And cleanup any queued bufs!! */
pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED);
+ if (pdev->fill_buf) {
+ vb2_buffer_done(&pdev->fill_buf->vb.vb2_buf,
+ VB2_BUF_STATE_QUEUED);
+ pdev->fill_buf = NULL;
+ }
}
mutex_unlock(&pdev->v4l2_lock);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]