aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/apic/vector.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 613b1cd8eecb..cef31955ab18 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -157,14 +157,9 @@ next:
157 vector = FIRST_EXTERNAL_VECTOR + offset; 157 vector = FIRST_EXTERNAL_VECTOR + offset;
158 } 158 }
159 159
160 if (unlikely(current_vector == vector)) { 160 /* If the search wrapped around, try the next cpu */
161 cpumask_or(searched_cpumask, searched_cpumask, 161 if (unlikely(current_vector == vector))
162 vector_cpumask); 162 goto next_cpu;
163 cpumask_andnot(vector_cpumask, mask, searched_cpumask);
164 cpu = cpumask_first_and(vector_cpumask,
165 cpu_online_mask);
166 continue;
167 }
168 163
169 if (test_bit(vector, used_vectors)) 164 if (test_bit(vector, used_vectors))
170 goto next; 165 goto next;
@@ -186,6 +181,19 @@ next:
186 d->cfg.vector = vector; 181 d->cfg.vector = vector;
187 cpumask_copy(d->domain, vector_cpumask); 182 cpumask_copy(d->domain, vector_cpumask);
188 goto success; 183 goto success;
184
185next_cpu:
186 /*
187 * We exclude the current @vector_cpumask from the requested
188 * @mask and try again with the next online cpu in the
189 * result. We cannot modify @mask, so we use @vector_cpumask
190 * as a temporary buffer here as it will be reassigned when
191 * calling apic->vector_allocation_domain() above.
192 */
193 cpumask_or(searched_cpumask, searched_cpumask, vector_cpumask);
194 cpumask_andnot(vector_cpumask, mask, searched_cpumask);
195 cpu = cpumask_first_and(vector_cpumask, cpu_online_mask);
196 continue;
189 } 197 }
190 return -ENOSPC; 198 return -ENOSPC;
191 199