- patches.fixes/patch-2.6.11-rc1: 2.6.11-rc1.
[linux-flexiantxendom0-3.2.10.git] / arch / x86_64 / kernel / process.c
index 399e652..129a20d 100644 (file)
@@ -61,6 +61,7 @@ EXPORT_SYMBOL(boot_option_idle_override);
  * Powermanagement idle function, if any..
  */
 void (*pm_idle)(void);
+static cpumask_t cpu_idle_map;
 
 void disable_hlt(void)
 {
@@ -123,6 +124,23 @@ static void poll_idle (void)
        }
 }
 
+
+void cpu_idle_wait(void)
+{
+        int cpu;
+        cpumask_t map;
+
+        for_each_online_cpu(cpu)
+                cpu_set(cpu, cpu_idle_map);
+
+        wmb();
+        do {
+                ssleep(1);
+                cpus_and(map, cpu_idle_map, cpu_online_map);
+        } while (!cpus_empty(map));
+}
+EXPORT_SYMBOL_GPL(cpu_idle_wait);
+
 /*
  * The idle thread. There's no useful work to be
  * done, so just try to conserve power and have a
@@ -131,21 +149,20 @@ static void poll_idle (void)
  */
 void cpu_idle (void)
 {
+       int cpu = smp_processor_id();
+
        /* endless idle loop with no priority at all */
        while (1) {
                while (!need_resched()) {
                        void (*idle)(void);
-                       /*
-                        * Mark this as an RCU critical section so that
-                        * synchronize_kernel() in the unload path waits
-                        * for our completion.
-                        */
-                       rcu_read_lock();
+
+                       if (cpu_isset(cpu, cpu_idle_map))
+                               cpu_clear(cpu, cpu_idle_map);
+                       rmb();
                        idle = pm_idle;
                        if (!idle)
                                idle = default_idle;
                        idle();
-                       rcu_read_unlock();
                }
                schedule();
        }
@@ -297,7 +314,7 @@ void flush_thread(void)
         * Forget coprocessor state..
         */
        clear_fpu(tsk);
-       clear_used_math();
+       tsk->used_math = 0;
 }
 
 void release_thread(struct task_struct *dead_task)