2020-10-12 12:52:06 +00:00
|
|
|
From 7b86b7671128097bf9b6263e1adf0da06473a421 Mon Sep 17 00:00:00 2001
|
|
|
|
Message-Id: <7b86b7671128097bf9b6263e1adf0da06473a421.1601675151.git.zanussi@kernel.org>
|
|
|
|
In-Reply-To: <5b5a156f9808b1acf1205606e03da117214549ea.1601675151.git.zanussi@kernel.org>
|
|
|
|
References: <5b5a156f9808b1acf1205606e03da117214549ea.1601675151.git.zanussi@kernel.org>
|
2020-01-19 00:54:59 +00:00
|
|
|
From: Thomas Gleixner <tglx@linutronix.de>
|
|
|
|
Date: Tue, 17 Jul 2018 18:25:31 +0200
|
2020-09-04 20:10:21 +00:00
|
|
|
Subject: [PATCH 013/333] x86/ioapic: Don't let setaffinity unmask threaded EOI
|
2020-01-19 00:54:59 +00:00
|
|
|
interrupt too early
|
2020-10-12 12:52:06 +00:00
|
|
|
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.148-rt64.tar.xz
|
2020-01-19 00:54:59 +00:00
|
|
|
|
|
|
|
There is an issue with threaded interrupts which are marked ONESHOT
|
|
|
|
and using the fasteoi handler.
|
|
|
|
|
|
|
|
if (IS_ONESHOT())
|
|
|
|
mask_irq();
|
|
|
|
|
|
|
|
....
|
|
|
|
....
|
|
|
|
|
|
|
|
cond_unmask_eoi_irq()
|
|
|
|
chip->irq_eoi();
|
|
|
|
|
|
|
|
So if setaffinity is pending then the interrupt will be moved and then
|
|
|
|
unmasked, which is wrong as it should be kept masked up to the point where
|
|
|
|
the threaded handler finished. It's not a real problem, the interrupt will
|
|
|
|
just be able to fire before the threaded handler has finished, though the irq
|
|
|
|
masked state will be wrong for a bit.
|
|
|
|
|
|
|
|
The patch below should cure the issue. It also renames the horribly
|
|
|
|
misnomed functions so it becomes clear what they are supposed to do.
|
|
|
|
|
|
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
|
|
[bigeasy: add the body of the patch, use the same functions in both
|
|
|
|
ifdef paths (spotted by Andy Shevchenko)]
|
|
|
|
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
|
|
---
|
|
|
|
arch/x86/kernel/apic/io_apic.c | 16 ++++++++--------
|
|
|
|
1 file changed, 8 insertions(+), 8 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
|
2020-09-04 20:10:21 +00:00
|
|
|
index 95e21c438012..53590eea257b 100644
|
2020-01-19 00:54:59 +00:00
|
|
|
--- a/arch/x86/kernel/apic/io_apic.c
|
|
|
|
+++ b/arch/x86/kernel/apic/io_apic.c
|
|
|
|
@@ -1722,7 +1722,7 @@ static bool io_apic_level_ack_pending(struct mp_chip_data *data)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static inline bool ioapic_irqd_mask(struct irq_data *data)
|
|
|
|
+static inline bool ioapic_prepare_move(struct irq_data *data)
|
|
|
|
{
|
|
|
|
/* If we are moving the IRQ we need to mask it */
|
|
|
|
if (unlikely(irqd_is_setaffinity_pending(data))) {
|
|
|
|
@@ -1733,9 +1733,9 @@ static inline bool ioapic_irqd_mask(struct irq_data *data)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static inline void ioapic_irqd_unmask(struct irq_data *data, bool masked)
|
|
|
|
+static inline void ioapic_finish_move(struct irq_data *data, bool moveit)
|
|
|
|
{
|
|
|
|
- if (unlikely(masked)) {
|
|
|
|
+ if (unlikely(moveit)) {
|
|
|
|
/* Only migrate the irq if the ack has been received.
|
|
|
|
*
|
|
|
|
* On rare occasions the broadcast level triggered ack gets
|
|
|
|
@@ -1770,11 +1770,11 @@ static inline void ioapic_irqd_unmask(struct irq_data *data, bool masked)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
-static inline bool ioapic_irqd_mask(struct irq_data *data)
|
|
|
|
+static inline bool ioapic_prepare_move(struct irq_data *data)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
-static inline void ioapic_irqd_unmask(struct irq_data *data, bool masked)
|
|
|
|
+static inline void ioapic_finish_move(struct irq_data *data, bool moveit)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
@@ -1783,11 +1783,11 @@ static void ioapic_ack_level(struct irq_data *irq_data)
|
|
|
|
{
|
|
|
|
struct irq_cfg *cfg = irqd_cfg(irq_data);
|
|
|
|
unsigned long v;
|
|
|
|
- bool masked;
|
|
|
|
+ bool moveit;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
irq_complete_move(cfg);
|
|
|
|
- masked = ioapic_irqd_mask(irq_data);
|
|
|
|
+ moveit = ioapic_prepare_move(irq_data);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* It appears there is an erratum which affects at least version 0x11
|
|
|
|
@@ -1842,7 +1842,7 @@ static void ioapic_ack_level(struct irq_data *irq_data)
|
|
|
|
eoi_ioapic_pin(cfg->vector, irq_data->chip_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
- ioapic_irqd_unmask(irq_data, masked);
|
|
|
|
+ ioapic_finish_move(irq_data, moveit);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ioapic_ir_ack_level(struct irq_data *irq_data)
|
|
|
|
--
|
2020-06-22 13:14:16 +00:00
|
|
|
2.17.1
|
2020-01-19 00:54:59 +00:00
|
|
|
|