Message ID | 20250128142152.9889-8-philmd@linaro.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | accel: Only include qdev-realized vCPUs in global &cpus_queue | expand |
On 1/28/25 06:21, Philippe Mathieu-Daudé wrote: > cpu_list_add() was doing 2 distinct things: > - assign some index to vCPU > - add unrealized (thus in inconsistent state) vcpu to &cpus_queue > > Code using CPU_FOREACH() macro would iterate over possibly > unrealized vCPUs, often dealt with special casing. > > In order to avoid that, we move the addition of vCPU to global queue > to the DeviceWire handler, which is called just before switching the > vCPU to REALIZED state. This ensure all &cpus_queue users (like via > &first_cpu or CPU_FOREACH) get a realized vCPU in consistent state. > > Similarly we remove it from the global queue at DeviceUnwire phase, > just after marking the vCPU UNREALIZED. > > Signed-off-by: Philippe Mathieu-Daudé<philmd@linaro.org> > --- > cpu-common.c | 2 -- > hw/core/cpu-common.c | 5 +++++ > 2 files changed, 5 insertions(+), 2 deletions(-) Reviewed-by: Richard Henderson <richard.henderson@linaro.org> r~
On 1/28/25 06:21, Philippe Mathieu-Daudé wrote: > @@ -91,7 +91,6 @@ void cpu_list_add(CPUState *cpu) > } else { > assert(!cpu_index_auto_assigned); > } > - QTAILQ_INSERT_TAIL_RCU(&cpus_queue, cpu, node); > cpu_list_generation_id++; > } > > @@ -103,7 +102,6 @@ void cpu_list_remove(CPUState *cpu) > return; > } > > - QTAILQ_REMOVE_RCU(&cpus_queue, cpu, node); > cpu->cpu_index = UNASSIGNED_CPU_INDEX; > cpu_list_generation_id++; > } We might rename cpu_list_add/remove, since they no longer do what's said on the tin. r~
diff --git a/cpu-common.c b/cpu-common.c index 4248b2d727e..72ee8dc414e 100644 --- a/cpu-common.c +++ b/cpu-common.c @@ -91,7 +91,6 @@ void cpu_list_add(CPUState *cpu) } else { assert(!cpu_index_auto_assigned); } - QTAILQ_INSERT_TAIL_RCU(&cpus_queue, cpu, node); cpu_list_generation_id++; } @@ -103,7 +102,6 @@ void cpu_list_remove(CPUState *cpu) return; } - QTAILQ_REMOVE_RCU(&cpus_queue, cpu, node); cpu->cpu_index = UNASSIGNED_CPU_INDEX; cpu_list_generation_id++; } diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c index 8a02ac146f6..df7a6913603 100644 --- a/hw/core/cpu-common.c +++ b/hw/core/cpu-common.c @@ -218,6 +218,8 @@ static void cpu_common_wire(DeviceState *dev) { CPUState *cpu = CPU(dev); + QTAILQ_INSERT_TAIL_RCU(&cpus_queue, cpu, node); + if (dev->hotplugged) { cpu_synchronize_post_init(cpu); cpu_resume(cpu); @@ -226,6 +228,9 @@ static void cpu_common_wire(DeviceState *dev) static void cpu_common_unwire(DeviceState *dev) { + CPUState *cpu = CPU(dev); + + QTAILQ_REMOVE_RCU(&cpus_queue, cpu, node); } static void cpu_common_unrealizefn(DeviceState *dev)
cpu_list_add() was doing 2 distinct things: - assign some index to vCPU - add unrealized (thus in inconsistent state) vcpu to &cpus_queue Code using CPU_FOREACH() macro would iterate over possibly unrealized vCPUs, often dealt with special casing. In order to avoid that, we move the addition of vCPU to global queue to the DeviceWire handler, which is called just before switching the vCPU to REALIZED state. This ensure all &cpus_queue users (like via &first_cpu or CPU_FOREACH) get a realized vCPU in consistent state. Similarly we remove it from the global queue at DeviceUnwire phase, just after marking the vCPU UNREALIZED. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> --- cpu-common.c | 2 -- hw/core/cpu-common.c | 5 +++++ 2 files changed, 5 insertions(+), 2 deletions(-)