aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Gleixner <[email protected]>2015-12-31 16:30:52 +0000
committerThomas Gleixner <[email protected]>2016-01-15 13:44:01 +0100
commit56d7d2f4bbd00fb198b7907cb3ab657d06115a42 (patch)
tree68abc85548849ef65c4501c647e1ae3e2d0015be
parent5da0c1217f05d2ccc9a8ed6e6e5c23a8a1d24dd6 (diff)
x86/irq: Remove outgoing CPU from vector cleanup mask
We want to synchronize new vector assignments with a pending cleanup. Remove a dying cpu from a pending cleanup mask. Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Borislav Petkov <[email protected]> Tested-by: Joe Lawrence <[email protected]> Cc: Jiang Liu <[email protected]> Cc: Jeremiah Mahler <[email protected]> Cc: [email protected] Cc: Guenter Roeck <[email protected]> Cc: [email protected] #4.3+ Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Thomas Gleixner <[email protected]>
-rw-r--r--arch/x86/kernel/apic/vector.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 91dc2742cfb1..a7fa11e49582 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -633,9 +633,23 @@ void irq_complete_move(struct irq_cfg *cfg)
void irq_force_complete_move(int irq)
{
struct irq_cfg *cfg = irq_cfg(irq);
+ struct apic_chip_data *data;
+
+ if (!cfg)
+ return;
- if (cfg)
- __irq_complete_move(cfg, cfg->vector);
+ __irq_complete_move(cfg, cfg->vector);
+
+ /*
+ * Remove this cpu from the cleanup mask. The IPI might have been sent
+ * just before the cpu was removed from the offline mask, but has not
+ * been processed because the CPU has interrupts disabled and is on
+ * the way out.
+ */
+ raw_spin_lock(&vector_lock);
+ data = container_of(cfg, struct apic_chip_data, cfg);
+ cpumask_clear_cpu(smp_processor_id(), data->old_domain);
+ raw_spin_unlock(&vector_lock);
}
#endif