From: Greg Kroah-Hartman Date: Mon, 26 Jul 2021 10:53:02 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.4.277~16 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e96297010c32f177130880bb107849b7fe52bf3b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: usb-ehci-prevent-missed-ehci-interrupts-with-edge-triggered-msi.patch --- diff --git a/queue-5.10/series b/queue-5.10/series index 27bf8caec18..b9b4e57f339 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -161,3 +161,4 @@ bonding-fix-build-issue.patch skbuff-release-nfct-refcount-on-napi-stolen-or-re-used-skbs.patch documentation-fix-intiramfs-script-name.patch perf-inject-close-inject.output-on-exit.patch +usb-ehci-prevent-missed-ehci-interrupts-with-edge-triggered-msi.patch diff --git a/queue-5.10/usb-ehci-prevent-missed-ehci-interrupts-with-edge-triggered-msi.patch b/queue-5.10/usb-ehci-prevent-missed-ehci-interrupts-with-edge-triggered-msi.patch new file mode 100644 index 00000000000..b57a9072f91 --- /dev/null +++ b/queue-5.10/usb-ehci-prevent-missed-ehci-interrupts-with-edge-triggered-msi.patch @@ -0,0 +1,85 @@ +From 0b60557230adfdeb8164e0b342ac9cd469a75759 Mon Sep 17 00:00:00 2001 +From: David Jeffery +Date: Thu, 15 Jul 2021 17:37:44 -0400 +Subject: usb: ehci: Prevent missed ehci interrupts with edge-triggered MSI + +From: David Jeffery + +commit 0b60557230adfdeb8164e0b342ac9cd469a75759 upstream. + +When MSI is used by the ehci-hcd driver, it can cause lost interrupts which +results in EHCI only continuing to work due to a polling fallback. But the +reliance of polling drastically reduces performance of any I/O through EHCI. + +Interrupts are lost as the EHCI interrupt handler does not safely handle +edge-triggered interrupts. It fails to ensure all interrupt status bits are +cleared, which works with level-triggered interrupts but not the +edge-triggered interrupts typical from using MSI. + +To fix this problem, check if the driver may have raced with the hardware +setting additional interrupt status bits and clear status until it is in a +stable state. + +Fixes: 306c54d0edb6 ("usb: hcd: Try MSI interrupts on PCI devices") +Tested-by: Laurence Oberman +Reviewed-by: Andy Shevchenko +Acked-by: Alan Stern +Signed-off-by: David Jeffery +Link: https://lore.kernel.org/r/20210715213744.GA44506@redhat +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/ehci-hcd.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -703,7 +703,8 @@ EXPORT_SYMBOL_GPL(ehci_setup); + static irqreturn_t ehci_irq (struct usb_hcd *hcd) + { + struct ehci_hcd *ehci = hcd_to_ehci (hcd); +- u32 status, masked_status, pcd_status = 0, cmd; ++ u32 status, current_status, masked_status, pcd_status = 0; ++ u32 cmd; + int bh; + unsigned long flags; + +@@ -715,19 +716,22 @@ static irqreturn_t ehci_irq (struct usb_ + */ + spin_lock_irqsave(&ehci->lock, flags); + +- status = ehci_readl(ehci, &ehci->regs->status); ++ status = 0; ++ current_status = ehci_readl(ehci, &ehci->regs->status); ++restart: + + /* e.g. cardbus physical eject */ +- if (status == ~(u32) 0) { ++ if (current_status == ~(u32) 0) { + ehci_dbg (ehci, "device removed\n"); + goto dead; + } ++ status |= current_status; + + /* + * We don't use STS_FLR, but some controllers don't like it to + * remain on, so mask it out along with the other status bits. + */ +- masked_status = status & (INTR_MASK | STS_FLR); ++ masked_status = current_status & (INTR_MASK | STS_FLR); + + /* Shared IRQ? */ + if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { +@@ -737,6 +741,12 @@ static irqreturn_t ehci_irq (struct usb_ + + /* clear (just) interrupts */ + ehci_writel(ehci, masked_status, &ehci->regs->status); ++ ++ /* For edge interrupts, don't race with an interrupt bit being raised */ ++ current_status = ehci_readl(ehci, &ehci->regs->status); ++ if (current_status & INTR_MASK) ++ goto restart; ++ + cmd = ehci_readl(ehci, &ehci->regs->command); + bh = 0; +