lkml.org 
[lkml]   [2018]   [Nov]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 4.14 110/143] media: uvcvideo: Fix driver reference counting
Date
4.14-stable review patch.  If anyone has any objections, please let me know.

------------------

commit f9ffcb0a21e1fa8e64d09ed613d884e054ae8191 upstream

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: 9d15cd958c17 ("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>
---
drivers/media/usb/uvc/uvc_driver.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 6d22b22cb35b..064d88299adc 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -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)
--
2.17.1


\
 
 \ /
  Last update: 2018-11-02 20:26    [W:0.993 / U:0.256 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site