Skip to content

Commit

Permalink
x86: Fix interrupt leak due to migration
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Matthew Wilcox authored and Linus Torvalds committed Nov 20, 2008
1 parent 23918b0 commit 0ca4b6b
Showing 1 changed file with 14 additions and 0 deletions.
14 changes: 14 additions & 0 deletions arch/x86/kernel/io_apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,20 @@ static void __clear_irq_vector(int irq)

cfg->vector = 0;
cpus_clear(cfg->domain);

if (likely(!cfg->move_in_progress))
return;
cpus_and(mask, cfg->old_domain, cpu_online_map);
for_each_cpu_mask_nr(cpu, mask) {
for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS;
vector++) {
if (per_cpu(vector_irq, cpu)[vector] != irq)
continue;
per_cpu(vector_irq, cpu)[vector] = -1;
break;
}
}
cfg->move_in_progress = 0;
}

void __setup_vector_irq(int cpu)
Expand Down

0 comments on commit 0ca4b6b

Please sign in to comment.