Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2019-07-21 10:23:21 +0200
committerJiri Slaby <jslaby@suse.cz>2019-07-21 10:23:26 +0200
commit1f59201537e9ef3a4179add5c7f4df805cc79f41 (patch)
tree0d0a06f52d0b45fca5551f3cdb4ceb084b82c846
parentc4ec1ff3d406a900904aa20d751be440363009c8 (diff)
x86/irq: Handle spurious interrupt after shutdown gracefully
-rw-r--r--patches.kernel.org/5.2.2-011-x86-irq-Handle-spurious-interrupt-after-shutdow.patch120
-rw-r--r--series.conf1
2 files changed, 121 insertions, 0 deletions
diff --git a/patches.kernel.org/5.2.2-011-x86-irq-Handle-spurious-interrupt-after-shutdow.patch b/patches.kernel.org/5.2.2-011-x86-irq-Handle-spurious-interrupt-after-shutdow.patch
new file mode 100644
index 0000000000..d0bbac7cd1
--- /dev/null
+++ b/patches.kernel.org/5.2.2-011-x86-irq-Handle-spurious-interrupt-after-shutdow.patch
@@ -0,0 +1,120 @@
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Fri, 28 Jun 2019 13:11:53 +0200
+Subject: [PATCH] x86/irq: Handle spurious interrupt after shutdown gracefully
+References: bnc#1012628
+Patch-mainline: 5.2.2
+Git-commit: b7107a67f0d125459fe41f86e8079afd1a5e0b15
+
+commit b7107a67f0d125459fe41f86e8079afd1a5e0b15 upstream.
+
+Since the rework of the vector management, warnings about spurious
+interrupts have been reported. Robert provided some more information and
+did an initial analysis. The following situation leads to these warnings:
+
+ CPU 0 CPU 1 IO_APIC
+
+ interrupt is raised
+ sent to CPU1
+ Unable to handle
+ immediately
+ (interrupts off,
+ deep idle delay)
+ mask()
+ ...
+ free()
+ shutdown()
+ synchronize_irq()
+ clear_vector()
+ do_IRQ()
+ -> vector is clear
+
+Before the rework the vector entries of legacy interrupts were statically
+assigned and occupied precious vector space while most of them were
+unused. Due to that the above situation was handled silently because the
+vector was handled and the core handler of the assigned interrupt
+descriptor noticed that it is shut down and returned.
+
+While this has been usually observed with legacy interrupts, this situation
+is not limited to them. Any other interrupt source, e.g. MSI, can cause the
+same issue.
+
+After adding proper synchronization for level triggered interrupts, this
+can only happen for edge triggered interrupts where the IO-APIC obviously
+cannot provide information about interrupts in flight.
+
+While the spurious warning is actually harmless in this case it worries
+users and driver developers.
+
+Handle it gracefully by marking the vector entry as VECTOR_SHUTDOWN instead
+of VECTOR_UNUSED when the vector is freed up.
+
+If that above late handling happens the spurious detector will not complain
+and switch the entry to VECTOR_UNUSED. Any subsequent spurious interrupt on
+that line will trigger the spurious warning as before.
+
+Fixes: 464d12309e1b ("x86/vector: Switch IOAPIC to global reservation mode")
+Reported-by: Robert Hodaszi <Robert.Hodaszi@digi.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>-
+Tested-by: Robert Hodaszi <Robert.Hodaszi@digi.com>
+Cc: Marc Zyngier <marc.zyngier@arm.com>
+Link: https://lkml.kernel.org/r/20190628111440.459647741@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/include/asm/hw_irq.h | 3 ++-
+ arch/x86/kernel/apic/vector.c | 4 ++--
+ arch/x86/kernel/irq.c | 2 +-
+ 3 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
+index 32e666e1231e..626e1ac6516e 100644
+--- a/arch/x86/include/asm/hw_irq.h
++++ b/arch/x86/include/asm/hw_irq.h
+@@ -151,7 +151,8 @@ extern char irq_entries_start[];
+ #endif
+
+ #define VECTOR_UNUSED NULL
+-#define VECTOR_RETRIGGERED ((void *)~0UL)
++#define VECTOR_SHUTDOWN ((void *)~0UL)
++#define VECTOR_RETRIGGERED ((void *)~1UL)
+
+ typedef struct irq_desc* vector_irq_t[NR_VECTORS];
+ DECLARE_PER_CPU(vector_irq_t, vector_irq);
+diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
+index e7cb78aed644..fdacb864c3dd 100644
+--- a/arch/x86/kernel/apic/vector.c
++++ b/arch/x86/kernel/apic/vector.c
+@@ -340,7 +340,7 @@ static void clear_irq_vector(struct irq_data *irqd)
+ trace_vector_clear(irqd->irq, vector, apicd->cpu, apicd->prev_vector,
+ apicd->prev_cpu);
+
+- per_cpu(vector_irq, apicd->cpu)[vector] = VECTOR_UNUSED;
++ per_cpu(vector_irq, apicd->cpu)[vector] = VECTOR_SHUTDOWN;
+ irq_matrix_free(vector_matrix, apicd->cpu, vector, managed);
+ apicd->vector = 0;
+
+@@ -349,7 +349,7 @@ static void clear_irq_vector(struct irq_data *irqd)
+ if (!vector)
+ return;
+
+- per_cpu(vector_irq, apicd->prev_cpu)[vector] = VECTOR_UNUSED;
++ per_cpu(vector_irq, apicd->prev_cpu)[vector] = VECTOR_SHUTDOWN;
+ irq_matrix_free(vector_matrix, apicd->prev_cpu, vector, managed);
+ apicd->prev_vector = 0;
+ apicd->move_in_progress = 0;
+diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
+index 9b68b5b00ac9..cc496eb7a8d2 100644
+--- a/arch/x86/kernel/irq.c
++++ b/arch/x86/kernel/irq.c
+@@ -247,7 +247,7 @@ __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs)
+ if (!handle_irq(desc, regs)) {
+ ack_APIC_irq();
+
+- if (desc != VECTOR_RETRIGGERED) {
++ if (desc != VECTOR_RETRIGGERED && desc != VECTOR_SHUTDOWN) {
+ pr_emerg_ratelimited("%s: %d.%d No irq handler for vector\n",
+ __func__, smp_processor_id(),
+ vector);
+--
+2.22.0
+
diff --git a/series.conf b/series.conf
index 2b9fb49862..fa2e8396ba 100644
--- a/series.conf
+++ b/series.conf
@@ -98,6 +98,7 @@
patches.kernel.org/5.2.2-008-genirq-Fix-misleading-synchronize_irq-documenta.patch
patches.kernel.org/5.2.2-009-genirq-Add-optional-hardware-synchronization-fo.patch
patches.kernel.org/5.2.2-010-x86-ioapic-Implement-irq_get_irqchip_state-call.patch
+ patches.kernel.org/5.2.2-011-x86-irq-Handle-spurious-interrupt-after-shutdow.patch
########################################################
# Build fixes that apply to the vanilla kernel too.