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] SMP support for Xen PM.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] SMP support for Xen PM.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 27 Jul 2007 03:12:26 -0700
Delivery-date: Fri, 27 Jul 2007 03:10:28 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/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 kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1184847813 -3600
# Node ID 858b9bc8d0e6245ba361cff097547ed8a1729e29
# Parent  0d291a7c8c1f4a77a01c49f2e8cc90271ed19d37
SMP support for Xen PM.

Add SMP sleep support to Xen. One new utility is created
to allow vcpu continue previous running after migration
to new processor.

Signed-off-by: Kevin Tian <kevin.tian@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/acpi/power.c          |   44 +++++++++++++++++++++++++++------
 xen/arch/x86/cpu/intel_cacheinfo.c |    4 +--
 xen/arch/x86/domain.c              |   49 +++++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/domain.h       |    8 +++++-
 xen/include/asm-x86/smp.h          |    2 +
 5 files changed, 96 insertions(+), 11 deletions(-)

diff -r 0d291a7c8c1f -r 858b9bc8d0e6 xen/arch/x86/acpi/power.c
--- a/xen/arch/x86/acpi/power.c Thu Jul 19 12:53:32 2007 +0100
+++ b/xen/arch/x86/acpi/power.c Thu Jul 19 13:23:33 2007 +0100
@@ -119,19 +119,25 @@ static int enter_state(u32 state)
     if (state <= ACPI_STATE_S0 || state > ACPI_S_STATES_MAX)
         return -EINVAL;
 
-    /* Sync lazy state on ths cpu */
     __sync_lazy_execstate();
     pmprintk(XENLOG_INFO, "Flush lazy state\n");
 
     if (!spin_trylock(&pm_lock))
         return -EBUSY;
     
-    freeze_domains();
-
-    hvm_cpu_down();
-
     pmprintk(XENLOG_INFO, "PM: Preparing system for %s sleep\n",
         acpi_states[state]);
+
+    freeze_domains();
+
+    disable_nonboot_cpus();
+    if (num_online_cpus() != 1)
+    {
+        error = -EBUSY;
+        goto Enable_cpu;
+    }
+
+    hvm_cpu_down();
 
     acpi_sleep_prepare(state);
 
@@ -169,16 +175,31 @@ static int enter_state(u32 state)
     if ( !hvm_cpu_up() )
         BUG();
 
+ Enable_cpu:
+    enable_nonboot_cpus();
+
     thaw_domains();
     spin_unlock(&pm_lock);
     return error;
 }
 
+static void acpi_power_off(void)
+{
+    pmprintk(XENLOG_INFO, "%s called\n", __FUNCTION__);
+    local_irq_disable();
+    /* Some SMP machines only can poweroff in boot CPU */
+    acpi_enter_sleep_state(ACPI_STATE_S5);
+}
+
+static long enter_state_helper(void *data)
+{
+    struct acpi_sleep_info *sinfo = (struct acpi_sleep_info *)data;
+    return enter_state(sinfo->sleep_state);
+}
+
 /*
  * Dom0 issues this hypercall in place of writing pm1a_cnt. Xen then
  * takes over the control and put the system into sleep state really.
- * Also video flags and mode are passed here, in case user may use
- * "acpi_sleep=***" for video resume.
  *
  * Guest may issue a two-phases write to PM1x_CNT, to work
  * around poorly implemented hardware. It's better to keep
@@ -216,7 +237,14 @@ int acpi_enter_sleep(struct xenpf_enter_
     acpi_sinfo.pm1b_cnt_val = sleep->pm1b_cnt_val;
     acpi_sinfo.sleep_state = sleep->sleep_state;
 
-    return enter_state(acpi_sinfo.sleep_state);
+    /* ACPI power-off method. */
+    if ( acpi_sinfo.sleep_state == ACPI_STATE_S5 )
+    {
+        for ( ; ; )
+            acpi_power_off();
+    }
+
+    return continue_hypercall_on_cpu(0, enter_state_helper, &acpi_sinfo);
 }
 
 static int acpi_get_wake_status(void)
diff -r 0d291a7c8c1f -r 858b9bc8d0e6 xen/arch/x86/cpu/intel_cacheinfo.c
--- a/xen/arch/x86/cpu/intel_cacheinfo.c        Thu Jul 19 12:53:32 2007 +0100
+++ b/xen/arch/x86/cpu/intel_cacheinfo.c        Thu Jul 19 13:23:33 2007 +0100
@@ -17,7 +17,7 @@ struct _cache_table
 };
 
 /* all the cache descriptor types we care about (no TLB or trace cache 
entries) */
-static struct _cache_table cache_table[] __initdata =
+static struct _cache_table cache_table[] __devinitdata =
 {
        { 0x06, LVL_1_INST, 8 },        /* 4-way set assoc, 32 byte line size */
        { 0x08, LVL_1_INST, 16 },       /* 4-way set assoc, 32 byte line size */
@@ -60,7 +60,7 @@ static struct _cache_table cache_table[]
        { 0x00, 0, 0}
 };
 
