ChangeSet 1.1602, 2005/05/31 09:27:49+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx
Updated process.c for x86-64.
Signed-off-by: Jun Nakajima <jun.nakajima@xxxxxxxxx>
process.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 52 insertions(+), 12 deletions(-)
diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/process.c
b/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/process.c
--- a/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/process.c 2005-05-31
05:02:11 -04:00
+++ b/linux-2.6.11-xen-sparse/arch/xen/x86_64/kernel/process.c 2005-05-31
05:02:11 -04:00
@@ -21,6 +21,7 @@
#include <stdarg.h>
+#include <linux/cpu.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -84,28 +85,48 @@
EXPORT_SYMBOL(enable_hlt);
/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
-extern int set_timeout_timer(void);
+extern void stop_hz_timer(void);
+extern void start_hz_timer(void);
void xen_idle(void)
{
- int cpu;
-
local_irq_disable();
- cpu = smp_processor_id();
- if (rcu_pending(cpu))
- rcu_check_callbacks(cpu, 0);
-
if (need_resched()) {
local_irq_enable();
- } else if (set_timeout_timer() == 0) {
- /* NB. Blocking reenable events in a race-free manner. */
- HYPERVISOR_block();
} else {
- local_irq_enable();
- HYPERVISOR_yield();
+ stop_hz_timer();
+ HYPERVISOR_block(); /* implicit local_irq_enable() */
+ start_hz_timer();
}
}
+#ifdef CONFIG_HOTPLUG_CPU
+#include <asm/nmi.h>
+/* We don't actually take CPU down, just spin without interrupts. */
+static inline void play_dead(void)
+{
+ /* Ack it */
+ __get_cpu_var(cpu_state) = CPU_DEAD;
+
+ /* We shouldn't have to disable interrupts while dead, but
+ * some interrupts just don't seem to go away, and this makes
+ * it "work" for testing purposes. */
+ /* Death loop */
+ while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
+ HYPERVISOR_yield();
+
+ local_irq_disable();
+ __flush_tlb_all();
+ cpu_set(smp_processor_id(), cpu_online_map);
+ local_irq_enable();
+}
+#else
+static inline void play_dead(void)
+{
+ BUG();
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
/*
* The idle thread. There's no useful work to be
* done, so just try to conserve power and have a
@@ -122,6 +143,9 @@
if (cpu_isset(cpu, cpu_idle_map))
cpu_clear(cpu, cpu_idle_map);
rmb();
+
+ if (cpu_is_offline(cpu))
+ play_dead();
__IRQ_STAT(cpu,idle_timestamp) = jiffies;
xen_idle();
@@ -129,6 +153,22 @@
schedule();
}
}
+
+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);
/* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */
/* Always use xen_idle() instead. */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|