From: Fabiano Rosas <farosas@suse.de>
To: qemu-devel@nongnu.org
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
"Richard Henderson" <richard.henderson@linaro.org>,
"Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>,
"Shivang Upadhyay" <shivangu@linux.ibm.com>,
"Chinmay Rath" <rathc@linux.ibm.com>,
"Doru Blânzeanu" <dblanzeanu@linux.microsoft.com>,
"Magnus Kulke" <magnuskulke@linux.microsoft.com>
Subject: Re: [PATCH] accel: Fix qtest deadlock during unplug
Date: Wed, 23 Sep 2026 10:05:22 -0300 [thread overview]
Message-ID: <87ld8s9kz1.fsf@suse.de> (raw)
In-Reply-To: <20260918140037.3082357-1-farosas@suse.de>
Fabiano Rosas <farosas@suse.de> writes:
> This is a revert of one hunk of commit d5e33b5f8f ("accel: make all
> calls to qemu_process_cpu_events look the same"). It regressed
> device-plug-test on ppc64. Run this in a loop and it deadlocks before
> 50 iterations:
>
> QTEST_QEMU_BINARY=./qemu-system-ppc64 ./tests/qtest/device-plug-test -p
> /ppc64/device-plug/spapr-cpu-unplug-request
>
> The deadlocked stacks are:
> T0:
> #0 in sigtimedwait
> #1 in sigwait
> #2 in dummy_cpu_thread_fn (arg=0x558ed4db8eb0) at ../accel/dummy-cpus.c:52
>
> T1:
> #2 in qemu_thread_join (thread=0x55e3803dfc60) at ../util/qemu-thread-posix.c:554
> #3 in cpu_remove_sync (cpu=0x558ed4db8eb0) at ../system/cpus.c:633
> #4 in ppc_cpu_unrealize (dev=0x558ed4db8eb0) at ../target/ppc/cpu_init.c:6967
>
> What the test does is to queue a cpu unplug request to be executed
> during system reset. So we end up with two cpu_exit() calls affecting
> the dummy loop, one via pause_all_cpus() and another via
> cpu_remove_sync().
>
> Moving qemu_process_cpu_events() to the top of the loop has made the
> release of the halt_cond + the read of cpu->unplug not happen
> atomically regarding the BQL anymore.
>
> One cpu_exit() call will cause qemu_process_cpu_events() to make
> progress, the BQL be release and the pending SIG_IPI to be consumed by
> sigwait(). But since the BQL is unlocked, the second qemu_cpu_kick()
> invocation can execute entirely while the BQL is unlocked and issue:
>
> i) another broadcast on halt_cond, which will be queued and,
> ii) another signal, which will be discarded
>
> After the sigwait() returns and qemu_process_cpu_events() executes
> again in the next loop iteration, it exits right away due to the cond
> already being posted, but the sigwait() call for that loop won't see
> any signal. The thread cannot be joined at this point so there's a
> deadlock.
>
> Since the dummy_cpu loop is so simple, I think the best way to fix
> this is to revert that part of the change and move
> qemu_process_cpu_events() back to the end of the loop, where it will
> be within the same BQL locking window as the cpu->unplug check.
>
> Fixes: d5e33b5f8f ("accel: make all calls to qemu_process_cpu_events look the same")
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
> CI run: https://gitlab.com/farosas/qemu/-/pipelines/2861429046
> ---
> accel/dummy-cpus.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/accel/dummy-cpus.c b/accel/dummy-cpus.c
> index 5752f6302c..225a47c31f 100644
> --- a/accel/dummy-cpus.c
> +++ b/accel/dummy-cpus.c
> @@ -43,7 +43,6 @@ static void *dummy_cpu_thread_fn(void *arg)
> qemu_guest_random_seed_thread_part2(cpu->random_seed);
>
> do {
> - qemu_process_cpu_events(cpu);
> bql_unlock();
> #ifndef _WIN32
> do {
> @@ -58,6 +57,7 @@ static void *dummy_cpu_thread_fn(void *arg)
> qemu_sem_wait(&cpu->sem);
> #endif
> bql_lock();
> + qemu_process_cpu_events(cpu);
> } while (!cpu->unplug);
>
> bql_unlock();
+ppc and mshv folks
@Chinmay, just to make you aware that there's a broken test for ppc
@Shivang, we're discussing about cpu_remove_sync() down in this thread,
maybe that's of interest to you. Philippe is suggesting we could maybe
move the call up a layer.
@Doru, Magnus, for your awareness. This bug is about the dummy
cpu thread that qtest and xen use, but the pattern of coming out of
qemu_process_cpu_events() and unlocking the BQL is present in mshv as
well.
next prev parent reply other threads:[~2026-09-23 13:06 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-18 14:00 [PATCH] accel: Fix qtest deadlock during unplug Fabiano Rosas
2026-09-21 13:45 ` Philippe Mathieu-Daudé
2026-09-21 21:22 ` Fabiano Rosas
2026-09-23 13:05 ` Fabiano Rosas [this message]
2026-09-24 13:16 ` Shivang Upadhyay
2026-09-24 15:31 ` Fabiano Rosas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87ld8s9kz1.fsf@suse.de \
--to=farosas@suse.de \
--cc=dblanzeanu@linux.microsoft.com \
--cc=magnuskulke@linux.microsoft.com \
--cc=pbonzini@redhat.com \
--cc=philmd@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
--cc=rathc@linux.ibm.com \
--cc=richard.henderson@linaro.org \
--cc=shivangu@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.