# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1273857955 -3600
# Node ID e95448fc993ed011bae65296a3f531798b128518
# Parent 9fe4445a5fbe2fb8606621da4fb8dcae93bdf1e9
Some cleanups to cpu offline handling.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
xen/arch/ia64/linux-xen/smpboot.c | 15 ++++-----------
xen/arch/x86/domain.c | 7 -------
xen/arch/x86/hvm/hvm.c | 8 +++++++-
xen/arch/x86/hvm/svm/svm.c | 19 ++++++++++++++++---
xen/arch/x86/hvm/vmx/vmcs.c | 10 ++++++++--
xen/arch/x86/hvm/vmx/vmx.c | 3 ++-
xen/arch/x86/smpboot.c | 8 +++-----
xen/common/cpu.c | 3 ++-
xen/common/softirq.c | 3 ++-
xen/common/tasklet.c | 2 +-
xen/include/asm-ia64/linux-xen/asm/smp.h | 3 ---
xen/include/asm-x86/hvm/hvm.h | 4 +++-
xen/include/asm-x86/hvm/vmx/vmcs.h | 3 ++-
xen/include/asm-x86/smp.h | 2 --
xen/include/xen/cpu.h | 15 +++++++++++++--
xen/include/xen/smp.h | 5 -----
16 files changed, 63 insertions(+), 47 deletions(-)
diff -r 9fe4445a5fbe -r e95448fc993e xen/arch/ia64/linux-xen/smpboot.c
--- a/xen/arch/ia64/linux-xen/smpboot.c Fri May 14 17:48:53 2010 +0100
+++ b/xen/arch/ia64/linux-xen/smpboot.c Fri May 14 18:25:55 2010 +0100
@@ -721,15 +721,9 @@ remove_siblinginfo(int cpu)
extern void fixup_irqs(void);
/* must be called with cpucontrol mutex held */
-int __cpu_disable(void)
+void __cpu_disable(void)
{
int cpu = smp_processor_id();
-
- /*
- * dont permit boot processor for now
- */
- if (cpu == 0)
- return -EBUSY;
remove_siblinginfo(cpu);
cpu_clear(cpu, cpu_online_map);
@@ -738,12 +732,11 @@ int __cpu_disable(void)
#endif
local_flush_tlb_all();
cpu_clear(cpu, cpu_callin_map);
- return 0;
}
#else /* !CONFIG_HOTPLUG_CPU */
-int __cpu_disable(void)
-{
- return -ENOSYS;
+void __cpu_disable(void)
+{
+ BUG();
}
#endif /* CONFIG_HOTPLUG_CPU */
diff -r 9fe4445a5fbe -r e95448fc993e xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Fri May 14 17:48:53 2010 +0100
+++ b/xen/arch/x86/domain.c Fri May 14 18:25:55 2010 +0100
@@ -98,15 +98,8 @@ static void default_dead_idle(void)
static void play_dead(void)
{
- /*
- * Flush pending softirqs if any. They can be queued up before this CPU
- * was taken out of cpu_online_map in __cpu_disable().
- */
- do_softirq();
-
/* This must be done before dead CPU ack */
cpu_exit_clear();
- hvm_cpu_down();
wbinvd();
mb();
/* Ack it */
diff -r 9fe4445a5fbe -r e95448fc993e xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Fri May 14 17:48:53 2010 +0100
+++ b/xen/arch/x86/hvm/hvm.c Fri May 14 18:25:55 2010 +0100
@@ -80,7 +80,13 @@ static int cpu_callback(
switch ( action )
{
case CPU_UP_PREPARE:
- rc = hvm_funcs.cpu_prepare(cpu);
+ rc = hvm_funcs.cpu_up_prepare(cpu);
+ break;
+ case CPU_DYING:
+ hvm_cpu_down();
+ break;
+ case CPU_DEAD:
+ hvm_funcs.cpu_dead(cpu);
break;
default:
break;
diff -r 9fe4445a5fbe -r e95448fc993e xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Fri May 14 17:48:53 2010 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Fri May 14 18:25:55 2010 +0100
@@ -818,13 +818,25 @@ static int svm_do_pmu_interrupt(struct c
return vpmu_do_interrupt(regs);
}
-static int svm_cpu_prepare(unsigned int cpu)
+static void svm_cpu_dead(unsigned int cpu)
+{
+ free_xenheap_page(hsa[cpu]);
+ hsa[cpu] = NULL;
+ free_vmcb(root_vmcb[cpu]);
+ root_vmcb[cpu] = NULL;
+}
+
+static int svm_cpu_up_prepare(unsigned int cpu)
{
if ( ((hsa[cpu] == NULL) &&
((hsa[cpu] = alloc_host_save_area()) == NULL)) ||
((root_vmcb[cpu] == NULL) &&
((root_vmcb[cpu] = alloc_vmcb()) == NULL)) )
+ {
+ svm_cpu_dead(cpu);
return -ENOMEM;
+ }
+
return 0;
}
@@ -842,7 +854,7 @@ static int svm_cpu_up(struct cpuinfo_x86
return 0;
}
- if ( svm_cpu_prepare(cpu) != 0 )
+ if ( svm_cpu_up_prepare(cpu) != 0 )
return 0;
write_efer(read_efer() | EFER_SVME);
@@ -1328,7 +1340,8 @@ static void svm_invlpg_intercept(unsigne
static struct hvm_function_table __read_mostly svm_function_table = {
.name = "SVM",
- .cpu_prepare = svm_cpu_prepare,
+ .cpu_up_prepare = svm_cpu_up_prepare,
+ .cpu_dead = svm_cpu_dead,
.cpu_down = svm_cpu_down,
.domain_initialise = svm_domain_initialise,
.domain_destroy = svm_domain_destroy,
diff -r 9fe4445a5fbe -r e95448fc993e xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Fri May 14 17:48:53 2010 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Fri May 14 18:25:55 2010 +0100
@@ -337,7 +337,7 @@ static void vmx_load_vmcs(struct vcpu *v
local_irq_restore(flags);
}
-int vmx_cpu_prepare(unsigned int cpu)
+int vmx_cpu_up_prepare(unsigned int cpu)
{
if ( per_cpu(host_vmcs, cpu) != NULL )
return 0;
@@ -348,6 +348,12 @@ int vmx_cpu_prepare(unsigned int cpu)
printk("CPU%d: Could not allocate host VMCS\n", cpu);
return -ENOMEM;
+}
+
+void vmx_cpu_dead(unsigned int cpu)
+{
+ vmx_free_vmcs(per_cpu(host_vmcs, cpu));
+ per_cpu(host_vmcs, cpu) = NULL;
}
int vmx_cpu_up(void)
@@ -398,7 +404,7 @@ int vmx_cpu_up(void)
INIT_LIST_HEAD(&this_cpu(active_vmcs_list));
- if ( vmx_cpu_prepare(cpu) != 0 )
+ if ( vmx_cpu_up_prepare(cpu) != 0 )
return 0;
switch ( __vmxon(virt_to_maddr(this_cpu(host_vmcs))) )
diff -r 9fe4445a5fbe -r e95448fc993e xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Fri May 14 17:48:53 2010 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Fri May 14 18:25:55 2010 +0100
@@ -1379,7 +1379,8 @@ static void vmx_set_info_guest(struct vc
static struct hvm_function_table __read_mostly vmx_function_table = {
.name = "VMX",
- .cpu_prepare = vmx_cpu_prepare,
+ .cpu_up_prepare = vmx_cpu_up_prepare,
+ .cpu_dead = vmx_cpu_dead,
.domain_initialise = vmx_domain_initialise,
.domain_destroy = vmx_domain_destroy,
.vcpu_initialise = vmx_vcpu_initialise,
diff -r 9fe4445a5fbe -r e95448fc993e xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c Fri May 14 17:48:53 2010 +0100
+++ b/xen/arch/x86/smpboot.c Fri May 14 18:25:55 2010 +0100
@@ -1265,9 +1265,9 @@ remove_siblinginfo(int cpu)
cpu_clear(cpu, cpu_sibling_setup_map);
}
-extern void fixup_irqs(void);
-int __cpu_disable(void)
-{
+void __cpu_disable(void)
+{
+ extern void fixup_irqs(void);
int cpu = smp_processor_id();
local_irq_disable();
@@ -1287,8 +1287,6 @@ int __cpu_disable(void)
fixup_irqs();
cpu_disable_scheduler(cpu);
-
- return 0;
}
void __cpu_die(unsigned int cpu)
diff -r 9fe4445a5fbe -r e95448fc993e xen/common/cpu.c
--- a/xen/common/cpu.c Fri May 14 17:48:53 2010 +0100
+++ b/xen/common/cpu.c Fri May 14 18:25:55 2010 +0100
@@ -68,7 +68,8 @@ static int take_cpu_down(void *unused)
void *hcpu = (void *)(long)smp_processor_id();
if ( raw_notifier_call_chain(&cpu_chain, CPU_DYING, hcpu) != NOTIFY_DONE )
BUG();
- return __cpu_disable();
+ __cpu_disable();
+ return 0;
}
int cpu_down(unsigned int cpu)
diff -r 9fe4445a5fbe -r e95448fc993e xen/common/softirq.c
--- a/xen/common/softirq.c Fri May 14 17:48:53 2010 +0100
+++ b/xen/common/softirq.c Fri May 14 18:25:55 2010 +0100
@@ -38,7 +38,8 @@ static void __do_softirq(unsigned long i
if ( rcu_pending(cpu) )
rcu_check_callbacks(cpu);
- if ( (pending = (softirq_pending(cpu) & ~ignore_mask)) == 0 )
+ if ( ((pending = (softirq_pending(cpu) & ~ignore_mask)) == 0)
+ || cpu_is_offline(cpu) )
break;
i = find_first_set_bit(pending);
diff -r 9fe4445a5fbe -r e95448fc993e xen/common/tasklet.c
--- a/xen/common/tasklet.c Fri May 14 17:48:53 2010 +0100
+++ b/xen/common/tasklet.c Fri May 14 18:25:55 2010 +0100
@@ -78,7 +78,7 @@ void do_tasklet(void)
spin_lock_irq(&tasklet_lock);
- if ( unlikely(list_empty(list)) )
+ if ( unlikely(list_empty(list) || cpu_is_offline(cpu)) )
goto out;
t = list_entry(list->next, struct tasklet, list);
diff -r 9fe4445a5fbe -r e95448fc993e xen/include/asm-ia64/linux-xen/asm/smp.h
--- a/xen/include/asm-ia64/linux-xen/asm/smp.h Fri May 14 17:48:53 2010 +0100
+++ b/xen/include/asm-ia64/linux-xen/asm/smp.h Fri May 14 18:25:55 2010 +0100
@@ -118,10 +118,7 @@ max_xtp (void)
#define hard_smp_processor_id() ia64_get_lid()
/* Upping and downing of CPUs */
-extern int __cpu_disable (void);
-extern void __cpu_die (unsigned int cpu);
extern void cpu_die (void) __attribute__ ((noreturn));
-extern int __cpu_up (unsigned int cpu);
extern void __init smp_build_cpu_map(void);
extern void __init init_smp_config (void);
diff -r 9fe4445a5fbe -r e95448fc993e xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h Fri May 14 17:48:53 2010 +0100
+++ b/xen/include/asm-x86/hvm/hvm.h Fri May 14 18:25:55 2010 +0100
@@ -115,7 +115,9 @@ struct hvm_function_table {
int (*event_pending)(struct vcpu *v);
int (*do_pmu_interrupt)(struct cpu_user_regs *regs);
- int (*cpu_prepare)(unsigned int cpu);
+ int (*cpu_up_prepare)(unsigned int cpu);
+ void (*cpu_dead)(unsigned int cpu);
+
int (*cpu_up)(void);
void (*cpu_down)(void);
diff -r 9fe4445a5fbe -r e95448fc993e xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h Fri May 14 17:48:53 2010 +0100
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Fri May 14 18:25:55 2010 +0100
@@ -26,7 +26,8 @@ extern void start_vmx(void);
extern void start_vmx(void);
extern void vmcs_dump_vcpu(struct vcpu *v);
extern void setup_vmcs_dump(void);
-extern int vmx_cpu_prepare(unsigned int cpu);
+extern int vmx_cpu_up_prepare(unsigned int cpu);
+extern void vmx_cpu_dead(unsigned int cpu);
extern int vmx_cpu_up(void);
extern void vmx_cpu_down(void);
diff -r 9fe4445a5fbe -r e95448fc993e xen/include/asm-x86/smp.h
--- a/xen/include/asm-x86/smp.h Fri May 14 17:48:53 2010 +0100
+++ b/xen/include/asm-x86/smp.h Fri May 14 18:25:55 2010 +0100
@@ -93,8 +93,6 @@ static __inline int logical_smp_processo
#endif
-extern int __cpu_disable(void);
-extern void __cpu_die(unsigned int cpu);
#endif /* !__ASSEMBLY__ */
#else /* CONFIG_SMP */
diff -r 9fe4445a5fbe -r e95448fc993e xen/include/xen/cpu.h
--- a/xen/include/xen/cpu.h Fri May 14 17:48:53 2010 +0100
+++ b/xen/include/xen/cpu.h Fri May 14 18:25:55 2010 +0100
@@ -17,8 +17,14 @@ int register_cpu_notifier(struct notifie
int register_cpu_notifier(struct notifier_block *nb);
/*
- * Notification actions: note that only CPU_{UP,DOWN}_PREPARE may fail ---
- * all other handlers *must* return NOTIFY_DONE.
+ * Possible event sequences for a given CPU:
+ * CPU_UP_PREPARE -> CPU_UP_CANCELLED -- failed CPU up
+ * CPU_UP_PREPARE -> CPU_ONLINE -- successful CPU up
+ * CPU_DOWN_PREPARE -> CPU_DOWN_FAILED -- failed CPU down
+ * CPU_DOWN_PREPARE -> CPU_DYING -> CPU_DEAD -- successful CPU down
+ *
+ * Hence note that only CPU_*_PREPARE handlers are allowed to fail. Also note
+ * that once CPU_DYING is delivered, an offline action can no longer fail.
*/
#define CPU_UP_PREPARE 0x0002 /* CPU is coming up */
#define CPU_UP_CANCELED 0x0003 /* CPU is no longer coming up */
@@ -36,4 +42,9 @@ int disable_nonboot_cpus(void);
int disable_nonboot_cpus(void);
void enable_nonboot_cpus(void);
+/* Private arch-dependent helpers for CPU hotplug. */
+int __cpu_up(unsigned int cpunum);
+void __cpu_disable(void);
+void __cpu_die(unsigned int cpu);
+
#endif /* __XEN_CPU_H__ */
diff -r 9fe4445a5fbe -r e95448fc993e xen/include/xen/smp.h
--- a/xen/include/xen/smp.h Fri May 14 17:48:53 2010 +0100
+++ b/xen/include/xen/smp.h Fri May 14 18:25:55 2010 +0100
@@ -19,11 +19,6 @@ extern void smp_send_state_dump(unsigned
* Prepare machine for booting other CPUs.
*/
extern void smp_prepare_cpus(unsigned int max_cpus);
-
-/*
- * Bring a CPU up
- */
-extern int __cpu_up(unsigned int cpunum);
/*
* Final polishing of CPUs
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|