aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r--kernel/cpu.c69
1 files changed, 47 insertions, 22 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 41a6cb85c0af..15a413639abc 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -228,6 +228,43 @@ static int cpu_notify(unsigned long val, unsigned int cpu)
228 return __cpu_notify(val, cpu, -1, NULL); 228 return __cpu_notify(val, cpu, -1, NULL);
229} 229}
230 230
231/* Notifier wrappers for transitioning to state machine */
232static int notify_prepare(unsigned int cpu)
233{
234 int nr_calls = 0;
235 int ret;
236
237 ret = __cpu_notify(CPU_UP_PREPARE, cpu, -1, &nr_calls);
238 if (ret) {
239 nr_calls--;
240 printk(KERN_WARNING "%s: attempt to bring up CPU %u failed\n",
241 __func__, cpu);
242 __cpu_notify(CPU_UP_CANCELED, cpu, nr_calls, NULL);
243 }
244 return ret;
245}
246
247static int notify_online(unsigned int cpu)
248{
249 cpu_notify(CPU_ONLINE, cpu);
250 return 0;
251}
252
253static int bringup_cpu(unsigned int cpu)
254{
255 struct task_struct *idle = idle_thread_get(cpu);
256 int ret;
257
258 /* Arch-specific enabling code. */
259 ret = __cpu_up(cpu, idle);
260 if (ret) {
261 cpu_notify(CPU_UP_CANCELED, cpu);
262 return ret;
263 }
264 BUG_ON(!cpu_online(cpu));
265 return 0;
266}
267
231#ifdef CONFIG_HOTPLUG_CPU 268#ifdef CONFIG_HOTPLUG_CPU
232 269
233static void cpu_notify_nofail(unsigned long val, unsigned int cpu) 270static void cpu_notify_nofail(unsigned long val, unsigned int cpu)
@@ -481,7 +518,7 @@ void smpboot_thread_init(void)
481static int _cpu_up(unsigned int cpu, int tasks_frozen) 518static int _cpu_up(unsigned int cpu, int tasks_frozen)
482{ 519{
483 struct task_struct *idle; 520 struct task_struct *idle;
484 int ret, nr_calls = 0; 521 int ret;
485 522
486 cpu_hotplug_begin(); 523 cpu_hotplug_begin();
487 524
@@ -496,33 +533,21 @@ static int _cpu_up(unsigned int cpu, int tasks_frozen)
496 goto out; 533 goto out;
497 } 534 }
498 535
536 cpuhp_tasks_frozen = tasks_frozen;
537
499 ret = smpboot_create_threads(cpu); 538 ret = smpboot_create_threads(cpu);
500 if (ret) 539 if (ret)
501 goto out; 540 goto out;
502 541
503 cpuhp_tasks_frozen = tasks_frozen; 542 ret = notify_prepare(cpu);
504 543 if (ret)
505 ret = __cpu_notify(CPU_UP_PREPARE, cpu, -1, &nr_calls); 544 goto out;
506 if (ret) {
507 nr_calls--;
508 pr_warn("%s: attempt to bring up CPU %u failed\n",
509 __func__, cpu);
510 goto out_notify;
511 }
512
513 /* Arch-specific enabling code. */
514 ret = __cpu_up(cpu, idle);
515
516 if (ret != 0)
517 goto out_notify;
518 BUG_ON(!cpu_online(cpu));
519 545
520 /* Now call notifier in preparation. */ 546 ret = bringup_cpu(cpu);
521 cpu_notify(CPU_ONLINE, cpu); 547 if (ret)
548 goto out;
522 549
523out_notify: 550 notify_online(cpu);
524 if (ret != 0)
525 __cpu_notify(CPU_UP_CANCELED, cpu, nr_calls, NULL);
526out: 551out:
527 cpu_hotplug_done(); 552 cpu_hotplug_done();
528 553