• Daniel Axtens's avatar
    media: uvcvideo: Refactor teardown of uvc on USB disconnect · 13e97606
    Daniel Axtens authored
    [ Upstream commit 10e1fdb9 ]
    
    Currently, disconnecting a USB webcam while it is in use prints out a
    number of warnings, such as:
    
    WARNING: CPU: 2 PID: 3118 at /build/linux-ezBi1T/linux-4.8.0/fs/sysfs/group.c:237 sysfs_remove_group+0x8b/0x90
    sysfs group ffffffffa7cd0780 not found for kobject 'event13'
    
    This has been noticed before. [0]
    
    This is because of the order in which things are torn down.
    
    If there are no streams active during a USB disconnect:
    
     - uvc_disconnect() is invoked via device_del() through the bus
       notifier mechanism.
    
     - this calls uvc_unregister_video().
    
     - uvc_unregister_video() unregisters the video device for each
       stream,
    
     - because there are no streams open, it calls uvc_delete()
    
     - uvc_delete() calls uvc_status_cleanup(), which cleans up the status
       input device.
    
     - uvc_delete() calls media_device_unregister(), which cleans up the
       media device
    
     - uvc_delete(), uvc_unregister_video() and uvc_disconnect() all
       return, and we end up back in device_del().
    
     - device_del() then cleans up the sysfs folder for the camera with
       dpm_sysfs_remove(). Because uvc_status_cleanup() and
       media_device_unregister() have already been called, this all works
       nicely.
    
    If, on the other hand, there *are* streams active during a USB disconnect:
    
     - uvc_disconnect() is invoked
    
     - this calls uvc_unregister_video()
    
     - uvc_unregister_video() unregisters the video device for each
       stream,
    
     - uvc_unregister_video() and uvc_disconnect() return, and we end up
       back in device_del().
    
     - device_del() then cleans up the sysfs folder for the camera with
       dpm_sysfs_remove(). Because the status input device and the media
       device are children of the USB device, this also deletes their
       sysfs folders.
    
     - Sometime later, the final stream is closed, invoking uvc_release().
    
     - uvc_release() calls uvc_delete()
    
     - uvc_delete() calls uvc_status_cleanup(), which cleans up the status
       input device. Because the sysfs directory has already been removed,
       this causes a WARNing.
    
     - uvc_delete() calls media_device_unregister(), which cleans up the
       media device. Because the sysfs directory has already been removed,
       this causes another WARNing.
    
    To fix this, we need to make sure the devices are always unregistered
    before the end of uvc_disconnect(). To this, move the unregistration
    into the disconnect path:
    
     - split uvc_status_cleanup() into two parts, one on disconnect that
       unregisters and one on delete that frees.
    
     - move v4l2_device_unregister() and media_device_unregister() into
       the disconnect path.
    
    [0]: https://lkml.org/lkml/2016/12/8/657
    
    [Renamed uvc_input_cleanup() to uvc_input_unregister()]
    Signed-off-by: default avatarDaniel Axtens <dja@axtens.net>
    Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Laurent Pinchart's avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
    Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
    Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
    13e97606
Name
Last commit
Last update
..
airspy Loading commit data...
as102 Loading commit data...
au0828 Loading commit data...
b2c2 Loading commit data...
cpia2 Loading commit data...
cx231xx Loading commit data...
dvb-usb Loading commit data...
dvb-usb-v2 Loading commit data...
em28xx Loading commit data...
go7007 Loading commit data...
gspca Loading commit data...
hackrf Loading commit data...
hdpvr Loading commit data...
msi2500 Loading commit data...
pulse8-cec Loading commit data...
pvrusb2 Loading commit data...
pwc Loading commit data...
rainshadow-cec Loading commit data...
s2255 Loading commit data...
siano Loading commit data...
stk1160 Loading commit data...
stkwebcam Loading commit data...
tm6000 Loading commit data...
ttusb-budget Loading commit data...
ttusb-dec Loading commit data...
usbtv Loading commit data...
usbvision Loading commit data...
uvc Loading commit data...
zr364xx Loading commit data...
Kconfig Loading commit data...
Makefile Loading commit data...