Skip to content

Commit fdd64df

Browse files
AlanSterngregkh
authored andcommitted
USB: usbfs: Always unlink URBs in reverse order
When the kernel unlinks a bunch of URBs for a single endpoint, it should always unlink them in reverse order. This eliminates any possibility that some URB x will be unlinked before it can execute but the following URB x+1 will execute before it can be unlinked. Such an event would be bad, for obvious reasons. Chris Dickens pointed out that usbfs doesn't behave this way when it is unbound from an interface. All pending URBs are cancelled, but in the order of submission. This patch changes the behavior to make the unlinks occur in reverse order. It similarly changes the behavior when usbfs cancels the continuation URBs for a BULK endpoint. Suggested-by: Chris Dickens <[email protected]> Signed-off-by: Alan Stern <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 50f737a commit fdd64df

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

drivers/usb/core/devio.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ __acquires(ps->lock)
574574

575575
/* Now carefully unlink all the marked pending URBs */
576576
rescan:
577-
list_for_each_entry(as, &ps->async_pending, asynclist) {
577+
list_for_each_entry_reverse(as, &ps->async_pending, asynclist) {
578578
if (as->bulk_status == AS_UNLINK) {
579579
as->bulk_status = 0; /* Only once */
580580
urb = as->urb;
@@ -636,7 +636,7 @@ static void destroy_async(struct usb_dev_state *ps, struct list_head *list)
636636

637637
spin_lock_irqsave(&ps->lock, flags);
638638
while (!list_empty(list)) {
639-
as = list_entry(list->next, struct async, asynclist);
639+
as = list_last_entry(list, struct async, asynclist);
640640
list_del_init(&as->asynclist);
641641
urb = as->urb;
642642
usb_get_urb(urb);

0 commit comments

Comments
 (0)