• Ricardo Ribalda's avatar
    media: uvcvideo: Fix race condition with usb_kill_urb · 619d9b71
    Ricardo Ribalda authored
    usb_kill_urb warranties that all the handlers are finished when it
    returns, but does not protect against threads that might be handling
    asynchronously the urb.
    
    For UVC, the function uvc_ctrl_status_event_async() takes care of
    control changes asynchronously.
    
    If the code is executed in the following order:
    
    CPU 0					CPU 1
    ===== 					=====
    uvc_status_complete()
    					uvc_status_stop()
    uvc_ctrl_status_event_work()
    					uvc_status_start() -> FAIL
    
    Then uvc_status_start will keep failing and this error will be shown:
    
    <4>[    5.540139] URB 0000000000000000 submitted while active
    drivers/usb/core/urb.c:378 usb_submit_urb+0x4c3/0x528
    
    Let's improve the current situation, by not re-submiting the urb if
    we are stopping the status event. Also process the queued work
    (if any) during stop.
    
    CPU 0					CPU 1
    ===== 					=====
    uvc_status_complete()
    					uvc_status_stop()
    					uvc_status_start()
    uvc_ctrl_status_event_work() -> FAIL
    
    Hopefully, with the usb layer protection this should be enough to cover
    all the cases.
    
    Cc: stable@vger.kernel.org
    Fixes: e5225c82 ("media: uvcvideo: Send a control event when a Control Change interrupt arrives")
    Reviewed-by: default avatarYunke Cao <yunkec@chromium.org>
    Signed-off-by: default avatarRicardo Ribalda <ribalda@chromium.org>
    Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
    Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
    619d9b71
uvcvideo.h 21.6 KB