From: "Alex Bennée" <alex.bennee@linaro.org>
To: "Philippe Mathieu-Daudé" <philmd@linaro.org>
Cc: Richard Henderson <richard.henderson@linaro.org>,
qemu-devel@nongnu.org,
Pierrick Bouvier <pierrick.bouvier@linaro.org>,
Igor Mammedov <imammedo@redhat.com>,
Peter Maydell <peter.maydell@linaro.org>,
Paolo Bonzini <pbonzini@redhat.com>,
Peter Xu <peterx@redhat.com>,
David Hildenbrand <david@redhat.com>
Subject: Re: [RFC PATCH 02/19] system/cpus: Only kick running vCPUs
Date: Tue, 17 Jun 2025 10:42:27 +0100 [thread overview]
Message-ID: <87sejyvh4s.fsf@draig.linaro.org> (raw)
In-Reply-To: <9ec68c71-c53d-495f-b7ab-6061ea727dd0@linaro.org> ("Philippe Mathieu-Daudé"'s message of "Mon, 16 Jun 2025 10:21:28 +0200")
Philippe Mathieu-Daudé <philmd@linaro.org> writes:
> On 7/6/25 15:23, Richard Henderson wrote:
>> On 6/6/25 17:44, Philippe Mathieu-Daudé wrote:
>>> As an optimization, avoid kicking stopped vCPUs.
This also breaks gdbstub:
pause_all_vcpus() -> cpu_pause(sets cpu->stop) -> qemu_cpu_kick(skips kicking)
>>>
>>> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>>> ---
>>> system/cpus.c | 5 +++++
>>> 1 file changed, 5 insertions(+)
>>>
>>> diff --git a/system/cpus.c b/system/cpus.c
>>> index d16b0dff989..4835e5ced48 100644
>>> --- a/system/cpus.c
>>> +++ b/system/cpus.c
>>> @@ -494,6 +494,11 @@ void cpus_kick_thread(CPUState *cpu)
>>> void qemu_cpu_kick(CPUState *cpu)
>>> {
>>> qemu_cond_broadcast(cpu->halt_cond);
>>> +
>>> + if (!cpu_can_run(cpu)) {
>>> + return;
>>> + }
>>> +
>> This would appear to be a race condition. The evaluation of
>> cpu_can_run should be done within the context of 'cpu', not here,
>> and not *after* we've already woken 'cpu' via the broadcast.
>
> OK.
>
> Still I don't understand something, when putting this assertion:
>
> -- >8 --
> diff --git a/system/cpus.c b/system/cpus.c
> index d16b0dff989..0631015f754 100644
> --- a/system/cpus.c
> +++ b/system/cpus.c
> @@ -493,7 +493,10 @@ void cpus_kick_thread(CPUState *cpu)
>
> void qemu_cpu_kick(CPUState *cpu)
> {
> + assert(cpu_can_run(cpu));
> +
> qemu_cond_broadcast(cpu->halt_cond);
> if (cpus_accel->kick_vcpu_thread) {
> cpus_accel->kick_vcpu_thread(cpu);
> } else { /* default */
> ---
>
> I get:
>
> (lldb) bt
> * thread #1, queue = 'com.apple.main-thread', stop reason = hit
> program assert
> frame #0: 0x000000018a669388 libsystem_kernel.dylib`__pthread_kill + 8
> frame #1: 0x000000018a6a288c libsystem_pthread.dylib`pthread_kill + 296
> frame #2: 0x000000018a5abc60 libsystem_c.dylib`abort + 124
> frame #3: 0x000000018a5aaeec libsystem_c.dylib`__assert_rtn + 284
> * frame #4: 0x000000010057ddc4 qemu_cpu_kick(cpu=0x0000000130218000)
> at cpus.c:496:5
> frame #5: 0x00000001000106ec
> queue_work_on_cpu(cpu=0x0000000130218000, wi=0x000060000038c000)
> at cpu-common.c:140:5
> frame #6: 0x0000000100010780
> async_run_on_cpu(cpu=0x0000000130218000, func=(tcg_commit_cpu at
> physmem.c:2758), data=(host_int = 60885632, host_ulong =
> 105553177152128, host_ptr = 0x0000600003a10a80, target_ptr =
> 105553177152128)) at cpu-common.c:177:5
> frame #7: 0x000000010059ad34
> tcg_commit(listener=0x0000600003a10a98) at physmem.c:2789:9
> frame #8: 0x0000000100591240
> listener_add_address_space(listener=0x0000600003a10a98,
> as=0x0000600003611980) at memory.c:3082:9
> frame #9: 0x0000000100590f48
> memory_listener_register(listener=0x0000600003a10a98,
> as=0x0000600003611980) at memory.c:3170:5
> frame #10: 0x000000010059abe4
> cpu_address_space_init(cpu=0x0000000130218000, asidx=0,
> prefix="cpu-memory", mr=0x000000012b1faba0) at physmem.c:813:9
> frame #11: 0x0000000100750c40
> arm_cpu_realizefn(dev=0x0000000130218000, errp=0x000000016fdfe2c0)
> at cpu.c:2572:5
> frame #12: 0x0000000100b7ed9c
> device_set_realized(obj=0x0000000130218000, value=true,
> errp=0x000000016fdfe388) at qdev.c:494:13
> frame #13: 0x0000000100b8a880
> property_set_bool(obj=0x0000000130218000, v=0x0000600003f12d00,
> name="realized", opaque=0x000060000010c1d0,
> errp=0x000000016fdfe388) at object.c:2375:5
> frame #14: 0x0000000100b87acc
> object_property_set(obj=0x0000000130218000, name="realized",
> v=0x0000600003f12d00, errp=0x000000016fdfe388) at object.c:1450:5
> frame #15: 0x0000000100b8f14c
> object_property_set_qobject(obj=0x0000000130218000,
> name="realized", value=0x0000600000386920,
> errp=0x0000000101e39e28) at qom-qobject.c:28:10
> frame #16: 0x0000000100b882f8
> object_property_set_bool(obj=0x0000000130218000, name="realized",
> value=true, errp=0x0000000101e39e28) at object.c:1520:15
> frame #17: 0x0000000100b7d240 qdev_realize(dev=0x0000000130218000,
> bus=0x0000000000000000, errp=0x0000000101e39e28) at qdev.c:276:12
> frame #18: 0x000000010083a81c
> machvirt_init(machine=0x000000012b1fa710) at virt.c:2329:9
> frame #19: 0x0000000100136a40
> machine_run_board_init(machine=0x000000012b1fa710,
> mem_path=0x0000000000000000, errp=0x000000016fdfe6a8) at
> machine.c:1669:5
> frame #20: 0x0000000100571384 qemu_init_board at vl.c:2714:5
> frame #21: 0x0000000100571154
> qmp_x_exit_preconfig(errp=0x0000000101e39e28) at vl.c:2808:5
> frame #22: 0x0000000100573a14 qemu_init(argc=17,
> argv=0x000000016fdff138) at vl.c:3844:9
> frame #23: 0x0000000100d036e0 main(argc=17,
> argv=0x000000016fdff138) at main.c:71:5
> frame #24: 0x000000018a302b98 dyld`start + 6076
> (lldb)
>
> I expect a vCPU to be in a "stable" state and usable *after* it is
> realized, as we are calling various hooks in many places. Here we are
> processing the pending work queue while the vCPU isn't fully realized,
> so some hooks might not have been called yet...
>
> Git history of tcg_commit() points to commit 0d58c660689 ("softmmu: Use
> async_run_on_cpu in tcg_commit").
> This isn't the first time I ends there, see also:
> https://lore.kernel.org/qemu-devel/20230907161415.6102-1-philmd@linaro.org/.
> Using the same reasoning of this patch, adding:
>
> -- >8 --
> diff --git a/system/physmem.c b/system/physmem.c
> index a8a9ca309ea..479a7a88037 100644
> --- a/system/physmem.c
> +++ b/system/physmem.c
> @@ -2773,6 +2774,14 @@ static void tcg_commit(MemoryListener *listener)
> cpuas = container_of(listener, CPUAddressSpace, tcg_as_listener);
> cpu = cpuas->cpu;
>
> + if (!qdev_is_realized(DEVICE(cpu))) {
> + /*
> + * The listener is also called during realize, before
> + * all of the tcg machinery for run-on is initialized.
> + */
> + return;
> + }
> +
> /*
> * Defer changes to as->memory_dispatch until the cpu is quiescent.
> * Otherwise we race between (1) other cpu threads and (2) ongoing
> ---
>
> makes my issues disappear; tcg_commit_cpu() calls are run on realized
> vCPUs, and the order of pre-realize vcpu hooks doesn't alter anything.
>
> I don't remember why I wrote this "The listener is also called during
> realize, before all of the tcg machinery for run-on is initialized"
> comment, it could be better to call memory_region_transaction_commit()
> after CpuRealize, maybe in CpuReset.
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
next prev parent reply other threads:[~2025-06-17 9:43 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-06 16:43 [RFC PATCH 00/19] accel: Preparatory cleanups for split-accel Philippe Mathieu-Daudé
2025-06-06 16:44 ` [RFC PATCH 01/19] hw/arm/virt: Only require TCG || QTest to use virtualization extension Philippe Mathieu-Daudé
2025-06-07 13:18 ` Richard Henderson
2025-06-11 13:37 ` Alex Bennée
2025-06-11 13:45 ` Miguel Luis
2025-06-11 14:31 ` Alex Bennée
2025-06-11 14:38 ` Miguel Luis
2025-06-06 16:44 ` [RFC PATCH 02/19] system/cpus: Only kick running vCPUs Philippe Mathieu-Daudé
2025-06-07 13:23 ` Richard Henderson
2025-06-16 8:21 ` Philippe Mathieu-Daudé
2025-06-17 9:42 ` Alex Bennée [this message]
2025-06-06 16:44 ` [RFC PATCH 03/19] accel: Keep reference to AccelOpsClass in AccelClass Philippe Mathieu-Daudé
2025-06-07 13:35 ` Richard Henderson
2025-06-11 13:42 ` Alex Bennée
2025-06-06 16:44 ` [RFC PATCH 04/19] accel: Propagate AccelState to AccelClass::init_machine() Philippe Mathieu-Daudé
2025-06-07 13:31 ` Richard Henderson
2025-06-11 13:42 ` Alex Bennée
2025-06-06 16:44 ` [RFC PATCH 05/19] accel/kvm: Prefer local AccelState over global MachineState::accel Philippe Mathieu-Daudé
2025-06-07 13:30 ` Richard Henderson
2025-06-06 16:44 ` [RFC PATCH 06/19] accel/hvf: Fix TYPE_HVF_ACCEL instance size Philippe Mathieu-Daudé
2025-06-07 13:29 ` Richard Henderson
2025-06-06 16:44 ` [RFC PATCH 07/19] accel/hvf: Re-use QOM allocated state Philippe Mathieu-Daudé
2025-06-07 13:30 ` Richard Henderson
2025-06-06 16:44 ` [RFC PATCH 08/19] accel/tcg: Prefer local AccelState over global current_accel() Philippe Mathieu-Daudé
2025-06-07 13:37 ` Richard Henderson
2025-06-06 16:44 ` [RFC PATCH 09/19] accel: Factor accel_cpu_realize() out Philippe Mathieu-Daudé
2025-06-11 13:46 ` Alex Bennée
2025-06-06 16:44 ` [RFC PATCH 10/19] accel/dummy: Factor dummy_thread_precreate() out Philippe Mathieu-Daudé
2025-06-06 16:44 ` [RFC PATCH 11/19] accel/dummy: Factor tcg_vcpu_thread_precreate() out Philippe Mathieu-Daudé
2025-06-06 16:44 ` [RFC PATCH 12/19] accel: Factor accel_create_vcpu_thread() out Philippe Mathieu-Daudé
2025-06-06 16:44 ` [RFC PATCH 13/19] accel: Introduce AccelOpsClass::cpu_thread_routine handler Philippe Mathieu-Daudé
2025-06-11 14:09 ` Alex Bennée
2025-06-06 16:44 ` [RFC PATCH 14/19] accel/dummy: Convert to AccelOpsClass::cpu_thread_routine Philippe Mathieu-Daudé
2025-06-06 16:44 ` [RFC PATCH 15/19] accel/tcg: " Philippe Mathieu-Daudé
2025-06-06 16:44 ` [RFC PATCH 16/19] accel/hvf: " Philippe Mathieu-Daudé
2025-06-06 16:44 ` [RFC PATCH 17/19] accel/kvm: " Philippe Mathieu-Daudé
2025-06-06 16:44 ` [RFC PATCH 18/19] accel/nvmm: " Philippe Mathieu-Daudé
2025-06-06 16:44 ` [RFC PATCH 19/19] accel/whpx: " Philippe Mathieu-Daudé
2025-06-11 14:00 ` [RFC PATCH 00/19] accel: Preparatory cleanups for split-accel Alex Bennée
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=87sejyvh4s.fsf@draig.linaro.org \
--to=alex.bennee@linaro.org \
--cc=david@redhat.com \
--cc=imammedo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=peterx@redhat.com \
--cc=philmd@linaro.org \
--cc=pierrick.bouvier@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/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.