From eb5eb075d8d073142eaea20e1ab7af87a1e00e1d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 22 Aug 2022 19:16:15 +0200 Subject: [PATCH] Revert "USB: HCD: Fix URB giveback issue in tasklet function" This reverts commit 4d7da7e565c36bd5685b5d5452f4feffc794050a which is commit 26c6c2f8a907c9e3a2f24990552a4d77235791e6 upstream. It breaks the Android GKI kernel abi, and is not needed for Android devices, so revert it for now. If it is needed for this branch, it can come back later in an ABI-stable way. Bug: 161946584 Signed-off-by: Greg Kroah-Hartman Change-Id: I7cebceb7c3e1eccf4a36a18dbe0e7ec21378b719 --- drivers/usb/core/hcd.c | 26 +++++++++++--------------- include/linux/usb/hcd.h | 1 - 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index ac347f9d5ef0..bf5e37667697 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1692,6 +1692,7 @@ static void usb_giveback_urb_bh(struct tasklet_struct *t) spin_lock_irq(&bh->lock); bh->running = true; + restart: list_replace_init(&bh->head, &local_list); spin_unlock_irq(&bh->lock); @@ -1705,17 +1706,10 @@ static void usb_giveback_urb_bh(struct tasklet_struct *t) bh->completing_ep = NULL; } - /* - * giveback new URBs next time to prevent this function - * from not exiting for a long time. - */ + /* check if there are new URBs to giveback */ spin_lock_irq(&bh->lock); - if (!list_empty(&bh->head)) { - if (bh->high_prio) - tasklet_hi_schedule(&bh->bh); - else - tasklet_schedule(&bh->bh); - } + if (!list_empty(&bh->head)) + goto restart; bh->running = false; spin_unlock_irq(&bh->lock); } @@ -1740,7 +1734,7 @@ static void usb_giveback_urb_bh(struct tasklet_struct *t) void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) { struct giveback_urb_bh *bh; - bool running; + bool running, high_prio_bh; /* pass status to tasklet via unlinked */ if (likely(!urb->unlinked)) @@ -1751,10 +1745,13 @@ void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) return; } - if (usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe)) + if (usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe)) { bh = &hcd->high_prio_bh; - else + high_prio_bh = true; + } else { bh = &hcd->low_prio_bh; + high_prio_bh = false; + } spin_lock(&bh->lock); list_add_tail(&urb->urb_list, &bh->head); @@ -1763,7 +1760,7 @@ void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) if (running) ; - else if (bh->high_prio) + else if (high_prio_bh) tasklet_hi_schedule(&bh->bh); else tasklet_schedule(&bh->bh); @@ -2803,7 +2800,6 @@ int usb_add_hcd(struct usb_hcd *hcd, /* initialize tasklets */ init_giveback_urb_bh(&hcd->high_prio_bh); - hcd->high_prio_bh.high_prio = true; init_giveback_urb_bh(&hcd->low_prio_bh); /* enable irqs just before we start the controller, diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 70106b34785a..d14b39d1418e 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -67,7 +67,6 @@ struct giveback_urb_bh { bool running; - bool high_prio; spinlock_t lock; struct list_head head; struct tasklet_struct bh;