Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

x86: Fix interrupt leak due to migration

When we migrate an interrupt from one CPU to another, we set the
move_in_progress flag and clean up the vectors later once they're not
being used. If you're unlucky and call destroy_irq() before the vectors
become un-used, the move_in_progress flag is never cleared, which causes
the interrupt to become unusable.

This was discovered by Jesse Brandeburg for whom it manifested as an
MSI-X device refusing to use MSI-X mode when the driver was unloaded
and reloaded repeatedly.

Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Matthew Wilcox and committed by
Linus Torvalds
0ca4b6b0 23918b03

+14
+14
arch/x86/kernel/io_apic.c
··· 1140 1140 1141 1141 cfg->vector = 0; 1142 1142 cpus_clear(cfg->domain); 1143 + 1144 + if (likely(!cfg->move_in_progress)) 1145 + return; 1146 + cpus_and(mask, cfg->old_domain, cpu_online_map); 1147 + for_each_cpu_mask_nr(cpu, mask) { 1148 + for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; 1149 + vector++) { 1150 + if (per_cpu(vector_irq, cpu)[vector] != irq) 1151 + continue; 1152 + per_cpu(vector_irq, cpu)[vector] = -1; 1153 + break; 1154 + } 1155 + } 1156 + cfg->move_in_progress = 0; 1143 1157 } 1144 1158 1145 1159 void __setup_vector_irq(int cpu)