aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
-rw-r--r--arch/powerpc/kernel/smp.c318
1 files changed, 214 insertions, 104 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 0008bc58e826..8ebc6700b98d 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -57,6 +57,25 @@
57#define DBG(fmt...) 57#define DBG(fmt...)
58#endif 58#endif
59 59
60
61/* Store all idle threads, this can be reused instead of creating
62* a new thread. Also avoids complicated thread destroy functionality
63* for idle threads.
64*/
65#ifdef CONFIG_HOTPLUG_CPU
66/*
67 * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
68 * removed after init for !CONFIG_HOTPLUG_CPU.
69 */
70static DEFINE_PER_CPU(struct task_struct *, idle_thread_array);
71#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x))
72#define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p))
73#else
74static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
75#define get_idle_for_cpu(x) (idle_thread_array[(x)])
76#define set_idle_for_cpu(x, p) (idle_thread_array[(x)] = (p))
77#endif
78
60struct thread_info *secondary_ti; 79struct thread_info *secondary_ti;
61 80
62DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); 81DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
@@ -76,7 +95,7 @@ int smt_enabled_at_boot = 1;
76static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL; 95static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL;
77 96
78#ifdef CONFIG_PPC64 97#ifdef CONFIG_PPC64
79void __devinit smp_generic_kick_cpu(int nr) 98int __devinit smp_generic_kick_cpu(int nr)
80{ 99{
81 BUG_ON(nr < 0 || nr >= NR_CPUS); 100 BUG_ON(nr < 0 || nr >= NR_CPUS);
82 101
@@ -87,37 +106,10 @@ void __devinit smp_generic_kick_cpu(int nr)
87 */ 106 */
88 paca[nr].cpu_start = 1; 107 paca[nr].cpu_start = 1;
89 smp_mb(); 108 smp_mb();
90}
91#endif
92 109
93void smp_message_recv(int msg) 110 return 0;
94{
95 switch(msg) {
96 case PPC_MSG_CALL_FUNCTION:
97 generic_smp_call_function_interrupt();
98 break;
99 case PPC_MSG_RESCHEDULE:
100 /* we notice need_resched on exit */
101 break;
102 case PPC_MSG_CALL_FUNC_SINGLE:
103 generic_smp_call_function_single_interrupt();
104 break;
105 case PPC_MSG_DEBUGGER_BREAK:
106 if (crash_ipi_function_ptr) {
107 crash_ipi_function_ptr(get_irq_regs());
108 break;
109 }
110#ifdef CONFIG_DEBUGGER
111 debugger_ipi(get_irq_regs());
112 break;
113#endif /* CONFIG_DEBUGGER */
114 /* FALLTHROUGH */
115 default:
116 printk("SMP %d: smp_message_recv(): unknown msg %d\n",
117 smp_processor_id(), msg);
118 break;
119 }
120} 111}
112#endif
121 113
122static irqreturn_t call_function_action(int irq, void *data) 114static irqreturn_t call_function_action(int irq, void *data)
123{ 115{
@@ -127,7 +119,7 @@ static irqreturn_t call_function_action(int irq, void *data)
127 119
128static irqreturn_t reschedule_action(int irq, void *data) 120static irqreturn_t reschedule_action(int irq, void *data)
129{ 121{
130 /* we just need the return path side effect of checking need_resched */ 122 scheduler_ipi();
131 return IRQ_HANDLED; 123 return IRQ_HANDLED;
132} 124}
133 125
@@ -139,7 +131,15 @@ static irqreturn_t call_function_single_action(int irq, void *data)
139 131
140static irqreturn_t debug_ipi_action(int irq, void *data) 132static irqreturn_t debug_ipi_action(int irq, void *data)
141{ 133{
142 smp_message_recv(PPC_MSG_DEBUGGER_BREAK); 134 if (crash_ipi_function_ptr) {
135 crash_ipi_function_ptr(get_irq_regs());
136 return IRQ_HANDLED;
137 }
138
139#ifdef CONFIG_DEBUGGER
140 debugger_ipi(get_irq_regs());
141#endif /* CONFIG_DEBUGGER */
142
143 return IRQ_HANDLED; 143 return IRQ_HANDLED;
144} 144}
145 145
@@ -178,6 +178,66 @@ int smp_request_message_ipi(int virq, int msg)
178 return err; 178 return err;
179} 179}
180 180
181#ifdef CONFIG_PPC_SMP_MUXED_IPI
182struct cpu_messages {
183 int messages; /* current messages */
184 unsigned long data; /* data for cause ipi */
185};
186static DEFINE_PER_CPU_SHARED_ALIGNED(struct cpu_messages, ipi_message);
187
188void smp_muxed_ipi_set_data(int cpu, unsigned long data)
189{
190 struct cpu_messages *info = &per_cpu(ipi_message, cpu);
191
192 info->data = data;
193}
194
195void smp_muxed_ipi_message_pass(int cpu, int msg)
196{
197 struct cpu_messages *info = &per_cpu(ipi_message, cpu);
198 char *message = (char *)&info->messages;
199
200 message[msg] = 1;
201 mb();
202 smp_ops->cause_ipi(cpu, info->data);
203}
204
205void smp_muxed_ipi_resend(void)
206{
207 struct cpu_messages *info = &__get_cpu_var(ipi_message);
208
209 if (info->messages)
210 smp_ops->cause_ipi(smp_processor_id(), info->data);
211}
212
213irqreturn_t smp_ipi_demux(void)
214{
215 struct cpu_messages *info = &__get_cpu_var(ipi_message);
216 unsigned int all;
217
218 mb(); /* order any irq clear */
219
220 do {
221 all = xchg_local(&info->messages, 0);
222
223#ifdef __BIG_ENDIAN
224 if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNCTION)))
225 generic_smp_call_function_interrupt();
226 if (all & (1 << (24 - 8 * PPC_MSG_RESCHEDULE)))
227 scheduler_ipi();
228 if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNC_SINGLE)))
229 generic_smp_call_function_single_interrupt();
230 if (all & (1 << (24 - 8 * PPC_MSG_DEBUGGER_BREAK)))
231 debug_ipi_action(0, NULL);
232#else
233#error Unsupported ENDIAN
234#endif
235 } while (info->messages);
236
237 return IRQ_HANDLED;
238}
239#endif /* CONFIG_PPC_SMP_MUXED_IPI */
240
181void smp_send_reschedule(int cpu) 241void smp_send_reschedule(int cpu)
182{ 242{
183 if (likely(smp_ops)) 243 if (likely(smp_ops))
@@ -197,11 +257,18 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
197 smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNCTION); 257 smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNCTION);
198} 258}
199 259
200#ifdef CONFIG_DEBUGGER 260#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
201void smp_send_debugger_break(int cpu) 261void smp_send_debugger_break(void)
202{ 262{
203 if (likely(smp_ops)) 263 int cpu;
204 smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK); 264 int me = raw_smp_processor_id();
265
266 if (unlikely(!smp_ops))
267 return;
268
269 for_each_online_cpu(cpu)
270 if (cpu != me)
271 smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK);
205} 272}
206#endif 273#endif
207 274
@@ -209,9 +276,9 @@ void smp_send_debugger_break(int cpu)
209void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) 276void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
210{ 277{
211 crash_ipi_function_ptr = crash_ipi_callback; 278 crash_ipi_function_ptr = crash_ipi_callback;
212 if (crash_ipi_callback && smp_ops) { 279 if (crash_ipi_callback) {
213 mb(); 280 mb();
214 smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK); 281 smp_send_debugger_break();
215 } 282 }
216} 283}
217#endif 284#endif
@@ -238,23 +305,6 @@ static void __devinit smp_store_cpu_info(int id)
238 per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR); 305 per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR);
239} 306}
240 307
241static void __init smp_create_idle(unsigned int cpu)
242{
243 struct task_struct *p;
244
245 /* create a process for the processor */
246 p = fork_idle(cpu);
247 if (IS_ERR(p))
248 panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
249#ifdef CONFIG_PPC64
250 paca[cpu].__current = p;
251 paca[cpu].kstack = (unsigned long) task_thread_info(p)
252 + THREAD_SIZE - STACK_FRAME_OVERHEAD;
253#endif
254 current_set[cpu] = task_thread_info(p);
255 task_thread_info(p)->cpu = cpu;
256}
257
258void __init smp_prepare_cpus(unsigned int max_cpus) 308void __init smp_prepare_cpus(unsigned int max_cpus)
259{ 309{
260 unsigned int cpu; 310 unsigned int cpu;
@@ -288,10 +338,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
288 max_cpus = NR_CPUS; 338 max_cpus = NR_CPUS;
289 else 339 else
290 max_cpus = 1; 340 max_cpus = 1;
291
292 for_each_possible_cpu(cpu)
293 if (cpu != boot_cpuid)
294 smp_create_idle(cpu);
295} 341}
296 342
297void __devinit smp_prepare_boot_cpu(void) 343void __devinit smp_prepare_boot_cpu(void)
@@ -305,7 +351,7 @@ void __devinit smp_prepare_boot_cpu(void)
305 351
306#ifdef CONFIG_HOTPLUG_CPU 352#ifdef CONFIG_HOTPLUG_CPU
307/* State of each CPU during hotplug phases */ 353/* State of each CPU during hotplug phases */
308DEFINE_PER_CPU(int, cpu_state) = { 0 }; 354static DEFINE_PER_CPU(int, cpu_state) = { 0 };
309 355
310int generic_cpu_disable(void) 356int generic_cpu_disable(void)
311{ 357{
@@ -317,30 +363,8 @@ int generic_cpu_disable(void)
317 set_cpu_online(cpu, false); 363 set_cpu_online(cpu, false);
318#ifdef CONFIG_PPC64 364#ifdef CONFIG_PPC64
319 vdso_data->processorCount--; 365 vdso_data->processorCount--;
320 fixup_irqs(cpu_online_mask);
321#endif
322 return 0;
323}
324
325int generic_cpu_enable(unsigned int cpu)
326{
327 /* Do the normal bootup if we haven't
328 * already bootstrapped. */
329 if (system_state != SYSTEM_RUNNING)
330 return -ENOSYS;
331
332 /* get the target out of it's holding state */
333 per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
334 smp_wmb();
335
336 while (!cpu_online(cpu))
337 cpu_relax();
338
339#ifdef CONFIG_PPC64
340 fixup_irqs(cpu_online_mask);
341 /* counter the irq disable in fixup_irqs */
342 local_irq_enable();
343#endif 366#endif
367 migrate_irqs();
344 return 0; 368 return 0;
345} 369}
346 370
@@ -362,37 +386,89 @@ void generic_mach_cpu_die(void)
362 unsigned int cpu; 386 unsigned int cpu;
363 387
364 local_irq_disable(); 388 local_irq_disable();
389 idle_task_exit();
365 cpu = smp_processor_id(); 390 cpu = smp_processor_id();
366 printk(KERN_DEBUG "CPU%d offline\n", cpu); 391 printk(KERN_DEBUG "CPU%d offline\n", cpu);
367 __get_cpu_var(cpu_state) = CPU_DEAD; 392 __get_cpu_var(cpu_state) = CPU_DEAD;
368 smp_wmb(); 393 smp_wmb();
369 while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) 394 while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
370 cpu_relax(); 395 cpu_relax();
371 set_cpu_online(cpu, true); 396}
372 local_irq_enable(); 397
398void generic_set_cpu_dead(unsigned int cpu)
399{
400 per_cpu(cpu_state, cpu) = CPU_DEAD;
373} 401}
374#endif 402#endif
375 403
376static int __devinit cpu_enable(unsigned int cpu) 404struct create_idle {
405 struct work_struct work;
406 struct task_struct *idle;
407 struct completion done;
408 int cpu;
409};
410
411static void __cpuinit do_fork_idle(struct work_struct *work)
377{ 412{
378 if (smp_ops && smp_ops->cpu_enable) 413 struct create_idle *c_idle =
379 return smp_ops->cpu_enable(cpu); 414 container_of(work, struct create_idle, work);
380 415
381 return -ENOSYS; 416 c_idle->idle = fork_idle(c_idle->cpu);
417 complete(&c_idle->done);
382} 418}
383 419
384int __cpuinit __cpu_up(unsigned int cpu) 420static int __cpuinit create_idle(unsigned int cpu)
385{ 421{
386 int c; 422 struct thread_info *ti;
423 struct create_idle c_idle = {
424 .cpu = cpu,
425 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
426 };
427 INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
387 428
388 secondary_ti = current_set[cpu]; 429 c_idle.idle = get_idle_for_cpu(cpu);
389 if (!cpu_enable(cpu)) 430
390 return 0; 431 /* We can't use kernel_thread since we must avoid to
432 * reschedule the child. We use a workqueue because
433 * we want to fork from a kernel thread, not whatever
434 * userspace process happens to be trying to online us.
435 */
436 if (!c_idle.idle) {
437 schedule_work(&c_idle.work);
438 wait_for_completion(&c_idle.done);
439 } else
440 init_idle(c_idle.idle, cpu);
441 if (IS_ERR(c_idle.idle)) {
442 pr_err("Failed fork for CPU %u: %li", cpu, PTR_ERR(c_idle.idle));
443 return PTR_ERR(c_idle.idle);
444 }
445 ti = task_thread_info(c_idle.idle);
446
447#ifdef CONFIG_PPC64
448 paca[cpu].__current = c_idle.idle;
449 paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD;
450#endif
451 ti->cpu = cpu;
452 current_set[cpu] = ti;
453
454 return 0;
455}
456
457int __cpuinit __cpu_up(unsigned int cpu)
458{
459 int rc, c;
391 460
392 if (smp_ops == NULL || 461 if (smp_ops == NULL ||
393 (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))) 462 (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
394 return -EINVAL; 463 return -EINVAL;
395 464
465 /* Make sure we have an idle thread */
466 rc = create_idle(cpu);
467 if (rc)
468 return rc;
469
470 secondary_ti = current_set[cpu];
471
396 /* Make sure callin-map entry is 0 (can be leftover a CPU 472 /* Make sure callin-map entry is 0 (can be leftover a CPU
397 * hotplug 473 * hotplug
398 */ 474 */
@@ -406,7 +482,11 @@ int __cpuinit __cpu_up(unsigned int cpu)
406 482
407 /* wake up cpus */ 483 /* wake up cpus */
408 DBG("smp: kicking cpu %d\n", cpu); 484 DBG("smp: kicking cpu %d\n", cpu);
409 smp_ops->kick_cpu(cpu); 485 rc = smp_ops->kick_cpu(cpu);
486 if (rc) {
487 pr_err("smp: failed starting cpu %d (rc %d)\n", cpu, rc);
488 return rc;
489 }
410 490
411 /* 491 /*
412 * wait to see if the cpu made a callin (is actually up). 492 * wait to see if the cpu made a callin (is actually up).
@@ -466,6 +546,19 @@ out:
466 return id; 546 return id;
467} 547}
468 548
549/* Helper routines for cpu to core mapping */
550int cpu_core_index_of_thread(int cpu)
551{
552 return cpu >> threads_shift;
553}
554EXPORT_SYMBOL_GPL(cpu_core_index_of_thread);
555
556int cpu_first_thread_of_core(int core)
557{
558 return core << threads_shift;
559}
560EXPORT_SYMBOL_GPL(cpu_first_thread_of_core);
561
469/* Must be called when no change can occur to cpu_present_mask, 562/* Must be called when no change can occur to cpu_present_mask,
470 * i.e. during cpu online or offline. 563 * i.e. during cpu online or offline.
471 */ 564 */
@@ -489,7 +582,7 @@ static struct device_node *cpu_to_l2cache(int cpu)
489} 582}
490 583
491/* Activate a secondary processor. */ 584/* Activate a secondary processor. */
492int __devinit start_secondary(void *unused) 585void __devinit start_secondary(void *unused)
493{ 586{
494 unsigned int cpu = smp_processor_id(); 587 unsigned int cpu = smp_processor_id();
495 struct device_node *l2_cache; 588 struct device_node *l2_cache;
@@ -508,16 +601,17 @@ int __devinit start_secondary(void *unused)
508 if (smp_ops->take_timebase) 601 if (smp_ops->take_timebase)
509 smp_ops->take_timebase(); 602 smp_ops->take_timebase();
510 603
511 if (system_state > SYSTEM_BOOTING)
512 snapshot_timebase();
513
514 secondary_cpu_time_init(); 604 secondary_cpu_time_init();
515 605
606#ifdef CONFIG_PPC64
607 if (system_state == SYSTEM_RUNNING)
608 vdso_data->processorCount++;
609#endif
516 ipi_call_lock(); 610 ipi_call_lock();
517 notify_cpu_starting(cpu); 611 notify_cpu_starting(cpu);
518 set_cpu_online(cpu, true); 612 set_cpu_online(cpu, true);
519 /* Update sibling maps */ 613 /* Update sibling maps */
520 base = cpu_first_thread_in_core(cpu); 614 base = cpu_first_thread_sibling(cpu);
521 for (i = 0; i < threads_per_core; i++) { 615 for (i = 0; i < threads_per_core; i++) {
522 if (cpu_is_offline(base + i)) 616 if (cpu_is_offline(base + i))
523 continue; 617 continue;
@@ -548,7 +642,8 @@ int __devinit start_secondary(void *unused)
548 local_irq_enable(); 642 local_irq_enable();
549 643
550 cpu_idle(); 644 cpu_idle();
551 return 0; 645
646 BUG();
552} 647}
553 648
554int setup_profiling_timer(unsigned int multiplier) 649int setup_profiling_timer(unsigned int multiplier)
@@ -565,7 +660,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
565 * se we pin us down to CPU 0 for a short while 660 * se we pin us down to CPU 0 for a short while
566 */ 661 */
567 alloc_cpumask_var(&old_mask, GFP_NOWAIT); 662 alloc_cpumask_var(&old_mask, GFP_NOWAIT);
568 cpumask_copy(old_mask, &current->cpus_allowed); 663 cpumask_copy(old_mask, tsk_cpus_allowed(current));
569 set_cpus_allowed_ptr(current, cpumask_of(boot_cpuid)); 664 set_cpus_allowed_ptr(current, cpumask_of(boot_cpuid));
570 665
571 if (smp_ops && smp_ops->setup_cpu) 666 if (smp_ops && smp_ops->setup_cpu)
@@ -575,9 +670,20 @@ void __init smp_cpus_done(unsigned int max_cpus)
575 670
576 free_cpumask_var(old_mask); 671 free_cpumask_var(old_mask);
577 672
578 snapshot_timebases(); 673 if (smp_ops && smp_ops->bringup_done)
674 smp_ops->bringup_done();
579 675
580 dump_numa_cpu_topology(); 676 dump_numa_cpu_topology();
677
678}
679
680int arch_sd_sibling_asym_packing(void)
681{
682 if (cpu_has_feature(CPU_FTR_ASYM_SMT)) {
683 printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n");
684 return SD_ASYM_PACKING;
685 }
686 return 0;
581} 687}
582 688
583#ifdef CONFIG_HOTPLUG_CPU 689#ifdef CONFIG_HOTPLUG_CPU
@@ -596,7 +702,7 @@ int __cpu_disable(void)
596 return err; 702 return err;
597 703
598 /* Update sibling maps */ 704 /* Update sibling maps */
599 base = cpu_first_thread_in_core(cpu); 705 base = cpu_first_thread_sibling(cpu);
600 for (i = 0; i < threads_per_core; i++) { 706 for (i = 0; i < threads_per_core; i++) {
601 cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i)); 707 cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i));
602 cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu)); 708 cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu));
@@ -643,5 +749,9 @@ void cpu_die(void)
643{ 749{
644 if (ppc_md.cpu_die) 750 if (ppc_md.cpu_die)
645 ppc_md.cpu_die(); 751 ppc_md.cpu_die();
752
753 /* If we return, we re-enter start_secondary */
754 start_secondary_resume();
646} 755}
756
647#endif 757#endif