• Roger Quadros's avatar
    usb: xhci: fix xhci locking up during hcd remove · ad6b1d91
    Roger Quadros authored
    The problem seems to be that if a new device is detected
    while we have already removed the shared HCD, then many of the
    xhci operations (e.g.  xhci_alloc_dev(), xhci_setup_device())
    hang as command never completes.
    
    I don't think XHCI can operate without the shared HCD as we've
    already called xhci_halt() in xhci_only_stop_hcd() when shared HCD
    goes away. We need to prevent new commands from being queued
    not only when HCD is dying but also when HCD is halted.
    
    The following lockup was detected while testing the otg state
    machine.
    
    [  178.199951] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
    [  178.205799] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 1
    [  178.214458] xhci-hcd xhci-hcd.0.auto: hcc params 0x0220f04c hci version 0x100 quirks 0x00010010
    [  178.223619] xhci-hcd xhci-hcd.0.auto: irq 400, io mem 0x48890000
    [  178.230677] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
    [  178.237796] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
    [  178.245358] usb usb1: Product: xHCI Host Controller
    [  178.250483] usb usb1: Manufacturer: Linux 4.0.0-rc1-00024-g6111320 xhci-hcd
    [  178.257783] usb usb1: SerialNumber: xhci-hcd.0.auto
    [  178.267014] hub 1-0:1.0: USB hub found
    [  178.272108] hub 1-0:1.0: 1 port detected
    [  178.278371] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
    [  178.284171] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 2
    [  178.294038] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003
    [  178.301183] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
    [  178.308776] usb usb2: Product: xHCI Host Controller
    [  178.313902] usb usb2: Manufacturer: Linux 4.0.0-rc1-00024-g6111320 xhci-hcd
    [  178.321222] usb usb2: SerialNumber: xhci-hcd.0.auto
    [  178.329061] hub 2-0:1.0: USB hub found
    [  178.333126] hub 2-0:1.0: 1 port detected
    [  178.567585] dwc3 48890000.usb: usb_otg_start_host 0
    [  178.572707] xhci-hcd xhci-hcd.0.auto: remove, state 4
    [  178.578064] usb usb2: USB disconnect, device number 1
    [  178.586565] xhci-hcd xhci-hcd.0.auto: USB bus 2 deregistered
    [  178.592585] xhci-hcd xhci-hcd.0.auto: remove, state 1
    [  178.597924] usb usb1: USB disconnect, device number 1
    [  178.603248] usb 1-1: new high-speed USB device number 2 using xhci-hcd
    [  190.597337] INFO: task kworker/u4:0:6 blocked for more than 10 seconds.
    [  190.604273]       Not tainted 4.0.0-rc1-00024-g6111320 #1058
    [  190.610228] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
    [  190.618443] kworker/u4:0    D c05c0ac0     0     6      2 0x00000000
    [  190.625120] Workqueue: usb_otg usb_otg_work
    [  190.629533] [<c05c0ac0>] (__schedule) from [<c05c10ac>] (schedule+0x34/0x98)
    [  190.636915] [<c05c10ac>] (schedule) from [<c05c1318>] (schedule_preempt_disabled+0xc/0x10)
    [  190.645591] [<c05c1318>] (schedule_preempt_disabled) from [<c05c23d0>] (mutex_lock_nested+0x1ac/0x3fc)
    [  190.655353] [<c05c23d0>] (mutex_lock_nested) from [<c046cf8c>] (usb_disconnect+0x3c/0x208)
    [  190.664043] [<c046cf8c>] (usb_disconnect) from [<c0470cf0>] (_usb_remove_hcd+0x98/0x1d8)
    [  190.672535] [<c0470cf0>] (_usb_remove_hcd) from [<c0485da8>] (usb_otg_start_host+0x50/0xf4)
    [  190.681299] [<c0485da8>] (usb_otg_start_host) from [<c04849a4>] (otg_set_protocol+0x5c/0xd0)
    [  190.690153] [<c04849a4>] (otg_set_protocol) from [<c0484b88>] (otg_set_state+0x170/0xbfc)
    [  190.698735] [<c0484b88>] (otg_set_state) from [<c0485740>] (otg_statemachine+0x12c/0x470)
    [  190.707326] [<c0485740>] (otg_statemachine) from [<c0053c84>] (process_one_work+0x1b4/0x4a0)
    [  190.716162] [<c0053c84>] (process_one_work) from [<c00540f8>] (worker_thread+0x154/0x44c)
    [  190.724742] [<c00540f8>] (worker_thread) from [<c0058f88>] (kthread+0xd4/0xf0)
    [  190.732328] [<c0058f88>] (kthread) from [<c000e810>] (ret_from_fork+0x14/0x24)
    [  190.739898] 5 locks held by kworker/u4:0/6:
    [  190.744274]  #0:  ("%s""usb_otg"){.+.+.+}, at: [<c0053bf4>] process_one_work+0x124/0x4a0
    [  190.752799]  #1:  ((&otgd->work)){+.+.+.}, at: [<c0053bf4>] process_one_work+0x124/0x4a0
    [  190.761326]  #2:  (&otgd->fsm.lock){+.+.+.}, at: [<c048562c>] otg_statemachine+0x18/0x470
    [  190.769934]  #3:  (usb_bus_list_lock){+.+.+.}, at: [<c0470ce8>] _usb_remove_hcd+0x90/0x1d8
    [  190.778635]  #4:  (&dev->mutex){......}, at: [<c046cf8c>] usb_disconnect+0x3c/0x208
    [  190.786700] INFO: task kworker/1:0:14 blocked for more than 10 seconds.
    [  190.793633]       Not tainted 4.0.0-rc1-00024-g6111320 #1058
    [  190.799567] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
    [  190.807783] kworker/1:0     D c05c0ac0     0    14      2 0x00000000
    [  190.814457] Workqueue: usb_hub_wq hub_event
    [  190.818866] [<c05c0ac0>] (__schedule) from [<c05c10ac>] (schedule+0x34/0x98)
    [  190.826252] [<c05c10ac>] (schedule) from [<c05c4e40>] (schedule_timeout+0x13c/0x1ec)
    [  190.834377] [<c05c4e40>] (schedule_timeout) from [<c05c19f0>] (wait_for_common+0xbc/0x150)
    [  190.843062] [<c05c19f0>] (wait_for_common) from [<bf068a3c>] (xhci_setup_device+0x164/0x5cc [xhci_hcd])
    [  190.852986] [<bf068a3c>] (xhci_setup_device [xhci_hcd]) from [<c046b7f4>] (hub_port_init+0x3f4/0xb10)
    [  190.862667] [<c046b7f4>] (hub_port_init) from [<c046eb64>] (hub_event+0x704/0x1018)
    [  190.870704] [<c046eb64>] (hub_event) from [<c0053c84>] (process_one_work+0x1b4/0x4a0)
    [  190.878919] [<c0053c84>] (process_one_work) from [<c00540f8>] (worker_thread+0x154/0x44c)
    [  190.887503] [<c00540f8>] (worker_thread) from [<c0058f88>] (kthread+0xd4/0xf0)
    [  190.895076] [<c0058f88>] (kthread) from [<c000e810>] (ret_from_fork+0x14/0x24)
    [  190.902650] 5 locks held by kworker/1:0/14:
    [  190.907023]  #0:  ("usb_hub_wq"){.+.+.+}, at: [<c0053bf4>] process_one_work+0x124/0x4a0
    [  190.915454]  #1:  ((&hub->events)){+.+.+.}, at: [<c0053bf4>] process_one_work+0x124/0x4a0
    [  190.924070]  #2:  (&dev->mutex){......}, at: [<c046e490>] hub_event+0x30/0x1018
    [  190.931768]  #3:  (&port_dev->status_lock){+.+.+.}, at: [<c046eb50>] hub_event+0x6f0/0x1018
    [  190.940558]  #4:  (&bus->usb_address0_mutex){+.+.+.}, at: [<c046b458>] hub_port_init+0x58/0xb10
    Signed-off-by: default avatarRoger Quadros <rogerq@ti.com>
    Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    ad6b1d91
xhci-ring.c 121 KB