[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Updated process.c for x86-64.
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |