• Alan Stern's avatar
    USB: xhci: fix lock-inversion problem · 63aea0db
    Alan Stern authored
    With threaded interrupts, bottom-half handlers are called with
    interrupts enabled.  Therefore they can't safely use spin_lock(); they
    have to use spin_lock_irqsave().  Lockdep warns about a violation
    occurring in xhci_irq():
    
    =========================================================
    [ INFO: possible irq lock inversion dependency detected ]
    4.11.0-rc8-dbg+ #1 Not tainted
    ---------------------------------------------------------
    swapper/7/0 just changed the state of lock:
     (&(&ehci->lock)->rlock){-.-...}, at: [<ffffffffa0130a69>]
    ehci_hrtimer_func+0x29/0xc0 [ehci_hcd]
    but this lock took another, HARDIRQ-unsafe lock in the past:
     (hcd_urb_list_lock){+.....}
    
    and interrupts could create inverse lock ordering between them.
    
    other info that might help us debug this:
     Possible interrupt unsafe locking scenario:
    
           CPU0                    CPU1
           ----                    ----
      lock(hcd_urb_list_lock);
                                   local_irq_disable();
                                   lock(&(&ehci->lock)->rlock);
                                   lock(hcd_urb_list_lock);
      <Interrupt>
        lock(&(&ehci->lock)->rlock);
     *** DEADLOCK ***
    
    no locks held by swapper/7/0.
    the shortest dependencies between 2nd lock and 1st lock:
     -> (hcd_urb_list_lock){+.....} ops: 252 {
        HARDIRQ-ON-W at:
                          __lock_acquire+0x602/0x1280
                          lock_acquire+0xd5/0x1c0
                          _raw_spin_lock+0x2f/0x40
                          usb_hcd_unlink_urb_from_ep+0x1b/0x60 [usbcore]
                          xhci_giveback_urb_in_irq.isra.45+0x70/0x1b0 [xhci_hcd]
                          finish_td.constprop.60+0x1d8/0x2e0 [xhci_hcd]
                          xhci_irq+0xdd6/0x1fa0 [xhci_hcd]
                          usb_hcd_irq+0x26/0x40 [usbcore]
                          irq_forced_thread_fn+0x2f/0x70
                          irq_thread+0x149/0x1d0
                          kthread+0x113/0x150
                          ret_from_fork+0x2e/0x40
    
    This patch fixes the problem.
    Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
    Reported-and-tested-by: default avatarBart Van Assche <bart.vanassche@sandisk.com>
    CC: <stable@vger.kernel.org>
    Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    63aea0db
xhci-ring.c 122 KB