diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index 74f7dd6f69b128..60bab79abbe503 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c @@ -155,14 +155,9 @@ static int __assign_irq_vector(int irq, struct apic_chip_data *d, vector = FIRST_EXTERNAL_VECTOR + offset; } - if (unlikely(current_vector == vector)) { - cpumask_or(searched_cpumask, searched_cpumask, - vector_cpumask); - cpumask_andnot(vector_cpumask, mask, searched_cpumask); - cpu = cpumask_first_and(vector_cpumask, - cpu_online_mask); - continue; - } + /* If the search wrapped around, try the next cpu */ + if (unlikely(current_vector == vector)) + goto next_cpu; if (test_bit(vector, used_vectors)) goto next; @@ -184,6 +179,19 @@ static int __assign_irq_vector(int irq, struct apic_chip_data *d, d->cfg.vector = vector; cpumask_copy(d->domain, vector_cpumask); goto success; + +next_cpu: + /* + * We exclude the current @vector_cpumask from the requested + * @mask and try again with the next online cpu in the + * result. We cannot modify @mask, so we use @vector_cpumask + * as a temporary buffer here as it will be reassigned when + * calling apic->vector_allocation_domain() above. + */ + cpumask_or(searched_cpumask, searched_cpumask, vector_cpumask); + cpumask_andnot(vector_cpumask, mask, searched_cpumask); + cpu = cpumask_first_and(vector_cpumask, cpu_online_mask); + continue; } return -ENOSPC;