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] Avoid deadlocks on domctl_lock when pausi

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Avoid deadlocks on domctl_lock when pausing domains/vcpus.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 09 Apr 2009 23:00:18 -0700
Delivery-date: Thu, 09 Apr 2009 23:00:45 -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 1239194915 -3600
# Node ID 3929487cdb821d4c26160828ed44589499716aa0
# Parent  9f945f16bd0224d4b761333366e355837944f21d
Avoid deadlocks on domctl_lock when pausing domains/vcpus.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c      |   13 ++++++++-----
 xen/common/domctl.c         |   35 ++++++++++++++++++++++++++++++++---
 xen/include/xen/domain.h    |    3 +++
 xen/include/xen/hypercall.h |    1 -
 4 files changed, 43 insertions(+), 9 deletions(-)

diff -r 9f945f16bd02 -r 3929487cdb82 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Wed Apr 08 13:18:22 2009 +0100
+++ b/xen/arch/x86/hvm/hvm.c    Wed Apr 08 13:48:35 2009 +0100
@@ -2489,20 +2489,23 @@ long do_hvm_op(unsigned long op, XEN_GUE
                 if ( !paging_mode_hap(d) )
                     break;
 
-                domain_pause(d);
-
                 /*
                  * Update GUEST_CR3 in each VMCS to point at identity map.
                  * All foreign updates to guest state must synchronise on
                  * the domctl_lock.
                  */
-                spin_lock(&domctl_lock);
+                rc = -EAGAIN;
+                if ( !domctl_lock_acquire() )
+                    break;
+
+                rc = 0;
+                domain_pause(d);
                 d->arch.hvm_domain.params[a.index] = a.value;
                 for_each_vcpu ( d, v )
                     paging_update_cr3(v);
-                spin_unlock(&domctl_lock);
-
                 domain_unpause(d);
+
+                domctl_lock_release();
                 break;
             case HVM_PARAM_DM_DOMAIN:
                 /* Privileged domains only, as we must domain_pause(d). */
diff -r 9f945f16bd02 -r 3929487cdb82 xen/common/domctl.c
--- a/xen/common/domctl.c       Wed Apr 08 13:18:22 2009 +0100
+++ b/xen/common/domctl.c       Wed Apr 08 13:48:35 2009 +0100
@@ -25,7 +25,7 @@
 #include <public/domctl.h>
 #include <xsm/xsm.h>
 
-DEFINE_SPINLOCK(domctl_lock);
+static DEFINE_SPINLOCK(domctl_lock);
 
 extern long arch_do_domctl(
     struct xen_domctl *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);
@@ -188,6 +188,33 @@ static unsigned int default_vcpu0_locati
     return cpu;
 }
 
+bool_t domctl_lock_acquire(void)
+{
+    /*
+     * Caller may try to pause its own VCPUs. We must prevent deadlock
+     * against other non-domctl routines which try to do the same.
+     */
+    if ( !spin_trylock(&current->domain->hypercall_deadlock_mutex) )
+        return 0;
+
+    /*
+     * Trylock here is paranoia if we have multiple privileged domains. Then
+     * we could have one domain trying to pause another which is spinning
+     * on domctl_lock -- results in deadlock.
+     */
+    if ( spin_trylock(&domctl_lock) )
+        return 1;
+
+    spin_unlock(&current->domain->hypercall_deadlock_mutex);
+    return 0;
+}
+
+void domctl_lock_release(void)
+{
+    spin_unlock(&domctl_lock);
+    spin_unlock(&current->domain->hypercall_deadlock_mutex);
+}
+
 long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
 {
     long ret = 0;
@@ -202,7 +229,9 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
     if ( op->interface_version != XEN_DOMCTL_INTERFACE_VERSION )
         return -EACCES;
 
-    spin_lock(&domctl_lock);
+    if ( !domctl_lock_acquire() )
+        return hypercall_create_continuation(
+            __HYPERVISOR_domctl, "h", u_domctl);
 
     switch ( op->cmd )
     {
@@ -866,7 +895,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         break;
     }
 
-    spin_unlock(&domctl_lock);
+    domctl_lock_release();
 
     return ret;
 }
diff -r 9f945f16bd02 -r 3929487cdb82 xen/include/xen/domain.h
--- a/xen/include/xen/domain.h  Wed Apr 08 13:18:22 2009 +0100
+++ b/xen/include/xen/domain.h  Wed Apr 08 13:48:35 2009 +0100
@@ -58,6 +58,9 @@ void arch_dump_domain_info(struct domain
 
 void arch_vcpu_reset(struct vcpu *v);
 
+bool_t domctl_lock_acquire(void);
+void domctl_lock_release(void);
+
 extern unsigned int xen_processor_pmbits;
 
 #endif /* __XEN_DOMAIN_H__ */
diff -r 9f945f16bd02 -r 3929487cdb82 xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h       Wed Apr 08 13:18:22 2009 +0100
+++ b/xen/include/xen/hypercall.h       Wed Apr 08 13:48:35 2009 +0100
@@ -30,7 +30,6 @@ do_sched_op(
     int cmd,
     XEN_GUEST_HANDLE(void) arg);
 
-extern spinlock_t domctl_lock;
 extern long
 do_domctl(
     XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);

_______________________________________________
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] Avoid deadlocks on domctl_lock when pausing domains/vcpus., Xen patchbot-unstable <=