diff options
author | Josh Boyer <jwboyer@redhat.com> | 2012-06-20 15:06:01 -0400 |
---|---|---|
committer | Josh Boyer <jwboyer@redhat.com> | 2012-06-20 15:06:01 -0400 |
commit | b718a988d5426217902c7790d6aa070b729fbc6a (patch) | |
tree | 7f1f83ea10f3a107d9836c174bc8ef700fb3bd89 /unhandled-irqs-switch-to-polling.patch | |
parent | 3b37beedf48825354c42e25f7001677320958d38 (diff) | |
download | kernel-b718a988d5426217902c7790d6aa070b729fbc6a.tar.gz kernel-b718a988d5426217902c7790d6aa070b729fbc6a.tar.xz kernel-b718a988d5426217902c7790d6aa070b729fbc6a.zip |
Fix incorrect logic in irqpoll patch
Diffstat (limited to 'unhandled-irqs-switch-to-polling.patch')
-rw-r--r-- | unhandled-irqs-switch-to-polling.patch | 101 |
1 files changed, 49 insertions, 52 deletions
diff --git a/unhandled-irqs-switch-to-polling.patch b/unhandled-irqs-switch-to-polling.patch index 2f25cda6f..0fc4d080e 100644 --- a/unhandled-irqs-switch-to-polling.patch +++ b/unhandled-irqs-switch-to-polling.patch @@ -1,23 +1,8 @@ -Date: Mon, 30 Jan 2012 22:37:28 +0100 -Message-ID: <CAPRPZsAt+e3cy1YTriikpb2SNN=jOusvnPF0ByFeun+uaBa5Og@mail.gmail.com> +From f9b32cd97783f2be14386f1347439e86109050b9 Mon Sep 17 00:00:00 2001 +From: Jeroen Van den Keybus <jeroen.vandenkeybus@gmail.com> +Date: Mon, 30 Jan 2012 22:37:28 +0100 Subject: [PATCH] Unhandled IRQs on AMD E-450: temporarily switch to low-performance polling IRQ mode -From: Jeroen Van den Keybus <jeroen.vandenkeybus@gmail.com> -To: linux-kernel@vger.kernel.org -Cc: Clemens Ladisch <clemens@ladisch.de>, "Huang, Shane" <Shane.Huang@amd.com>, - Borislav Petkov <bp@amd64.org>, "Nguyen, Dong" <Dong.Nguyen@amd.com>, - jesse.brandeburg@gmail.com -Content-Type: text/plain; charset=ISO-8859-1 -Sender: linux-kernel-owner@vger.kernel.org -Precedence: bulk -List-ID: <linux-kernel.vger.kernel.org> -X-Mailing-List: linux-kernel@vger.kernel.org -X-RedHat-Spam-Score: -4.898 (DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,FREEMAIL_FROM,RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD) -X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 -X-Scanned-By: MIMEDefang 2.68 on 10.5.110.19 -Status: RO -Content-Length: 7029 -Lines: 189 It seems that some motherboard designs using the ASM1083 PCI/PCIe bridge (PCI device ID 1b21:1080, Rev. 01) suffer from stuck IRQ lines @@ -79,16 +64,49 @@ I would like to thank Clemens Ladisch for his invaluable help in finding a solution (and providing a patch to avoid my SATA going down every time during debugging). - Signed-off-by: Jeroen Van den Keybus <jeroen.vandenkeybus@gmail.com> Make it less chatty. Only kick it in if we detect an ASM1083 PCI bridge. +Fix logic error due to lack of braces Josh Boyer <jwboyer@redhat.com> ====== +--- + drivers/pci/quirks.c | 16 +++++++++++ + kernel/irq/spurious.c | 73 +++++++++++++++++++++++++++++++++++++++--------- + 2 files changed, 75 insertions(+), 14 deletions(-) ---- linux-2.6.orig/kernel/irq/spurious.c -+++ linux-2.6/kernel/irq/spurious.c +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 78fda9c..6ba5dbf 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -1677,6 +1677,22 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2609, quirk_intel_pcie_pm); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm); + ++/* ASM108x transparent PCI bridges apparently have broken IRQ deassert ++ * handling. This causes interrupts to get "stuck" and eventually disabled. ++ * However, the interrupts are often shared and disabling them is fairly bad. ++ * It's been somewhat successful to switch to polling mode and retry after ++ * a bit, so let's do that. ++ */ ++extern int irq_poll_and_retry; ++static void quirk_asm108x_poll_interrupts(struct pci_dev *dev) ++{ ++ dev_info(&dev->dev, "Buggy bridge found [%04x:%04x]\n", ++ dev->vendor, dev->device); ++ dev_info(&dev->dev, "Stuck interrupts will be polled and retried\n"); ++ irq_poll_and_retry = 1; ++} ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_asm108x_poll_interrupts); ++ + #ifdef CONFIG_X86_IO_APIC + /* + * Boot interrupts on some chipsets cannot be turned off. For these chipsets, +diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c +index 611cd60..f722eb6 100644 +--- a/kernel/irq/spurious.c ++++ b/kernel/irq/spurious.c @@ -18,6 +18,8 @@ static int irqfixup __read_mostly; @@ -113,7 +131,7 @@ Josh Boyer <jwboyer@redhat.com> for_each_irq_desc(i, desc) { unsigned int state; -@@ -159,14 +162,33 @@ static void poll_spurious_irqs(unsigned +@@ -159,14 +162,33 @@ static void poll_spurious_irqs(unsigned long dummy) if (!(state & IRQS_SPURIOUS_DISABLED)) continue; @@ -152,7 +170,7 @@ Josh Boyer <jwboyer@redhat.com> } static inline int bad_action_ret(irqreturn_t action_ret) -@@ -177,11 +199,19 @@ static inline int bad_action_ret(irqretu +@@ -177,11 +199,19 @@ static inline int bad_action_ret(irqreturn_t action_ret) } /* @@ -174,7 +192,7 @@ Josh Boyer <jwboyer@redhat.com> * functioning device sharing an IRQ with the failing one) */ static void -@@ -269,6 +299,8 @@ try_misrouted_irq(unsigned int irq, stru +@@ -269,6 +299,8 @@ try_misrouted_irq(unsigned int irq, struct irq_desc *desc, void note_interrupt(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret) { @@ -183,18 +201,19 @@ Josh Boyer <jwboyer@redhat.com> if (desc->istate & IRQS_POLL_INPROGRESS) return; -@@ -302,19 +334,31 @@ void note_interrupt(unsigned int irq, st +@@ -302,19 +334,32 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc, } desc->irq_count++; - if (likely(desc->irq_count < 100000)) - return; -+ if (!irq_poll_and_retry) ++ if (!irq_poll_and_retry) { + if (likely(desc->irq_count < 100000)) + return; -+ else ++ } else { + if (likely(desc->irq_count < 10)) + return; ++ } desc->irq_count = 0; - if (unlikely(desc->irqs_unhandled > 99900)) { @@ -221,28 +240,6 @@ Josh Boyer <jwboyer@redhat.com> desc->istate |= IRQS_SPURIOUS_DISABLED; desc->depth++; irq_disable(desc); ---- linux-2.6.orig/drivers/pci/quirks.c -+++ linux-2.6/drivers/pci/quirks.c -@@ -1677,6 +1677,22 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm); - -+/* ASM108x transparent PCI bridges apparently have broken IRQ deassert -+ * handling. This causes interrupts to get "stuck" and eventually disabled. -+ * However, the interrupts are often shared and disabling them is fairly bad. -+ * It's been somewhat successful to switch to polling mode and retry after -+ * a bit, so let's do that. -+ */ -+extern int irq_poll_and_retry; -+static void quirk_asm108x_poll_interrupts(struct pci_dev *dev) -+{ -+ dev_info(&dev->dev, "Buggy bridge found [%04x:%04x]\n", -+ dev->vendor, dev->device); -+ dev_info(&dev->dev, "Stuck interrupts will be polled and retried\n"); -+ irq_poll_and_retry = 1; -+} -+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_asm108x_poll_interrupts); -+ - #ifdef CONFIG_X86_IO_APIC - /* - * Boot interrupts on some chipsets cannot be turned off. For these chipsets, +-- +1.7.7.6 + |