diff options
-rw-r--r-- | arch/x86/kernel/apic/vector.c | 24 |
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 | |||
185 | next_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 | ||