[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.