[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Some cleanups to cpu offline handling.
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |