x86: Fix interrupt leak due to migration
PATCH 1/1 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.
arch/x86/kernel/io_apic.c +14 -0
@@ -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)
Signature · 4 lines
Matthew Wilcox Intel Open Source Technology Centre "Bill, look, we understand that you're interested in selling us this operating system, but compare it to ours. We can't possibly take such a retrograde step."
Quoted 11 lines · Matthew Wilcox
When we migrate an interrupt from one CPU to another, we set the
move_in_progressflag and clean up the vectors later once they're not being used. If you're unlucky and calldestroy_irq()before the vectors become un-used, themove_in_progressflag 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 <[email protected]>
We did some other quick testing on this and it seems good. Thanks and good work Matthew!