diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-04-07 08:09:00 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-04-07 08:09:00 +0100 |
commit | f2dcefdc7bbebb44b09f2c4abaa8e731b4959fcf (patch) | |
tree | da359fcee6e22e2eb0ac3e45ad0d7d46ee97bf58 | |
parent | 0273e627ed1c8d6ed3a3494b3b670192e15c56f3 (diff) | |
download | xen-f2dcefdc7bbebb44b09f2c4abaa8e731b4959fcf.tar.gz xen-f2dcefdc7bbebb44b09f2c4abaa8e731b4959fcf.tar.bz2 xen-f2dcefdc7bbebb44b09f2c4abaa8e731b4959fcf.zip |
x86, cpu hotplug: Synchronise vcpu state earlier during cpu offline.
Needs to happen before non-idle VCPU is fully descheduled after CPU is
removed from cpu_online_map. Else sync_vcpu_execstate() doesn't work
properly.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
-rw-r--r-- | xen/arch/x86/domain.c | 3 | ||||
-rw-r--r-- | xen/arch/x86/smpboot.c | 17 |
2 files changed, 12 insertions, 8 deletions
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 6321e56bfb..1ed5c9e73f 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1442,7 +1442,8 @@ void context_switch(struct vcpu *prev, struct vcpu *next) set_current(next); - if ( (per_cpu(curr_vcpu, cpu) == next) || is_idle_vcpu(next) ) + if ( (per_cpu(curr_vcpu, cpu) == next) || + (is_idle_vcpu(next) && cpu_online(cpu)) ) { local_irq_enable(); } diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 0fb829028e..96db89fc54 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -997,17 +997,13 @@ static int __devinit do_boot_cpu(int apicid, int cpu) return boot_error; } -static void idle_task_exit(void) -{ - /* Give up lazy state borrowed by this idle vcpu */ - __sync_lazy_execstate(); -} - void cpu_exit_clear(void) { int cpu = raw_smp_processor_id(); - idle_task_exit(); + /* Previous non-idle state should be synchronised already. */ + if (__sync_lazy_execstate()) + BUG(); cpucount --; cpu_uninit(); @@ -1302,6 +1298,13 @@ int __cpu_disable(void) remove_siblinginfo(cpu); + /* + * If we are running the idle vcpu, sync last non-idle vcpu's state + * before changing cpu_online_map. If we are running non-idle vcpu, + * we will synchronously sync the state in context_switch() later. + */ + __sync_lazy_execstate(); + /* It's now safe to remove this processor from the online map */ cpu_clear(cpu, cpu_online_map); fixup_irqs(); |