Skip to content

Commit f2f9fca

Browse files
Vastargazinggregkh
authored andcommitted
media: pwc: Return queued buffers on start_streaming() failure
commit 975b2ee upstream. 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 4cf3b6f ("media: uvcvideo: Return queued buffers on start_streaming() failure"). Fixes: ceede9f ("[media] pwc: Fix locking") Cc: stable@vger.kernel.org Signed-off-by: Valery Borovsky <vebohr@gmail.com> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent a56e764 commit f2f9fca

1 file changed

Lines changed: 6 additions & 2 deletions

File tree

drivers/media/usb/pwc/pwc-if.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -711,11 +711,15 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
711711
struct pwc_device *pdev = vb2_get_drv_priv(vq);
712712
int r;
713713

714-
if (!pdev->udev)
714+
if (!pdev->udev) {
715+
pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED);
715716
return -ENODEV;
717+
}
716718

717-
if (mutex_lock_interruptible(&pdev->v4l2_lock))
719+
if (mutex_lock_interruptible(&pdev->v4l2_lock)) {
720+
pwc_cleanup_queued_bufs(pdev, VB2_BUF_STATE_QUEUED);
718721
return -ERESTARTSYS;
722+
}
719723
/* Turn on camera and set LEDS on */
720724
pwc_camera_power(pdev, 1);
721725
pwc_set_leds(pdev, leds[0], leds[1]);

0 commit comments

Comments
 (0)