On Mon May 11 20:12:08 2026 +0300, Valery Borovsky wrote:
> The vb2 framework hands buffers to the driver via buf_queue() before
> calling start_streaming().  If start_streaming() returns an error
> without first returning those buffers via vb2_buffer_done(),
> vb2_start_streaming() fires WARN_ON(owned_by_drv_count) and the queued
> buffers leak.
> 
> pwc's start_streaming() had two early returns that hit this trap:
> -ENODEV when the USB device was already disconnected, and -ERESTARTSYS
> when mutex_lock_interruptible() was interrupted by a signal.  Call the
> existing pwc_cleanup_queued_bufs() helper with VB2_BUF_STATE_QUEUED
> before returning (matching the state already used by the
> pwc_isoc_init() error path in the same function).
> 
> This mirrors the uvcvideo fix in commit 4cf3b6fd54eb ("media: uvcvideo:
> Return queued buffers on start_streaming() failure").
> 
> Fixes: ceede9fa8939 ("[media] pwc: Fix locking")
> 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 | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

---

diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c
index c416e2fc5754..59b99ac8fcb6 100644
--- a/drivers/media/usb/pwc/pwc-if.c
+++ b/drivers/media/usb/pwc/pwc-if.c
@@ -710,11 +710,15 @@ static int start_streaming(struct vb2_queue *vq, unsigned 
int count)
        struct pwc_device *pdev = vb2_get_drv_priv(vq);
        int r;
 
-       if (!pdev->udev)
+       if (!pdev->udev) {
+               pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED);
                return -ENODEV;
+       }
 
-       if (mutex_lock_interruptible(&pdev->v4l2_lock))
+       if (mutex_lock_interruptible(&pdev->v4l2_lock)) {
+               pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED);
                return -ERESTARTSYS;
+       }
        /* Turn on camera and set LEDS on */
        pwc_camera_power(pdev, 1);
        pwc_set_leds(pdev, leds[0], leds[1]);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to