From ee71e7b3ae1780e4475aa5dd980dd99c0309079b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 19 Apr 2012 12:27:56 -0300 Subject: [media] V4L: fix incorrect refcounting Both radio-keene and dsbr100 did one v4l2_device_get too many. Thus the refcount never became 0 and that causes a memory leak. Also updated the V4L2 framework documentation accordingly. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/v4l2-framework.txt | 14 +++++++++----- drivers/media/radio/dsbr100.c | 1 - drivers/media/radio/radio-keene.c | 1 - 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index 659b2ba12a4f..e3dfc268d9c1 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt @@ -182,11 +182,11 @@ static int __devinit drv_probe(struct pci_dev *pdev, } If you have multiple device nodes then it can be difficult to know when it is -safe to unregister v4l2_device. For this purpose v4l2_device has refcounting -support. The refcount is increased whenever video_register_device is called and -it is decreased whenever that device node is released. When the refcount reaches -zero, then the v4l2_device release() callback is called. You can do your final -cleanup there. +safe to unregister v4l2_device for hotpluggable devices. For this purpose +v4l2_device has refcounting support. The refcount is increased whenever +video_register_device is called and it is decreased whenever that device node +is released. When the refcount reaches zero, then the v4l2_device release() +callback is called. You can do your final cleanup there. If other device nodes (e.g. ALSA) are created, then you can increase and decrease the refcount manually as well by calling: @@ -197,6 +197,10 @@ or: int v4l2_device_put(struct v4l2_device *v4l2_dev); +Since the initial refcount is 1 you also need to call v4l2_device_put in the +disconnect() callback (for USB devices) or in the remove() callback (for e.g. +PCI devices), otherwise the refcount will never reach 0. + struct v4l2_subdev ------------------ diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index f36905b63645..bf813a63ab2a 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -481,7 +481,6 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf) { struct dsbr100_device *radio = usb_get_intfdata(intf); - v4l2_device_get(&radio->v4l2_dev); mutex_lock(&radio->v4l2_lock); usb_set_intfdata(intf, NULL); video_unregister_device(&radio->videodev); diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c index 26a2b7a0304e..5f33047d0d43 100644 --- a/drivers/media/radio/radio-keene.c +++ b/drivers/media/radio/radio-keene.c @@ -148,7 +148,6 @@ static void usb_keene_disconnect(struct usb_interface *intf) { struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf)); - v4l2_device_get(&radio->v4l2_dev); mutex_lock(&radio->lock); usb_set_intfdata(intf, NULL); video_unregister_device(&radio->vdev); -- cgit v1.2.3