futex: Move drop_futex_key_refs out of spinlock'ed region
[safe/jmp/linux-2.6] / kernel / cpu.c
index 30e74dd..6ba0f1e 100644 (file)
@@ -34,14 +34,11 @@ static struct {
         * an ongoing cpu hotplug operation.
         */
        int refcount;
-} cpu_hotplug;
-
-void __init cpu_hotplug_init(void)
-{
-       cpu_hotplug.active_writer = NULL;
-       mutex_init(&cpu_hotplug.lock);
-       cpu_hotplug.refcount = 0;
-}
+} cpu_hotplug = {
+       .active_writer = NULL,
+       .lock = __MUTEX_INITIALIZER(cpu_hotplug.lock),
+       .refcount = 0,
+};
 
 #ifdef CONFIG_HOTPLUG_CPU
 
@@ -281,7 +278,7 @@ int __ref cpu_down(unsigned int cpu)
                goto out;
        }
 
-       cpu_clear(cpu, cpu_active_map);
+       set_cpu_active(cpu, false);
 
        /*
         * Make sure the all cpus did the reschedule and are not
@@ -296,7 +293,7 @@ int __ref cpu_down(unsigned int cpu)
        err = _cpu_down(cpu, 0);
 
        if (cpu_online(cpu))
-               cpu_set(cpu, cpu_active_map);
+               set_cpu_active(cpu, true);
 
 out:
        cpu_maps_update_done();
@@ -333,7 +330,7 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
                goto out_notify;
        BUG_ON(!cpu_online(cpu));
 
-       cpu_set(cpu, cpu_active_map);
+       set_cpu_active(cpu, true);
 
        /* Now call notifier in preparation. */
        raw_notifier_call_chain(&cpu_chain, CPU_ONLINE | mod, hcpu);
@@ -379,8 +376,11 @@ static cpumask_var_t frozen_cpus;
 
 int disable_nonboot_cpus(void)
 {
-       int cpu, first_cpu, error = 0;
+       int cpu, first_cpu, error;
 
+       error = stop_machine_create();
+       if (error)
+               return error;
        cpu_maps_update_begin();
        first_cpu = cpumask_first(cpu_online_mask);
        /* We take down all of the non-boot CPUs in one shot to avoid races
@@ -401,6 +401,7 @@ int disable_nonboot_cpus(void)
                        break;
                }
        }
+
        if (!error) {
                BUG_ON(num_online_cpus() > 1);
                /* Make sure the CPUs won't be enabled by someone else */
@@ -409,9 +410,18 @@ int disable_nonboot_cpus(void)
                printk(KERN_ERR "Non-boot CPUs are not disabled\n");
        }
        cpu_maps_update_done();
+       stop_machine_destroy();
        return error;
 }
 
+void __weak arch_enable_nonboot_cpus_begin(void)
+{
+}
+
+void __weak arch_enable_nonboot_cpus_end(void)
+{
+}
+
 void __ref enable_nonboot_cpus(void)
 {
        int cpu, error;
@@ -423,6 +433,9 @@ void __ref enable_nonboot_cpus(void)
                goto out;
 
        printk("Enabling non-boot CPUs ...\n");
+
+       arch_enable_nonboot_cpus_begin();
+
        for_each_cpu(cpu, frozen_cpus) {
                error = _cpu_up(cpu, 1);
                if (!error) {
@@ -431,6 +444,9 @@ void __ref enable_nonboot_cpus(void)
                }
                printk(KERN_WARNING "Error taking CPU%d up: %d\n", cpu, error);
        }
+
+       arch_enable_nonboot_cpus_end();
+
        cpumask_clear(frozen_cpus);
 out:
        cpu_maps_update_done();