diff options
author | Fernando Luis [** ISO-8859-1 charset **] VázquezCao <fernando@oss.ntt.co.jp> | 2007-05-02 13:27:18 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2007-05-02 13:27:18 -0400 |
commit | 45ae5e968ea01d8326833ca2863cec5183ce1930 (patch) | |
tree | 63b3146cac6f725f7f7ae0c4044e218b7af9bd2b /arch/i386 | |
parent | 3144c332fa2ee4c4b9804aae5fe31098f04bffd9 (diff) |
[PATCH] i386: __send_IPI_dest_field - i386
Implement __send_IPI_dest_field which can be used to send IPIs when the
"destination shorthand" field of the ICR is set to 00 (destination
field). Use it whenever possible.
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/kernel/smp.c | 47 |
1 files changed, 18 insertions, 29 deletions
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 892cd64130bc..d14ffe2109b8 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c | |||
@@ -165,16 +165,13 @@ void fastcall send_IPI_self(int vector) | |||
165 | } | 165 | } |
166 | 166 | ||
167 | /* | 167 | /* |
168 | * This is only used on smaller machines. | 168 | * This is used to send an IPI with no shorthand notation (the destination is |
169 | * specified in bits 56 to 63 of the ICR). | ||
169 | */ | 170 | */ |
170 | void send_IPI_mask_bitmask(cpumask_t cpumask, int vector) | 171 | static inline void __send_IPI_dest_field(unsigned long mask, int vector) |
171 | { | 172 | { |
172 | unsigned long mask = cpus_addr(cpumask)[0]; | ||
173 | unsigned long cfg; | 173 | unsigned long cfg; |
174 | unsigned long flags; | ||
175 | 174 | ||
176 | local_irq_save(flags); | ||
177 | WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]); | ||
178 | /* | 175 | /* |
179 | * Wait for idle. | 176 | * Wait for idle. |
180 | */ | 177 | */ |
@@ -195,13 +192,25 @@ void send_IPI_mask_bitmask(cpumask_t cpumask, int vector) | |||
195 | * Send the IPI. The write to APIC_ICR fires this off. | 192 | * Send the IPI. The write to APIC_ICR fires this off. |
196 | */ | 193 | */ |
197 | apic_write_around(APIC_ICR, cfg); | 194 | apic_write_around(APIC_ICR, cfg); |
195 | } | ||
198 | 196 | ||
197 | /* | ||
198 | * This is only used on smaller machines. | ||
199 | */ | ||
200 | void send_IPI_mask_bitmask(cpumask_t cpumask, int vector) | ||
201 | { | ||
202 | unsigned long mask = cpus_addr(cpumask)[0]; | ||
203 | unsigned long flags; | ||
204 | |||
205 | local_irq_save(flags); | ||
206 | WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]); | ||
207 | __send_IPI_dest_field(mask, vector); | ||
199 | local_irq_restore(flags); | 208 | local_irq_restore(flags); |
200 | } | 209 | } |
201 | 210 | ||
202 | void send_IPI_mask_sequence(cpumask_t mask, int vector) | 211 | void send_IPI_mask_sequence(cpumask_t mask, int vector) |
203 | { | 212 | { |
204 | unsigned long cfg, flags; | 213 | unsigned long flags; |
205 | unsigned int query_cpu; | 214 | unsigned int query_cpu; |
206 | 215 | ||
207 | /* | 216 | /* |
@@ -211,30 +220,10 @@ void send_IPI_mask_sequence(cpumask_t mask, int vector) | |||
211 | */ | 220 | */ |
212 | 221 | ||
213 | local_irq_save(flags); | 222 | local_irq_save(flags); |
214 | |||
215 | for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) { | 223 | for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) { |
216 | if (cpu_isset(query_cpu, mask)) { | 224 | if (cpu_isset(query_cpu, mask)) { |
217 | 225 | __send_IPI_dest_field(cpu_to_logical_apicid(query_cpu), | |
218 | /* | 226 | vector); |
219 | * Wait for idle. | ||
220 | */ | ||
221 | apic_wait_icr_idle(); | ||
222 | |||
223 | /* | ||
224 | * prepare target chip field | ||
225 | */ | ||
226 | cfg = __prepare_ICR2(cpu_to_logical_apicid(query_cpu)); | ||
227 | apic_write_around(APIC_ICR2, cfg); | ||
228 | |||
229 | /* | ||
230 | * program the ICR | ||
231 | */ | ||
232 | cfg = __prepare_ICR(0, vector); | ||
233 | |||
234 | /* | ||
235 | * Send the IPI. The write to APIC_ICR fires this off. | ||
236 | */ | ||
237 | apic_write_around(APIC_ICR, cfg); | ||
238 | } | 227 | } |
239 | } | 228 | } |
240 | local_irq_restore(flags); | 229 | local_irq_restore(flags); |