[PATCH] Fix (rare) deadlock in QEMU monitor callbacks

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

 



From: "Daniel P. Berrange" <berrange@xxxxxxxxxx>

Some users report (very rarely) seeing a deadlock in the QEMU
monitor callbacks

Thread 10 (Thread 0x7fcd11e20700 (LWP 26753)):
    at util/threads-pthread.c:85
    at conf/domain_conf.c:14256
    vm=0x7fcccc00a850) at qemu/qemu_process.c:1026
    at qemu/qemu_monitor.c:249
    at util/virobject.c:139
    at qemu/qemu_monitor.c:860
    vm=vm@entry=0x7fcccc00a850,
    reason=reason@entry=VIR_DOMAIN_SHUTOFF_DESTROYED, flags=flags@entry=0)
    at qemu/qemu_process.c:4057
    flags=<optimized out>) at qemu/qemu_driver.c:1977
    domain=domain@entry=0x7fccf00c1830, flags=1) at libvirt.c:2256

At frame #10 we are holding the domain lock, we call into
qemuProcessStop() to cleanup QEMU, which triggers the monitor
to close, which invokes qemuProcessHandleMonitorDestroy() which
tries to obtain the domain lock again. This is a non-recursive
lock, hence hang.

Since qemuMonitorPtr is a virObject, the unref call in
qemuProcessHandleMonitorDestroy no longer needs mutex
protection. The assignment of priv->mon = NULL, can be
instead done by the caller of qemuMonitorClose(), thus
removing all need for locking.

Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx>
---
 src/qemu/qemu_process.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index ade64b7..c8c188a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1019,17 +1019,10 @@ no_memory:
 }
 
 
-static void qemuProcessHandleMonitorDestroy(qemuMonitorPtr mon,
+static void qemuProcessHandleMonitorDestroy(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                             virDomainObjPtr vm)
 {
-    qemuDomainObjPrivatePtr priv;
-
-    virDomainObjLock(vm);
-    priv = vm->privateData;
-    if (priv->mon == mon)
-        priv->mon = NULL;
-    if (virObjectUnref(vm))
-        virDomainObjUnlock(vm);
+    virObjectUnref(vm);
 }
 
 static int
@@ -3995,8 +3988,10 @@ void qemuProcessStop(struct qemud_driver *driver,
         priv->agentError = false;
     }
 
-    if (priv->mon)
+    if (priv->mon) {
         qemuMonitorClose(priv->mon);
+        priv->mon = NULL;
+    }
 
     if (priv->monConfig) {
         if (priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX)
-- 
1.7.11.2

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]