mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
media: uvcvideo: Fix driver reference counting
commitf9ffcb0a21upstream kref_init initializes the reference count to 1, not 0. This additional reference is never released since the conversion to reference counters. As a result, uvc_delete is not called anymore when UVC cameras are disconnected. Fix this by adding an additional kref_put in uvc_disconnect and in the probe error path. This also allows to remove the temporary additional reference in uvc_unregister_video. Fixes:9d15cd958c("media: uvcvideo: Convert from using an atomic variable to a reference count") Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> Signed-off-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
cdb44bdafc
commit
e75194d294
@@ -1865,13 +1865,6 @@ static void uvc_unregister_video(struct uvc_device *dev)
|
||||
{
|
||||
struct uvc_streaming *stream;
|
||||
|
||||
/* Unregistering all video devices might result in uvc_delete() being
|
||||
* called from inside the loop if there's no open file handle. To avoid
|
||||
* that, increment the refcount before iterating over the streams and
|
||||
* decrement it when done.
|
||||
*/
|
||||
kref_get(&dev->ref);
|
||||
|
||||
list_for_each_entry(stream, &dev->streams, list) {
|
||||
if (!video_is_registered(&stream->vdev))
|
||||
continue;
|
||||
@@ -1880,8 +1873,6 @@ static void uvc_unregister_video(struct uvc_device *dev)
|
||||
|
||||
uvc_debugfs_cleanup_stream(stream);
|
||||
}
|
||||
|
||||
kref_put(&dev->ref, uvc_delete);
|
||||
}
|
||||
|
||||
static int uvc_register_video(struct uvc_device *dev,
|
||||
@@ -2129,6 +2120,7 @@ static int uvc_probe(struct usb_interface *intf,
|
||||
|
||||
error:
|
||||
uvc_unregister_video(dev);
|
||||
kref_put(&dev->ref, uvc_delete);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -2146,6 +2138,7 @@ static void uvc_disconnect(struct usb_interface *intf)
|
||||
return;
|
||||
|
||||
uvc_unregister_video(dev);
|
||||
kref_put(&dev->ref, uvc_delete);
|
||||
}
|
||||
|
||||
static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
|
||||
Reference in New Issue
Block a user