linux_dsm_epyc7002/drivers/usb/gadget/function
Fupan Li a24b071bb4 usb: gadget: f_printer: fix deadlock caused by nested spinlock
Function printer_func_disable() has called spinlock on printer_dev->lock,
and it'll call function chain of

    printer_reset_interface()
        |
	+---dwc3_gadget_ep_disable()
	        |
                +---__dwc3_gadget_ep_disable()
                        |
                        +---dwc3_remove_requests()
                                |
                                +---dwc3_gadget_giveback()
                                        |
                                        +---rx_complete()

in the protected block.

However, rx_complete() in f_printer.c calls spinlock on printer_dev->lock
again, which will cause system hang.

The following steps can reproduce this hang:

1. Build the test program from Documentation/usb/gadget_printer.txt as
   g_printer
2. Plug in the USB device to a host(such as Ubuntu).
3. on the USB device system run:
   #modprobe g_printer.ko
   #./g_printer -read_data

4. Unplug the USB device from the host

   The system will hang later.

In order to avoid this deadlock, moving the spinlock from
printer_func_disable() into printer_reset_interface() and excluding the block
of calling dwc3_gadget_ep_disable(), in which the critical resource will be
protected by its spinlock in rx_complete().

This commit will fix the system hang with the following calltrace:

INFO: rcu_preempt detected stalls on CPUs/tasks: { 3} (detected by 0, t=21006 jiffies, g=524, c=523, q=2)
sending NMI to all CPUs:
NMI backtrace for cpu 3
CPU: 3 PID: 718 Comm: irq/22-dwc3 Not tainted 3.10.38-ltsi-WR6.0.0.11_standard #2
Hardware name: Intel Corp. VALLEYVIEW B3 PLATFORM/NOTEBOOK, BIOS BYTICRB1.86C.0092.R32.1410021707 10/02/2014
task: f44f4c20 ti: f40f6000 task.ti: f40f6000
EIP: 0060:[<c1824955>] EFLAGS: 00000097 CPU: 3
EIP is at _raw_spin_lock_irqsave+0x35/0x40
EAX: 00000076 EBX: f80fad00 ECX: 00000076 EDX: 00000075
ESI: 00000096 EDI: ffffff94 EBP: f40f7e20 ESP: f40f7e18
 DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
CR0: 8005003b CR2: b77ac000 CR3: 01c30000 CR4: 001007f0
DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
DR6: ffff0ff0 DR7: 00000400
Stack:
 f474a720 f80fad00 f40f7e3c f80f93cc c135d486 00000000 f474a720 f468fb00
 f4bea894 f40f7e54 f7e35f19 ffffff00 f468fb00 f468fb24 00000086 f40f7e64
 f7e36577 f468fb00 f4bea810 f40f7e74 f7e365a8 f468fb00 f4bea894 f40f7e9c
Call Trace:
 [<f80f93cc>] rx_complete+0x1c/0xb0 [g_printer]
 [<c135d486>] ? vsnprintf+0x166/0x390
 [<f7e35f19>] dwc3_gadget_giveback+0xc9/0xf0 [dwc3]
 [<f7e36577>] dwc3_remove_requests+0x57/0x70 [dwc3]
 [<f7e365a8>] __dwc3_gadget_ep_disable+0x18/0x60 [dwc3]
 [<f7e366e9>] dwc3_gadget_ep_disable+0x89/0xf0 [dwc3]
 [<f80f9031>] printer_reset_interface+0x31/0x50 [g_printer]
 [<f80f9270>] printer_func_disable+0x20/0x30 [g_printer]
 [<f80e6d8b>] composite_disconnect+0x4b/0x90 [libcomposite]
 [<f7e39a8b>] dwc3_disconnect_gadget+0x38/0x43 [dwc3]
 [<f7e39ad4>] dwc3_gadget_disconnect_interrupt+0x3e/0x5a [dwc3]
 [<f7e373b8>] dwc3_thread_interrupt+0x5c8/0x610 [dwc3]
 [<c10ac518>] irq_thread_fn+0x18/0x30
 [<c10ac800>] irq_thread+0x100/0x130
 [<c10ac500>] ? irq_finalize_oneshot.part.29+0xb0/0xb0
 [<c10ac650>] ? wake_threads_waitq+0x40/0x40
 [<c10ac700>] ? irq_thread_dtor+0xb0/0xb0
 [<c1057224>] kthread+0x94/0xa0
 [<c182b337>] ret_from_kernel_thread+0x1b/0x28
 [<c1057190>] ? kthread_create_on_node+0xc0/0xc0

