diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index b000017..3989fa5 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -624,11 +624,32 @@ static int __assign_irq_vector(int irq, if (irq_vector[irq] > 0) old_vector = irq_vector[irq]; if (old_vector > 0) { + cpumask_t domain, new_mask, old_mask; + int new_cpu, old_cpu; cpus_and(*result, irq_domain[irq], mask); if (!cpus_empty(*result)) return old_vector; + + /* try to reuse vector for phys flat */ + domain = vector_allocation_domain(cpu); + cpus_and(new_mask, domain, cpu_online_map); + for_each_cpu_mask(new_cpu, new_mask) + if (per_cpu(vector_irq, new_cpu)[old_vector] != -1) + goto new_vector; + /* We can reuse it */ + cpus_and(old_mask, irq_domain[irq], cpu_online_map); + for_each_cpu_mask(old_cpu, old_mask); + per_cpu(vector_irq, old_cpu)[old_vector] = -1; + for_each_cpu_mask(new_cpu, new_mask) + per_cpu(vector_irq, new_cpu)[old_vector] = irq; + irq_domain[irq] = domain; + cpus_and(*result, domain, mask); + return old_vector; + } +new_vector: + for_each_cpu_mask(cpu, mask) { cpumask_t domain; int first, new_cpu;