[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] PV-on-HVM: More carefully synchronise with APs when putting them to



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1176376198 -3600
# Node ID 4c06bcd83c902cf9851e8ad7ada5c09207da3e91
# Parent  9e9eb5b3dab7d2a09c0ba157c0fea628bbcac957
PV-on-HVM: More carefully synchronise with APs when putting them to
sleep in a spin loop.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c |   34 ++++++++++---
 1 files changed, 27 insertions(+), 7 deletions(-)

diff -r 9e9eb5b3dab7 -r 4c06bcd83c90 
unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c
--- a/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c        Thu Apr 
12 11:44:26 2007 +0100
+++ b/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c        Thu Apr 
12 12:09:58 2007 +0100
@@ -6,21 +6,32 @@
 #include "platform-pci.h"
 #include <asm/hypervisor.h>
 
+struct ap_suspend_info {
+       int      do_spin;
+       atomic_t nr_spinning;
+};
+
 /*
  * Spinning prevents, for example, APs touching grant table entries while
  * the shared grant table is not mapped into the address space imemdiately
  * after resume.
  */
-static void ap_suspend(void *_ap_spin)
+static void ap_suspend(void *_info)
 {
-       int *ap_spin = _ap_spin;
+       struct ap_suspend_info *info = _info;
 
        BUG_ON(!irqs_disabled());
 
-       while (*ap_spin) {
+       atomic_inc(&info->nr_spinning);
+       mb();
+
+       while (info->do_spin) {
                cpu_relax();
                HYPERVISOR_yield();
        }
+
+       mb();
+       atomic_dec(&info->nr_spinning);
 }
 
 static int bp_suspend(void)
@@ -42,7 +53,8 @@ static int bp_suspend(void)
 
 int __xen_suspend(int fast_suspend)
 {
-       int err, suspend_cancelled, ap_spin;
+       int err, suspend_cancelled, nr_cpus;
+       struct ap_suspend_info info;
 
        xenbus_suspend();
 
@@ -51,22 +63,30 @@ int __xen_suspend(int fast_suspend)
        /* Prevent any races with evtchn_interrupt() handler. */
        disable_irq(xen_platform_pdev->irq);
 
-       ap_spin = 1;
+       info.do_spin = 1;
+       atomic_set(&info.nr_spinning, 0);
        smp_mb();
 
-       err = smp_call_function(ap_suspend, &ap_spin, 0, 0);
+       nr_cpus = num_online_cpus() - 1;
+
+       err = smp_call_function(ap_suspend, &info, 0, 0);
        if (err < 0) {
                preempt_enable();
                xenbus_suspend_cancel();
                return err;
        }
 
+       while (atomic_read(&info.nr_spinning) != nr_cpus)
+               cpu_relax();
+
        local_irq_disable();
        suspend_cancelled = bp_suspend();
        local_irq_enable();
 
        smp_mb();
-       ap_spin = 0;
+       info.do_spin = 0;
+       while (atomic_read(&info.nr_spinning) != 0)
+               cpu_relax();
 
        enable_irq(xen_platform_pdev->irq);
 

_______________________________________________
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®.