Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: usbip: Fix deadlock

When detaching a port from the client side (usbip --detach 0),
the event thread, on the server side, is going to deadlock.
The "eh" server thread is getting USBIP_EH_RESET event and calls:
-> stub_device_reset() -> usb_reset_device()
the USB framework is then calling back _in the same "eh" thread_ :
-> stub_disconnect() -> usbip_stop_eh() -> wait_for_completion()
the "eh" thread is being asleep forever, waiting for its own completion.
This patch checks if "eh" is the current thread, in usbip_stop_eh().

Signed-off-by: Eric Lescouet <eric@lescouet.org>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Eric Lescouet and committed by
Greg Kroah-Hartman
d01f42a2 c0087580

+3
+3
drivers/staging/usbip/usbip_event.c
··· 117 117 { 118 118 struct usbip_task *eh = &ud->eh; 119 119 120 + if (eh->thread == current) 121 + return; /* do not wait for myself */ 122 + 120 123 wait_for_completion(&eh->thread_done); 121 124 usbip_dbg_eh("usbip_eh has finished\n"); 122 125 }