• Alan Stern's avatar
    USB: replace flush_workqueue with cancel_sync_work · d5d4db70
    Alan Stern authored
    This patch (as912) replaces a couple of calls to flush_workqueue()
    with cancel_sync_work() and cancel_rearming_delayed_work().  Using a
    more directed approach allows us to avoid some nasty deadlocks.  The
    prime example occurs when a first-level device (the parent is a root
    hub) is removed while at the same time the root hub gets a remote
    wakeup request.  khubd would try to flush the autosuspend workqueue
    while holding the root-hub's lock, and the remote-wakeup workqueue
    routine would be waiting to lock the root hub.
    
    The patch also reorganizes the power management portion of
    usb_disconnect(), separating it out into its own routine.  The
    autosuspend workqueue entry is cancelled immediately instead of
    waiting for the device's release routine.  In addition,
    synchronization with the autosuspend thread is carried out even for
    root hubs (an oversight in the original code).
    Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Cc: Greg KH <gregkh@suse.de>
    Cc: Mark Lord <lkml@rtr.ca>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    d5d4db70
hub.c 83.9 KB