Split cpu_down in separate functions in preparation for state machine conversion. Signed-off-by: Thomas Gleixner --- kernel/cpu.c | 83 +++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 30 deletions(-) Index: linux-2.6/kernel/cpu.c =================================================================== --- linux-2.6.orig/kernel/cpu.c +++ linux-2.6/kernel/cpu.c @@ -206,11 +206,6 @@ static int bringup_cpu(unsigned int cpu) } #ifdef CONFIG_HOTPLUG_CPU - -static void cpu_notify_nofail(unsigned long val, unsigned int cpu) -{ - BUG_ON(cpu_notify(val, cpu)); -} EXPORT_SYMBOL(register_cpu_notifier); void __ref unregister_cpu_notifier(struct notifier_block *nb) @@ -278,6 +273,25 @@ static inline void check_for_tasks(int c write_unlock_irq(&tasklist_lock); } +static void cpu_notify_nofail(unsigned long val, unsigned int cpu) +{ + BUG_ON(cpu_notify(val, cpu)); +} + +static int notify_down_prepare(unsigned int cpu) +{ + int err, nr_calls = 0; + + err = __cpu_notify(CPU_DOWN_PREPARE, cpu, -1, &nr_calls); + if (err) { + nr_calls--; + __cpu_notify(CPU_DOWN_FAILED, cpu, nr_calls, NULL); + printk("%s: attempt to take down CPU %u failed\n", + __func__, cpu); + } + return err; +} + /* Take this CPU down. */ static int __ref take_cpu_down(void *_param) { @@ -294,37 +308,17 @@ static int __ref take_cpu_down(void *_pa return 0; } -/* Requires cpu_add_remove_lock to be held */ -static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) +static int takedown_cpu(unsigned int cpu) { - int err, nr_calls = 0; - - if (num_online_cpus() == 1) - return -EBUSY; - - if (!cpu_online(cpu)) - return -EINVAL; - - cpu_hotplug_begin(); - - cpuhp_tasks_frozen = tasks_frozen; + int err; - err = __cpu_notify(CPU_DOWN_PREPARE, cpu, -1, &nr_calls); - if (err) { - nr_calls--; - __cpu_notify(CPU_DOWN_FAILED, cpu, nr_calls, NULL); - printk("%s: attempt to take down CPU %u failed\n", - __func__, cpu); - goto out_release; - } smpboot_park_threads(cpu); - err = __stop_machine(take_cpu_down, NULL, cpumask_of(cpu)); if (err) { /* CPU didn't die: tell everyone. Can't complain. */ smpboot_unpark_threads(cpu); cpu_notify_nofail(CPU_DOWN_FAILED, cpu); - goto out_release; + return err; } BUG_ON(cpu_online(cpu)); @@ -341,10 +335,39 @@ static int __ref _cpu_down(unsigned int /* This actually kills the CPU. */ __cpu_die(cpu); - /* CPU is completely dead: tell everyone. Too late to complain. */ - cpu_notify_nofail(CPU_DEAD, cpu); + return 0; +} +static int notify_dead(unsigned int cpu) +{ + cpu_notify_nofail(CPU_DEAD, cpu); check_for_tasks(cpu); + return 0; +} + +/* Requires cpu_add_remove_lock to be held */ +static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) +{ + int err; + + if (num_online_cpus() == 1) + return -EBUSY; + + if (!cpu_online(cpu)) + return -EINVAL; + + cpu_hotplug_begin(); + + cpuhp_tasks_frozen = tasks_frozen; + + err = notify_down_prepare(cpu); + if (err) + goto out_release; + err = takedown_cpu(cpu); + if (err) + goto out_release; + + notify_dead(cpu); out_release: cpu_hotplug_done();