Module Name: src Committed By: riastradh Date: Tue Sep 7 10:44:18 UTC 2021
Modified Files: src/sys/dev/usb: usb_subr.c usbdi.c usbdivar.h Log Message: usb(4): Fix xfer race between software abort and hardware completion. This fixes a bug in the API contract of usbd_abort_pipe: with the change, the caller is guaranteed the xfer completion callbacks have returned; without the change, completion callbacks could still be running on the queued xfers while the caller of usbd_abort_pipe proceeds to concurrently issue usbd_destroy_xfer. This also fixes the following problem for interrupt pipes, whose xfers stay on the queue until the pipe is aborted: Thread 1: Hardware completion interrupt calls usb_transfer_complete. Thread 1: pipe->up_repeat is 1, so usb_transfer_complete keeps xfer queued. Thread 2: Calls usbd_abort_pipe (e.g., in detach). Thread 2: usbd_abort_pipe waits for bus lock. Thread 1: usb_transfer_complete releases bus lock to invoke callback. Thread 2: Sets pipe->up_repeat := 0 (too late for thread 1 to see). Thread 1: usb_transfer_complete waits to reacquire bus lock before resetting xfer status to USBD_NOT_STARTED. Thread 2: Repeatdly calls upm_abort on the same xfer, which does nothing because upm_abort just does usbd_abort_xfer which does nothing because the xfer status is (e.g.) USBD_IOERROR and not USBD_IN_PROGRESS. Thread 2 is now spinning forever with the bus lock held (and possibly the kernel lock) waiting for queue or xfer status to change, which will never happen as long as it holds the bus lock. The resolution is for thread 2 to notice that thread 1 is busy invoking a callback, and to wait until thread 1 has finished invoking the callback and updated the xfer status to reset it to USBD_NOT_STARTED at which point thread 1 can make progress again. XXX pullup-9 To generate a diff of this commit: cvs rdiff -u -r1.266 -r1.267 src/sys/dev/usb/usb_subr.c cvs rdiff -u -r1.218 -r1.219 src/sys/dev/usb/usbdi.c cvs rdiff -u -r1.129 -r1.130 src/sys/dev/usb/usbdivar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.