CRED: Fix a race in creds_are_invalid() in credentials debugging
[safe/jmp/linux-2.6] / kernel / cpu.c
index 7c4e271..25bba73 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kthread.h>
 #include <linux/stop_machine.h>
 #include <linux/mutex.h>
+#include <linux/gfp.h>
 
 #ifdef CONFIG_SMP
 /* Serializes the updates to cpu_online_mask, cpu_present_mask */
@@ -151,13 +152,13 @@ static inline void check_for_tasks(int cpu)
 
        write_lock_irq(&tasklist_lock);
        for_each_process(p) {
-               if (task_cpu(p) == cpu &&
+               if (task_cpu(p) == cpu && p->state == TASK_RUNNING &&
                    (!cputime_eq(p->utime, cputime_zero) ||
                     !cputime_eq(p->stime, cputime_zero)))
-                       printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d\
-                               (state = %ld, flags = %x) \n",
-                                p->comm, task_pid_nr(p), cpu,
-                                p->state, p->flags);
+                       printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d "
+                               "(state = %ld, flags = %x)\n",
+                               p->comm, task_pid_nr(p), cpu,
+                               p->state, p->flags);
        }
        write_unlock_irq(&tasklist_lock);
 }
@@ -209,9 +210,12 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
                return -ENOMEM;
 
        cpu_hotplug_begin();
+       set_cpu_active(cpu, false);
        err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
                                        hcpu, -1, &nr_calls);
        if (err == NOTIFY_BAD) {
+               set_cpu_active(cpu, true);
+
                nr_calls--;
                __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod,
                                          hcpu, nr_calls, NULL);
@@ -223,11 +227,11 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
 
        /* Ensure that we are not runnable on dying cpu */
        cpumask_copy(old_allowed, &current->cpus_allowed);
-       set_cpus_allowed_ptr(current,
-                            cpumask_of(cpumask_any_but(cpu_online_mask, cpu)));
+       set_cpus_allowed_ptr(current, cpu_active_mask);
 
        err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
        if (err) {
+               set_cpu_active(cpu, true);
                /* CPU didn't die: tell everyone.  Can't complain. */
                if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod,
                                            hcpu) == NOTIFY_BAD)
@@ -278,23 +282,8 @@ int __ref cpu_down(unsigned int cpu)
                goto out;
        }
 
-       set_cpu_active(cpu, false);
-
-       /*
-        * Make sure the all cpus did the reschedule and are not
-        * using stale version of the cpu_active_mask.
-        * This is not strictly necessary becuase stop_machine()
-        * that we run down the line already provides the required
-        * synchronization. But it's really a side effect and we do not
-        * want to depend on the innards of the stop_machine here.
-        */
-       synchronize_sched();
-
        err = _cpu_down(cpu, 0);
 
-       if (cpu_online(cpu))
-               set_cpu_active(cpu, true);
-
 out:
        cpu_maps_update_done();
        stop_machine_destroy();
@@ -350,7 +339,7 @@ int __cpuinit cpu_up(unsigned int cpu)
        if (!cpu_possible(cpu)) {
                printk(KERN_ERR "can't online cpu %d because it is not "
                        "configured as may-hotadd at boot time\n", cpu);
-#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
+#if defined(CONFIG_IA64)
                printk(KERN_ERR "please check additional_cpus= boot "
                                "parameter\n");
 #endif
@@ -383,10 +372,12 @@ int disable_nonboot_cpus(void)
                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
+       /*
+        * We take down all of the non-boot CPUs in one shot to avoid races
         * with the userspace trying to use the CPU hotplug at the same time
         */
        cpumask_clear(frozen_cpus);
+
        printk("Disabling non-boot CPUs ...\n");
        for_each_online_cpu(cpu) {
                if (cpu == first_cpu)