Signed-off-by: Fupan Li <fupan.li@windriver.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
2015-08-03 09:49:47 -05:00
..
f_acm.c usb: gadget: function: acm: make f_acm pass USB20CV Chapter9 2014-10-20 15:58:48 -05:00
f_ecm.c usb: gadget: f_ecm/f_ncm: check quirk instead of UDC name 2015-07-30 11:43:36 -05:00
f_eem.c usb: gadget: function: Remove redundant usb_free_all_descriptors 2014-10-23 13:57:24 -05:00
f_fs.c usb: gadget: ffs: call functionfs_unbind() if _ffs_func_bind() fails 2015-07-31 08:57:57 -05:00
f_hid.c usb: gadget: hid: Fix static variable usage 2015-04-27 14:44:23 -05:00
f_loopback.c usb: gadget: loopback: Remove out-of-date comment 2015-07-29 09:59:18 -05:00
f_mass_storage.c usb: gadget: mass_storage: Use static array for luns 2015-07-31 09:01:19 -05:00
f_mass_storage.h usb: gadget: mass_storage: Use static array for luns 2015-07-31 09:01:19 -05:00
f_midi.c usb: gadget: midi: avoid redundant f_midi_set_alt() call 2015-07-31 08:57:59 -05:00
f_ncm.c usb: gadget: f_ecm/f_ncm: check quirk instead of UDC name 2015-07-30 11:43:36 -05:00
f_obex.c usb: gadget: apply generic altsetting support check mechanism 2015-07-30 11:43:36 -05:00
f_phonet.c usb: gadget: function: phonet: balance usb_ep_disable calls 2015-02-23 00:18:52 -06:00
f_printer.c usb: gadget: f_printer: fix deadlock caused by nested spinlock 2015-08-03 09:49:47 -05:00
f_rndis.c usb: gadget: rndis: remove the limit of available rndis connections 2015-05-07 13:47:17 -05:00
f_serial.c usb: gadget: serial: replace {V,}DBG macro with dev_{v,}dbg 2014-08-27 14:13:17 -05:00
f_sourcesink.c usb: gadget: SourceSink: Remove out-of-date comment 2015-07-29 09:59:18 -05:00
f_subset.c usb: gadget: function: Remove redundant usb_free_all_descriptors 2014-10-23 13:57:24 -05:00
f_uac1.c usb: gadget: f_uac1: check return code from config_ep_by_speed 2015-05-26 10:15:09 -05:00
f_uac2.c usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth 2015-07-30 11:43:38 -05:00
f_uvc.c usb: gadget: f_uvc: use bind_deactivated flag 2015-07-29 09:59:20 -05:00
f_uvc.h usb: gadget: f_uvc: remove compatibility layer 2014-09-09 09:49:41 -05:00
g_zero.h Revert "usb: gadget: zero: Add support for interrupt EP" 2015-03-11 10:00:05 -05:00
Makefile usb: gadget: f_printer: convert to new function interface with backward compatibility 2015-03-10 15:33:40 -05:00
ndis.h
rndis.c usb: gadget: rndis: use signed type for a signed value 2015-05-21 16:29:14 -05:00
rndis.h usb: gadget: rndis: use signed type for a signed value 2015-05-21 16:29:14 -05:00
storage_common.c vfs: add file_path() helper 2015-06-23 18:00:05 -04:00
storage_common.h usb: gadget: storage-common: Set FSG_MAX_LUNS to 16 2015-07-29 09:59:19 -05:00
u_ecm.h
u_eem.h
u_ether_configfs.h
u_ether.c usb: gadget: ethernet: re-use %pM specifier to print MAC 2015-01-19 12:53:32 -06:00
u_ether.h usb: gadget: apply generic altsetting support check mechanism 2015-07-30 11:43:36 -05:00
u_fs.h usb: gadget: ffs: add eventfd notification about ffs events 2015-01-27 09:34:59 -06:00
u_gether.h
u_hid.h usb: gadget: hid: add configfs support 2014-11-06 16:18:19 -06:00
u_midi.h usb: gadget: f_midi: add configfs support 2014-11-05 13:37:17 -06:00
u_ncm.h
u_phonet.h
u_printer.h usb: gadget: printer: add configfs support 2015-03-10 15:33:41 -05:00
u_rndis.h usb: gadget: rndis: remove the limit of available rndis connections 2015-05-07 13:47:17 -05:00
u_serial.c usb: gadget: serial: fix re-ordering of tx data 2015-04-27 14:44:29 -05:00
u_serial.h
u_uac1.c usb: gadget: u_uac1: fix one code style problem 2015-01-15 09:41:48 -06:00
u_uac1.h usb: gadget: uac1: struct gaudio is useless for struct f_uac1_opts 2015-01-15 09:41:48 -06:00
u_uac2.h usb: gadget: f_uac2: add configfs support 2014-08-20 14:04:42 -05:00
u_uvc.h usb: gadget: uvc: configfs support in uvc function 2015-01-12 12:13:26 -06:00
uvc_configfs.c usb: gadget: uvc: comments for iterating over streaming hierarchy 2015-01-27 10:00:27 -06:00
uvc_configfs.h usb: gadget: uvc: configfs support in uvc function 2015-01-12 12:13:26 -06:00
uvc_queue.c [media] uvc gadget: switch to v4l2 core locking 2015-03-02 17:05:23 -03:00
uvc_queue.h [media] uvc gadget: switch to v4l2 core locking 2015-03-02 17:05:23 -03:00
uvc_v4l2.c Merge branch 'drm-next-merged' of git://people.freedesktop.org/~airlied/linux into v4l_for_linus 2015-04-21 09:44:55 -03:00
uvc_v4l2.h usb: gadget: uvc: separately compile some components of f_uvc 2014-09-09 09:49:12 -05:00
uvc_video.c Merge branch 'drm-next-merged' of git://people.freedesktop.org/~airlied/linux into v4l_for_linus 2015-04-21 09:44:55 -03:00
uvc_video.h usb: gadget: uvc: separately compile some components of f_uvc 2014-09-09 09:49:12 -05:00
uvc.h usb: gadget: uvc: remove unused including <linux/version.h> 2015-04-27 15:48:11 -05:00