mirror_ubuntu-kernels/drivers/usb/core
Guenter Roeck 245b2eecee usb: hub: Fix error loop seen after hub communication errors
While stress testing a usb controller using a bind/unbind looop, the
following error loop was observed.

usb 7-1.2: new low-speed USB device number 3 using xhci-hcd
usb 7-1.2: hub failed to enable device, error -108
usb 7-1-port2: cannot disable (err = -22)
usb 7-1-port2: couldn't allocate usb_device
usb 7-1-port2: cannot disable (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: activate --> -22
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
hub 7-1:1.0: hub_ext_port_status failed (err = -22)
** 57 printk messages dropped ** hub 7-1:1.0: activate --> -22
** 82 printk messages dropped ** hub 7-1:1.0: hub_ext_port_status failed (err = -22)

This continues forever. After adding tracebacks into the code,
the call sequence leading to this is found to be as follows.

[<ffffffc0007fc8e0>] hub_activate+0x368/0x7b8
[<ffffffc0007fceb4>] hub_resume+0x2c/0x3c
[<ffffffc00080b3b8>] usb_resume_interface.isra.6+0x128/0x158
[<ffffffc00080b5d0>] usb_suspend_both+0x1e8/0x288
[<ffffffc00080c9c4>] usb_runtime_suspend+0x3c/0x98
[<ffffffc0007820a0>] __rpm_callback+0x48/0x7c
[<ffffffc00078217c>] rpm_callback+0xa8/0xd4
[<ffffffc000786234>] rpm_suspend+0x84/0x758
[<ffffffc000786ca4>] rpm_idle+0x2c8/0x498
[<ffffffc000786ed4>] __pm_runtime_idle+0x60/0xac
[<ffffffc00080eba8>] usb_autopm_put_interface+0x6c/0x7c
[<ffffffc000803798>] hub_event+0x10ac/0x12ac
[<ffffffc000249bb8>] process_one_work+0x390/0x6b8
[<ffffffc00024abcc>] worker_thread+0x480/0x610
[<ffffffc000251a80>] kthread+0x164/0x178
[<ffffffc0002045d0>] ret_from_fork+0x10/0x40

kick_hub_wq() is called from hub_activate() even after failures to
communicate with the hub. This results in an endless sequence of
hub event -> hub activate -> wq trigger -> hub event -> ...

Provide two solutions for the problem.

- Only trigger the hub event queue if communication with the hub
  is successful.
- After a suspend failure, only resume already suspended interfaces
  if the communication with the device is still possible.

Each of the changes fixes the observed problem. Use both to improve
robustness.

Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-03-23 08:13:22 +01:00
..
buffer.c USB: core: add missing license information to some files 2016-10-29 12:51:56 -04:00
config.c USB: fix problems with duplicate endpoint addresses 2017-01-05 19:38:40 +01:00
devices.c usb: core: devices: remove unnecessary & operation 2016-11-03 10:38:23 +02:00
devio.c sched/headers: Prepare for new header dependencies before moving code to <linux/sched/signal.h> 2017-03-02 08:42:29 +01:00
driver.c usb: hub: Fix error loop seen after hub communication errors 2017-03-23 08:13:22 +01:00
endpoint.c usb: patches for v4.10 merge window 2016-11-18 16:02:15 +01:00
file.c USB: core: add missing license information to some files 2016-10-29 12:51:56 -04:00
generic.c USB: core: add missing license information to some files 2016-10-29 12:51:56 -04:00
hcd-pci.c usb: hcd: out of bounds access in for_each_companion 2016-04-13 12:06:18 -07:00
hcd.c usb: hcd: initialize hcd->flags to 0 when rm hcd 2017-01-19 10:34:41 +01:00
hub.c usb: hub: Fix error loop seen after hub communication errors 2017-03-23 08:13:22 +01:00
hub.h usb: Support USB 3.1 extended port status request 2016-01-24 20:16:52 -08:00
Kconfig usb: core: Introduce a USB port LED trigger 2016-09-27 12:20:17 +02:00
ledtrig-usbport.c usb: core: usbport: Use proper LED API to fix potential crash 2016-12-06 08:37:41 +01:00
Makefile usb: add CONFIG_USB_PCI for system have both PCI HW and non-PCI based USB HW 2017-03-17 13:16:56 +09:00
message.c usb: core: update comments for send message functions 2017-01-19 10:34:40 +01:00
notify.c USB: core: add missing license information to some files 2016-10-29 12:51:56 -04:00
of.c usb: of: add functions to bind a companion controller 2017-03-17 13:24:48 +09:00
otg_whitelist.h usb: core: use IS_ENABLED() instead of checking for built-in or module 2016-09-02 14:36:33 +02:00
port.c Revert "USB / PM: Allow USB devices to remain runtime-suspended when sleeping" 2016-05-02 08:44:31 -07:00
quirks.c USB: Add quirk for WORLDE easykey.25 MIDI keyboard 2017-01-25 11:02:29 +01:00
sysfs.c USB: core: add missing license information to some files 2016-10-29 12:51:56 -04:00
urb.c usb: patches for v4.10 merge window 2016-11-18 16:02:15 +01:00
usb-acpi.c usb: find internal hub tier mismatch via acpi 2014-05-27 16:38:52 -07:00
usb.c USB: core: add missing license information to some files 2016-10-29 12:51:56 -04:00
usb.h USB: core: add missing license information to some files 2016-10-29 12:51:56 -04:00