-unsigned int __init init_intel_cacheinfo(struct cpuinfo_x86 *c)
+unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 {
        unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache 
sizes */
 
diff -r 0d291a7c8c1f -r 858b9bc8d0e6 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Thu Jul 19 12:53:32 2007 +0100
+++ b/xen/arch/x86/domain.c     Thu Jul 19 13:23:33 2007 +0100
@@ -82,6 +82,7 @@ static void play_dead(void)
     __cpu_disable();
     /* This must be done before dead CPU ack */
     cpu_exit_clear();
+    hvm_cpu_down();
     wbinvd();
     mb();
     /* Ack it */
@@ -1361,6 +1362,54 @@ void sync_vcpu_execstate(struct vcpu *v)
 
     /* Other cpus call __sync_lazy_execstate from flush ipi handler. */
     flush_tlb_mask(v->vcpu_dirty_cpumask);
+}
+
+struct migrate_info {
+    long (*func)(void *data);
+    void *data;
+    void (*saved_schedule_tail)(struct vcpu *);
+    cpumask_t saved_affinity;
+};
+
+static void continue_hypercall_on_cpu_helper(struct vcpu *v)
+{
+    struct cpu_user_regs *regs = guest_cpu_user_regs();
+    struct migrate_info *info = v->arch.continue_info;
+
+    regs->eax = info->func(info->data);
+
+    v->arch.schedule_tail = info->saved_schedule_tail;
+    v->cpu_affinity = info->saved_affinity;
+
+    xfree(info);
+    v->arch.continue_info = NULL;
+
+    vcpu_set_affinity(v, &v->cpu_affinity);
+    schedule_tail(v);
+}
+
+int continue_hypercall_on_cpu(int cpu, long (*func)(void *data), void *data)
+{
+    struct vcpu *v = current;
+    struct migrate_info *info;
+    cpumask_t mask = cpumask_of_cpu(cpu);
+
+    info = xmalloc(struct migrate_info);
+    if ( info == NULL )
+        return -ENOMEM;
+
+    info->func = func;
+    info->data = data;
+    info->saved_schedule_tail = v->arch.schedule_tail;
+    v->arch.schedule_tail = continue_hypercall_on_cpu_helper;
+
+    info->saved_affinity = v->cpu_affinity;
+    v->arch.continue_info = info;
+
+    vcpu_set_affinity(v, &mask);
+    schedule_tail(v);
+
+    return 0;
 }
 
 #define next_arg(fmt, args) ({                                              \
diff -r 0d291a7c8c1f -r 858b9bc8d0e6 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Thu Jul 19 12:53:32 2007 +0100
+++ b/xen/include/asm-x86/domain.h      Thu Jul 19 13:23:33 2007 +0100
@@ -268,6 +268,9 @@ struct arch_vcpu
     void (*ctxt_switch_from) (struct vcpu *);
     void (*ctxt_switch_to) (struct vcpu *);
 
+    /* Record information required to continue execution after migration */
+    void *continue_info;
+
     /* Bounce information for propagating an exception to guest OS. */
     struct trap_bounce trap_bounce;
 
@@ -311,9 +314,12 @@ struct arch_vcpu
     unsigned long vcpu_info_mfn;
 } __cacheline_aligned;
 
-/* shorthands to improve code legibility */
+/* Shorthands to improve code legibility. */
 #define hvm_vmx         hvm_vcpu.u.vmx
 #define hvm_svm         hvm_vcpu.u.svm
+
+/* Continue the current hypercall via func(data) on specified cpu. */
+int continue_hypercall_on_cpu(int cpu, long (*func)(void *data), void *data);
 
 #endif /* __ASM_DOMAIN_H__ */
 
diff -r 0d291a7c8c1f -r 858b9bc8d0e6 xen/include/asm-x86/smp.h
--- a/xen/include/asm-x86/smp.h Thu Jul 19 12:53:32 2007 +0100
+++ b/xen/include/asm-x86/smp.h Thu Jul 19 13:23:33 2007 +0100
@@ -66,6 +66,8 @@ extern void enable_nonboot_cpus(void);
 extern void enable_nonboot_cpus(void);
 #else
 static inline int cpu_is_offline(int cpu) {return 0;}
+static inline void disable_nonboot_cpus(void) {}
+static inline void enable_nonboot_cpus(void) {}
 #endif
 
 /*

_______________________________________________
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] SMP support for Xen PM., Xen patchbot-unstable <=