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] Do not spin on locks that may be held by

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Do not spin on locks that may be held by stop_machine_run() callers.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 22 Mar 2010 03:35:12 -0700
Delivery-date: Mon, 22 Mar 2010 03:35:17 -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 1269253753 0
# Node ID 4d3834df04831658eee8f2b7398443e24d4eb2fe
# Parent  81d9132ce00d353c5a9d6850bfd902304f65b54a
Do not spin on locks that may be held by stop_machine_run() callers.

Currently stop_machine_run() will try to bring all CPUs to softirq
context, with some locks held, like xenpf_lock or cpu_add_remove_lock
etc. However, if another CPU is trying to get these locks, it may
cause deadlock.

This patch replace all such spin_lock with spin_trylock. For
xenpf_lock and sysctl_lock, we try to use hypercall_continuation, so
that we will not cause trouble to user space tools. For
cpu_hot_remove_lock, we simply return EBUSY if failure, since it will
only impact small number of user space tools.

In the end, we should try to make the stop_machine_run as spinlock
free.

Signed-off-by: Jiang, Yunhong <yunhong.jiang@xxxxxxxxx>
---
 xen/arch/x86/platform_hypercall.c |   13 +++++++++++--
 xen/arch/x86/smpboot.c            |   20 +++++++++++++++++---
 xen/common/sysctl.c               |    6 +++++-
 3 files changed, 33 insertions(+), 6 deletions(-)

diff -r 81d9132ce00d -r 4d3834df0483 xen/arch/x86/platform_hypercall.c
--- a/xen/arch/x86/platform_hypercall.c Mon Mar 22 10:24:17 2010 +0000
+++ b/xen/arch/x86/platform_hypercall.c Mon Mar 22 10:29:13 2010 +0000
@@ -73,7 +73,11 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
     if ( op->interface_version != XENPF_INTERFACE_VERSION )
         return -EACCES;
 
-    spin_lock(&xenpf_lock);
+    /* spin_trylock() avoids deadlock with stop_machine_run(). */
+    while ( !spin_trylock(&xenpf_lock) )
+        if ( hypercall_preempt_check() )
+            return hypercall_create_continuation(
+                __HYPERVISOR_platform_op, "h", u_xenpf_op);
 
     switch ( op->cmd )
     {
@@ -398,7 +402,12 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
 
         g_info = &op->u.pcpu_info;
 
-        spin_lock(&cpu_add_remove_lock);
+        /* spin_trylock() avoids deadlock with stop_machine_run(). */
+        if ( !spin_trylock(&cpu_add_remove_lock) )
+        {
+            ret = -EBUSY;
+            break;
+        }
 
         if ( (g_info->xen_cpuid >= NR_CPUS) ||
              (g_info->xen_cpuid < 0) ||
diff -r 81d9132ce00d -r 4d3834df0483 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c    Mon Mar 22 10:24:17 2010 +0000
+++ b/xen/arch/x86/smpboot.c    Mon Mar 22 10:29:13 2010 +0000
@@ -1342,7 +1342,12 @@ int cpu_down(unsigned int cpu)
 {
        int err = 0;
 
-       spin_lock(&cpu_add_remove_lock);
+       /* spin_trylock() avoids deadlock with stop_machine_run(). */
+       if (!spin_trylock(&cpu_add_remove_lock)) {
+               err = -EBUSY;
+               goto out;
+       }
+
        if (num_online_cpus() == 1) {
                err = -EBUSY;
                goto out;
@@ -1384,7 +1389,10 @@ int cpu_up(unsigned int cpu)
 {
        int err = 0;
 
-       spin_lock(&cpu_add_remove_lock);
+       /* spin_trylock() avoids deadlock with stop_machine_run(). */
+       if (!spin_trylock(&cpu_add_remove_lock))
+           return -EBUSY;
+
        if (cpu_online(cpu)) {
                printk("Bring up a online cpu. Bogus!\n");
                err = -EBUSY;
@@ -1419,6 +1427,8 @@ void disable_nonboot_cpus(void)
                if (cpu == 0)
                        continue;
                error = cpu_down(cpu);
+               /* No need to check EBUSY here */
+               ASSERT(error != -EBUSY);
                if (!error) {
                        cpu_set(cpu, frozen_cpus);
                        printk("CPU%d is down\n", cpu);
@@ -1439,6 +1449,8 @@ void enable_nonboot_cpus(void)
        mtrr_aps_sync_begin();
        for_each_cpu_mask(cpu, frozen_cpus) {
                error = cpu_up(cpu);
+               /* No conflict will happen here */
+               ASSERT(error != -EBUSY);
                if (!error) {
                        printk("CPU%d is up\n", cpu);
                        continue;
@@ -1481,7 +1493,9 @@ int cpu_add(uint32_t apic_id, uint32_t a
        if ( physid_isset(apic_id, phys_cpu_present_map) )
                return -EEXIST;
 
-       spin_lock(&cpu_add_remove_lock);
+       /* spin_trylock() avoids deadlock with stop_machine_run(). */
+       if (!spin_trylock(&cpu_add_remove_lock))
+               return -EBUSY;
 
        cpu = mp_register_lapic(apic_id, 1);
 
diff -r 81d9132ce00d -r 4d3834df0483 xen/common/sysctl.c
--- a/xen/common/sysctl.c       Mon Mar 22 10:24:17 2010 +0000
+++ b/xen/common/sysctl.c       Mon Mar 22 10:29:13 2010 +0000
@@ -48,7 +48,11 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
     if ( op->interface_version != XEN_SYSCTL_INTERFACE_VERSION )
         return -EACCES;
 
-    spin_lock(&sysctl_lock);
+    /* spin_trylock() avoids deadlock with stop_machine_run(). */
+    while ( !spin_trylock(&sysctl_lock) )
+        if ( hypercall_preempt_check() )
+            return hypercall_create_continuation(
+                __HYPERVISOR_sysctl, "h", u_sysctl);
 
     switch ( op->cmd )
     {

_______________________________________________
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] Do not spin on locks that may be held by stop_machine_run() callers., Xen patchbot-unstable <=