qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <philmd@linaro.org>
To: Richard Henderson <richard.henderson@linaro.org>, qemu-devel@nongnu.org
Cc: "Alex Bennée" <alex.bennee@linaro.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: Mon, 16 Jun 2025 10:21:28 +0200	[thread overview]
Message-ID: <9ec68c71-c53d-495f-b7ab-6061ea727dd0@linaro.org> (raw)
In-Reply-To: <c9a8d923-0faf-46a4-962b-5a0f4289008f@linaro.org>

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.
>>
>> 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.


  reply	other threads:[~2025-06-16  8:24 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é [this message]
2025-06-17  9:42       ` Alex Bennée
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=9ec68c71-c53d-495f-b7ab-6061ea727dd0@linaro.org \
    --to=philmd@linaro.org \
    --cc=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=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).