WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Some cleanups to cpu offline handling.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Some cleanups to cpu offline handling.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 19 May 2010 05:15:33 -0700
Delivery-date: Wed, 19 May 2010 05:17:08 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Some cleanups to cpu offline handling., Xen patchbot-unstable <=