From e69e8b9da6483cb4646869e47d6b808a30f49be4 Mon Sep 17 00:00:00 2001 From: tangbinzy Date: Thu, 16 Mar 2023 02:54:16 +0000 Subject: [PATCH] qemu: avoid deadlock in qemuDomainObjStopWorker We are dropping the only reference here so that the event loop thread is going to be exited synchronously. In order to avoid deadlocks we need to unlock the VM so that any handler being called can finish execution and thus even loop thread be finished too. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nikolay Shirokovskiy Reviewed-by: Daniel Henrique Barboza Reviewed-by: Daniel P. Berrangé Signed-off-by: tangbin (cherry-pick from 860a999802d3c82538373bb3f314f92a2e258754) --- src/qemu/qemu_domain.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 70835e4efd..746adff3f1 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2192,11 +2192,21 @@ void qemuDomainObjStopWorker(virDomainObjPtr dom) { qemuDomainObjPrivatePtr priv = dom->privateData; + virEventThread *eventThread; - if (priv->eventThread) { - g_object_unref(priv->eventThread); - priv->eventThread = NULL; - } + if (!priv->eventThread) + return; + + /* + * We are dropping the only reference here so that the event loop thread + * is going to be exited synchronously. In order to avoid deadlocks we + * need to unlock the VM so that any handler being called can finish + * execution and thus even loop thread be finished too. + */ + eventThread = g_steal_pointer(&priv->eventThread); + virObjectUnlock(dom); + g_object_unref(eventThread); + virObjectLock(dom); } -- 2.27.0