• Hans de Goede's avatar
    usb-anchor: Delay usb_wait_anchor_empty_timeout wake up till completion is done · 6ec4147e
    Hans de Goede authored
    usb_wait_anchor_empty_timeout() should wait till the completion handler
    has run. Both the zd1211rw driver and the uas driver (in its task mgmt) depend
    on the completion handler having completed when usb_wait_anchor_empty_timeout()
    returns, as they read state set by the completion handler after an
    usb_wait_anchor_empty_timeout() call.
    
    But __usb_hcd_giveback_urb() calls usb_unanchor_urb before calling the
    completion handler. This is necessary as the completion handler may
    re-submit and re-anchor the urb. But this introduces a race where the state
    these drivers want to read has not been set yet by the completion handler
    (this race is easily triggered with the uas task mgmt code).
    
    I've considered adding an anchor_count to struct urb, which would be
    incremented on anchor and decremented on unanchor, and then only actually
    do the anchor / unanchor on 0 -> 1 and 1 -> 0 transtions, combined with
    moving the unanchor call in hcd_giveback_urb to after calling the completion
    handler. But this will only work if urb's are only re-anchored to the same
    anchor as they were anchored to before the completion handler ran.
    
    And at least one driver re-anchors to another anchor from the completion
    handler (rtlwifi).
    
    So I have come up with this patch instead, which adds the ability to
    suspend wakeups of usb_wait_anchor_empty_timeout() waiters to the usb_anchor
    functionality, and uses this in __usb_hcd_giveback_urb() to delay wake-ups
    until the completion handler has run.
    Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
    Acked-by: default avatarOliver Neukum <oliver@neukum.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    6ec4147e
hcd.c 82.9 KB