diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-07-15 21:07:59 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-07-15 21:07:59 -0400 |
commit | 84c3d4aaec3338201b449034beac41635866bddf (patch) | |
tree | 3412951682fb2dd4feb8a5532f8efbaf8b345933 /arch/sh/kernel | |
parent | 43d2548bb2ef7e6d753f91468a746784041e522d (diff) | |
parent | fafa3a3f16723997f039a0193997464d66dafd8f (diff) |
Merge commit 'origin/master'
Manual merge of:
arch/powerpc/Kconfig
arch/powerpc/kernel/stacktrace.c
arch/powerpc/mm/slice.c
arch/ppc/kernel/smp.c
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/smp.c | 62 | ||||
-rw-r--r-- | arch/sh/kernel/stacktrace.c | 1 |
2 files changed, 16 insertions, 47 deletions
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 5d039d168f57..60c50841143e 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c | |||
@@ -36,13 +36,6 @@ EXPORT_SYMBOL(cpu_possible_map); | |||
36 | cpumask_t cpu_online_map; | 36 | cpumask_t cpu_online_map; |
37 | EXPORT_SYMBOL(cpu_online_map); | 37 | EXPORT_SYMBOL(cpu_online_map); |
38 | 38 | ||
39 | static atomic_t cpus_booted = ATOMIC_INIT(0); | ||
40 | |||
41 | /* | ||
42 | * Run specified function on a particular processor. | ||
43 | */ | ||
44 | void __smp_call_function(unsigned int cpu); | ||
45 | |||
46 | static inline void __init smp_store_cpu_info(unsigned int cpu) | 39 | static inline void __init smp_store_cpu_info(unsigned int cpu) |
47 | { | 40 | { |
48 | struct sh_cpuinfo *c = cpu_data + cpu; | 41 | struct sh_cpuinfo *c = cpu_data + cpu; |
@@ -175,45 +168,20 @@ static void stop_this_cpu(void *unused) | |||
175 | 168 | ||
176 | void smp_send_stop(void) | 169 | void smp_send_stop(void) |
177 | { | 170 | { |
178 | smp_call_function(stop_this_cpu, 0, 1, 0); | 171 | smp_call_function(stop_this_cpu, 0, 0); |
179 | } | 172 | } |
180 | 173 | ||
181 | struct smp_fn_call_struct smp_fn_call = { | 174 | void arch_send_call_function_ipi(cpumask_t mask) |
182 | .lock = __SPIN_LOCK_UNLOCKED(smp_fn_call.lock), | ||
183 | .finished = ATOMIC_INIT(0), | ||
184 | }; | ||
185 | |||
186 | /* | ||
187 | * The caller of this wants the passed function to run on every cpu. If wait | ||
188 | * is set, wait until all cpus have finished the function before returning. | ||
189 | * The lock is here to protect the call structure. | ||
190 | * You must not call this function with disabled interrupts or from a | ||
191 | * hardware interrupt handler or from a bottom half handler. | ||
192 | */ | ||
193 | int smp_call_function(void (*func)(void *info), void *info, int retry, int wait) | ||
194 | { | 175 | { |
195 | unsigned int nr_cpus = atomic_read(&cpus_booted); | 176 | int cpu; |
196 | int i; | ||
197 | |||
198 | /* Can deadlock when called with interrupts disabled */ | ||
199 | WARN_ON(irqs_disabled()); | ||
200 | |||
201 | spin_lock(&smp_fn_call.lock); | ||
202 | |||
203 | atomic_set(&smp_fn_call.finished, 0); | ||
204 | smp_fn_call.fn = func; | ||
205 | smp_fn_call.data = info; | ||
206 | |||
207 | for (i = 0; i < nr_cpus; i++) | ||
208 | if (i != smp_processor_id()) | ||
209 | plat_send_ipi(i, SMP_MSG_FUNCTION); | ||
210 | |||
211 | if (wait) | ||
212 | while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1)); | ||
213 | 177 | ||
214 | spin_unlock(&smp_fn_call.lock); | 178 | for_each_cpu_mask(cpu, mask) |
179 | plat_send_ipi(cpu, SMP_MSG_FUNCTION); | ||
180 | } | ||
215 | 181 | ||
216 | return 0; | 182 | void arch_send_call_function_single_ipi(int cpu) |
183 | { | ||
184 | plat_send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE); | ||
217 | } | 185 | } |
218 | 186 | ||
219 | /* Not really SMP stuff ... */ | 187 | /* Not really SMP stuff ... */ |
@@ -229,7 +197,7 @@ static void flush_tlb_all_ipi(void *info) | |||
229 | 197 | ||
230 | void flush_tlb_all(void) | 198 | void flush_tlb_all(void) |
231 | { | 199 | { |
232 | on_each_cpu(flush_tlb_all_ipi, 0, 1, 1); | 200 | on_each_cpu(flush_tlb_all_ipi, 0, 1); |
233 | } | 201 | } |
234 | 202 | ||
235 | static void flush_tlb_mm_ipi(void *mm) | 203 | static void flush_tlb_mm_ipi(void *mm) |
@@ -255,7 +223,7 @@ void flush_tlb_mm(struct mm_struct *mm) | |||
255 | preempt_disable(); | 223 | preempt_disable(); |
256 | 224 | ||
257 | if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { | 225 | if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { |
258 | smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1); | 226 | smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1); |
259 | } else { | 227 | } else { |
260 | int i; | 228 | int i; |
261 | for (i = 0; i < num_online_cpus(); i++) | 229 | for (i = 0; i < num_online_cpus(); i++) |
@@ -292,7 +260,7 @@ void flush_tlb_range(struct vm_area_struct *vma, | |||
292 | fd.vma = vma; | 260 | fd.vma = vma; |
293 | fd.addr1 = start; | 261 | fd.addr1 = start; |
294 | fd.addr2 = end; | 262 | fd.addr2 = end; |
295 | smp_call_function(flush_tlb_range_ipi, (void *)&fd, 1, 1); | 263 | smp_call_function(flush_tlb_range_ipi, (void *)&fd, 1); |
296 | } else { | 264 | } else { |
297 | int i; | 265 | int i; |
298 | for (i = 0; i < num_online_cpus(); i++) | 266 | for (i = 0; i < num_online_cpus(); i++) |
@@ -316,7 +284,7 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end) | |||
316 | 284 | ||
317 | fd.addr1 = start; | 285 | fd.addr1 = start; |
318 | fd.addr2 = end; | 286 | fd.addr2 = end; |
319 | on_each_cpu(flush_tlb_kernel_range_ipi, (void *)&fd, 1, 1); | 287 | on_each_cpu(flush_tlb_kernel_range_ipi, (void *)&fd, 1); |
320 | } | 288 | } |
321 | 289 | ||
322 | static void flush_tlb_page_ipi(void *info) | 290 | static void flush_tlb_page_ipi(void *info) |
@@ -335,7 +303,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
335 | 303 | ||
336 | fd.vma = vma; | 304 | fd.vma = vma; |
337 | fd.addr1 = page; | 305 | fd.addr1 = page; |
338 | smp_call_function(flush_tlb_page_ipi, (void *)&fd, 1, 1); | 306 | smp_call_function(flush_tlb_page_ipi, (void *)&fd, 1); |
339 | } else { | 307 | } else { |
340 | int i; | 308 | int i; |
341 | for (i = 0; i < num_online_cpus(); i++) | 309 | for (i = 0; i < num_online_cpus(); i++) |
@@ -359,6 +327,6 @@ void flush_tlb_one(unsigned long asid, unsigned long vaddr) | |||
359 | fd.addr1 = asid; | 327 | fd.addr1 = asid; |
360 | fd.addr2 = vaddr; | 328 | fd.addr2 = vaddr; |
361 | 329 | ||
362 | smp_call_function(flush_tlb_one_ipi, (void *)&fd, 1, 1); | 330 | smp_call_function(flush_tlb_one_ipi, (void *)&fd, 1); |
363 | local_flush_tlb_one(asid, vaddr); | 331 | local_flush_tlb_one(asid, vaddr); |
364 | } | 332 | } |
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c index d41e561be20e..1b2ae35c4a76 100644 --- a/arch/sh/kernel/stacktrace.c +++ b/arch/sh/kernel/stacktrace.c | |||
@@ -34,3 +34,4 @@ void save_stack_trace(struct stack_trace *trace) | |||
34 | } | 34 | } |
35 | } | 35 | } |
36 | } | 36 | } |
37 | EXPORT_SYMBOL_GPL(save_stack_trace); | ||