Commit ee71e7b3 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[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: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent aa6d5f29
...@@ -182,11 +182,11 @@ static int __devinit drv_probe(struct pci_dev *pdev, ...@@ -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 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 safe to unregister v4l2_device for hotpluggable devices. For this purpose
support. The refcount is increased whenever video_register_device is called and v4l2_device has refcounting support. The refcount is increased whenever
it is decreased whenever that device node is released. When the refcount reaches video_register_device is called and it is decreased whenever that device node
zero, then the v4l2_device release() callback is called. You can do your final is released. When the refcount reaches zero, then the v4l2_device release()
cleanup there. callback is called. You can do your final cleanup there.
If other device nodes (e.g. ALSA) are created, then you can increase and If other device nodes (e.g. ALSA) are created, then you can increase and
decrease the refcount manually as well by calling: decrease the refcount manually as well by calling:
...@@ -197,6 +197,10 @@ or: ...@@ -197,6 +197,10 @@ or:
int v4l2_device_put(struct v4l2_device *v4l2_dev); 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 struct v4l2_subdev
------------------ ------------------
......
...@@ -481,7 +481,6 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf) ...@@ -481,7 +481,6 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
{ {
struct dsbr100_device *radio = usb_get_intfdata(intf); struct dsbr100_device *radio = usb_get_intfdata(intf);
v4l2_device_get(&radio->v4l2_dev);
mutex_lock(&radio->v4l2_lock); mutex_lock(&radio->v4l2_lock);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
video_unregister_device(&radio->videodev); video_unregister_device(&radio->videodev);
......
...@@ -148,7 +148,6 @@ static void usb_keene_disconnect(struct usb_interface *intf) ...@@ -148,7 +148,6 @@ static void usb_keene_disconnect(struct usb_interface *intf)
{ {
struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf)); struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf));
v4l2_device_get(&radio->v4l2_dev);
mutex_lock(&radio->lock); mutex_lock(&radio->lock);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
video_unregister_device(&radio->vdev); video_unregister_device(&radio->vdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment