mirror of
https://github.com/torvalds/linux.git
synced 2024-12-21 10:31:54 +00:00
[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 <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
aa6d5f2953
commit
ee71e7b3ae
@ -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:
|
|||||||
|
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user