diff mbox series

[PULL,04/49] hw: Add QOM parentship relation with CPUs

Message ID 20250112221726.30206-5-philmd@linaro.org
State New
Headers show
Series [PULL,01/49] pc-bios/meson.build: Silent unuseful DTC warnings | expand

Commit Message

Philippe Mathieu-Daudé Jan. 12, 2025, 10:16 p.m. UTC
QDev objects created with object_new() need to manually add
their parent relationship with object_property_add_child().

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Message-Id: <20240216110313.17039-22-philmd@linaro.org>
---
 hw/i386/x86-common.c                     | 1 +
 hw/microblaze/petalogix_ml605_mmu.c      | 1 +
 hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 +
 hw/mips/cps.c                            | 1 +
 hw/ppc/e500.c                            | 1 +
 hw/ppc/spapr.c                           | 1 +
 6 files changed, 6 insertions(+)

Comments

Igor Mammedov Jan. 13, 2025, 12:28 p.m. UTC | #1
On Sun, 12 Jan 2025 23:16:40 +0100
Philippe Mathieu-Daudé <philmd@linaro.org> wrote:

> QDev objects created with object_new() need to manually add
> their parent relationship with object_property_add_child().
> 
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
> Message-Id: <20240216110313.17039-22-philmd@linaro.org>
> ---
>  hw/i386/x86-common.c                     | 1 +
>  hw/microblaze/petalogix_ml605_mmu.c      | 1 +
>  hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 +
>  hw/mips/cps.c                            | 1 +
>  hw/ppc/e500.c                            | 1 +
>  hw/ppc/spapr.c                           | 1 +
>  6 files changed, 6 insertions(+)
> 
> diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
> index 97b4f7d4a0d..9c9ffb3484a 100644
> --- a/hw/i386/x86-common.c
> +++ b/hw/i386/x86-common.c
> @@ -60,6 +60,7 @@ static void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp)
>      if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) {
>          goto out;
>      }
> +    object_property_add_child(OBJECT(x86ms), "cpu[*]", OBJECT(cpu));

I might  be missing something but why it needs to be done manually?

device_set_realized() will place any parent-less device under (1) /machine/unattached
while devices created with device_add() are be placed under /machine/peripheral[-anon]

The commit message unfortunately doesn't explain why [1] shall be replaced
by direct cpu[*] array property directly under machine.
 
Granted, those paths aren't any kind of ABI and wrt x86 cpus
nothing should break (or I'd say it shouldn't break our promises) 
But I'd rather not do this without a good reason/explanation.

>      qdev_realize(DEVICE(cpu), NULL, errp);
>  
>  out:
> diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
> index 8b44be75a22..b6be40915ac 100644
> --- a/hw/microblaze/petalogix_ml605_mmu.c
> +++ b/hw/microblaze/petalogix_ml605_mmu.c
> @@ -83,6 +83,7 @@ petalogix_ml605_init(MachineState *machine)
>  
>      /* init CPUs */
>      cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
> +    object_property_add_child(OBJECT(machine), "cpu", OBJECT(cpu));
>      object_property_set_str(OBJECT(cpu), "version", "8.10.a", &error_abort);
>      /* Use FPU but don't use floating point conversion and square
>       * root instructions
> diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
> index 2c0d8c34cd2..29629310ba2 100644
> --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
> +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
> @@ -73,6 +73,7 @@ petalogix_s3adsp1800_init(MachineState *machine)
>      MemoryRegion *sysmem = get_system_memory();
>  
>      cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
> +    object_property_add_child(OBJECT(machine), "cpu", OBJECT(cpu));
>      object_property_set_str(OBJECT(cpu), "version", "7.10.d", &error_abort);
>      object_property_set_bool(OBJECT(cpu), "little-endian",
>                               !TARGET_BIG_ENDIAN, &error_abort);
> diff --git a/hw/mips/cps.c b/hw/mips/cps.c
> index 0d8cbdc8924..293b405b965 100644
> --- a/hw/mips/cps.c
> +++ b/hw/mips/cps.c
> @@ -87,6 +87,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
>          /* All cores use the same clock tree */
>          qdev_connect_clock_in(DEVICE(cpu), "clk-in", s->clock);
>  
> +        object_property_add_child(OBJECT(dev), "cpu[*]", OBJECT(cpu));
>          if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
>              return;
>          }
> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
> index 4551157c011..17d63ced907 100644
> --- a/hw/ppc/e500.c
> +++ b/hw/ppc/e500.c
> @@ -955,6 +955,7 @@ void ppce500_init(MachineState *machine)
>           */
>          object_property_set_bool(OBJECT(cs), "start-powered-off", i != 0,
>                                   &error_abort);
> +        object_property_add_child(OBJECT(machine), "cpu[*]", OBJECT(cpu));
>          qdev_realize_and_unref(DEVICE(cs), NULL, &error_fatal);
>  
>          if (!firstenv) {
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 623842f8064..125be6d29fd 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2705,6 +2705,7 @@ static void spapr_init_cpus(SpaprMachineState *spapr)
>                                      &error_fatal);
>              object_property_set_int(core, CPU_CORE_PROP_CORE_ID, core_id,
>                                      &error_fatal);
> +            object_property_add_child(OBJECT(spapr), "cpu[*]", OBJECT(core));
>              qdev_realize(DEVICE(core), NULL, &error_fatal);
>  
>              object_unref(core);
Philippe Mathieu-Daudé Jan. 13, 2025, 4 p.m. UTC | #2
On 13/1/25 13:28, Igor Mammedov wrote:
> On Sun, 12 Jan 2025 23:16:40 +0100
> Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
> 
>> QDev objects created with object_new() need to manually add
>> their parent relationship with object_property_add_child().
>>
>> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>> Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
>> Message-Id: <20240216110313.17039-22-philmd@linaro.org>
>> ---
>>   hw/i386/x86-common.c                     | 1 +
>>   hw/microblaze/petalogix_ml605_mmu.c      | 1 +
>>   hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 +
>>   hw/mips/cps.c                            | 1 +
>>   hw/ppc/e500.c                            | 1 +
>>   hw/ppc/spapr.c                           | 1 +
>>   6 files changed, 6 insertions(+)
>>
>> diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
>> index 97b4f7d4a0d..9c9ffb3484a 100644
>> --- a/hw/i386/x86-common.c
>> +++ b/hw/i386/x86-common.c
>> @@ -60,6 +60,7 @@ static void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp)
>>       if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) {
>>           goto out;
>>       }
>> +    object_property_add_child(OBJECT(x86ms), "cpu[*]", OBJECT(cpu));
> 
> I might  be missing something but why it needs to be done manually?
> 
> device_set_realized() will place any parent-less device under (1) /machine/unattached

This is exactly what we want to avoid, to eventually remove
the "/machine/unattached" container for good.

See "= Problem 4: The /machine/unattached/ orphanage =" in:
https://lore.kernel.org/qemu-devel/87o7d1i7ky.fsf@pond.sub.org/

> while devices created with device_add() are be placed under /machine/peripheral[-anon]
> 
> The commit message unfortunately doesn't explain why [1] shall be replaced
> by direct cpu[*] array property directly under machine.

Right. I'll drop for now and respin once reworded.

> Granted, those paths aren't any kind of ABI and wrt x86 cpus
> nothing should break (or I'd say it shouldn't break our promises)
> But I'd rather not do this without a good reason/explanation.
> 
>>       qdev_realize(DEVICE(cpu), NULL, errp);
>>   
>>   out:
Igor Mammedov Jan. 14, 2025, 10:18 a.m. UTC | #3
On Mon, 13 Jan 2025 17:00:55 +0100
Philippe Mathieu-Daudé <philmd@linaro.org> wrote:

> On 13/1/25 13:28, Igor Mammedov wrote:
> > On Sun, 12 Jan 2025 23:16:40 +0100
> > Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
> >   
> >> QDev objects created with object_new() need to manually add
> >> their parent relationship with object_property_add_child().
> >>
> >> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> >> Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
> >> Message-Id: <20240216110313.17039-22-philmd@linaro.org>
> >> ---
> >>   hw/i386/x86-common.c                     | 1 +
> >>   hw/microblaze/petalogix_ml605_mmu.c      | 1 +
> >>   hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 +
> >>   hw/mips/cps.c                            | 1 +
> >>   hw/ppc/e500.c                            | 1 +
> >>   hw/ppc/spapr.c                           | 1 +
> >>   6 files changed, 6 insertions(+)
> >>
> >> diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
> >> index 97b4f7d4a0d..9c9ffb3484a 100644
> >> --- a/hw/i386/x86-common.c
> >> +++ b/hw/i386/x86-common.c
> >> @@ -60,6 +60,7 @@ static void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp)
> >>       if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) {
> >>           goto out;
> >>       }
> >> +    object_property_add_child(OBJECT(x86ms), "cpu[*]", OBJECT(cpu));  
> > 
> > I might  be missing something but why it needs to be done manually?
> > 
> > device_set_realized() will place any parent-less device under (1) /machine/unattached  
> 
> This is exactly what we want to avoid, to eventually remove
> the "/machine/unattached" container for good.
> 
> See "= Problem 4: The /machine/unattached/ orphanage =" in:
> https://lore.kernel.org/qemu-devel/87o7d1i7ky.fsf@pond.sub.org/


QOM paths as far as I'm aware were never part ABI nor I'm aware of
of any proposal to make it or some parts of it a public interface.

IMHO for public ABI, QEMU provides explicit QMP commands while
QOM should stay a playground for developers.

I this specific case, one basically replaces /machine/unattached
orphanage with explicit /machine one and many 'cpuN' children,
which ain't any better than device[N].

and in future I can imagine that at least in x86 case vcpus
might have another parent depending on configuration.
(i.e. being parented to cores instead)

If goal is to get rid of /machine/unattached, that's fine.
But please not make brittle naming under /machine/unattached
as a reason as 'cpu[N]' is the same just in different place
and scattered all over code (hence doubts if it's any better than current way).
(ps: don't we have exactly the same for peripheral-anon container)


> > while devices created with device_add() are be placed under /machine/peripheral[-anon]
> > 
> > The commit message unfortunately doesn't explain why [1] shall be replaced
> > by direct cpu[*] array property directly under machine.  
> 
> Right. I'll drop for now and respin once reworded.
> 
> > Granted, those paths aren't any kind of ABI and wrt x86 cpus
> > nothing should break (or I'd say it shouldn't break our promises)
> > But I'd rather not do this without a good reason/explanation.
> >   
> >>       qdev_realize(DEVICE(cpu), NULL, errp);
> >>   
> >>   out:  
>
Markus Armbruster Jan. 14, 2025, 12:38 p.m. UTC | #4
Igor Mammedov <imammedo@redhat.com> writes:

> On Mon, 13 Jan 2025 17:00:55 +0100
> Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>
>> On 13/1/25 13:28, Igor Mammedov wrote:
>> > On Sun, 12 Jan 2025 23:16:40 +0100
>> > Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>> >   
>> >> QDev objects created with object_new() need to manually add
>> >> their parent relationship with object_property_add_child().
>> >>
>> >> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>> >> Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
>> >> Message-Id: <20240216110313.17039-22-philmd@linaro.org>
>> >> ---
>> >>   hw/i386/x86-common.c                     | 1 +
>> >>   hw/microblaze/petalogix_ml605_mmu.c      | 1 +
>> >>   hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 +
>> >>   hw/mips/cps.c                            | 1 +
>> >>   hw/ppc/e500.c                            | 1 +
>> >>   hw/ppc/spapr.c                           | 1 +
>> >>   6 files changed, 6 insertions(+)
>> >>
>> >> diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
>> >> index 97b4f7d4a0d..9c9ffb3484a 100644
>> >> --- a/hw/i386/x86-common.c
>> >> +++ b/hw/i386/x86-common.c
>> >> @@ -60,6 +60,7 @@ static void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp)
>> >>       if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) {
>> >>           goto out;
>> >>       }
>> >> +    object_property_add_child(OBJECT(x86ms), "cpu[*]", OBJECT(cpu));  
>> > 
>> > I might  be missing something but why it needs to be done manually?
>> > 
>> > device_set_realized() will place any parent-less device under (1) /machine/unattached  
>> 
>> This is exactly what we want to avoid, to eventually remove
>> the "/machine/unattached" container for good.
>> 
>> See "= Problem 4: The /machine/unattached/ orphanage =" in:
>> https://lore.kernel.org/qemu-devel/87o7d1i7ky.fsf@pond.sub.org/
>
>
> QOM paths as far as I'm aware were never part ABI nor I'm aware of
> of any proposal to make it or some parts of it a public interface.

We've been waffling on this since forever.  QOM is not a public
interface except when it is, and it is when somebody says so, and it
isn't when somebody says so, resulting in a wave function that wobbles
like an underdone souffle, but never quite collapses.

> IMHO for public ABI, QEMU provides explicit QMP commands while
> QOM should stay a playground for developers.

Plenty of commands take QOM paths as arguments: eject,
blockdev-open-tray, blockdev-close-tray, blockdev-remove-medium,
blockdev-insert-medium, blockdev-change-medium,
block-latency-histogram-set, cxl-inject-general-media-event,
cxl-inject-dram-event, cxl-inject-memory-module-event,
cxl-inject-poison, cxl-inject-uncorrectable-errors,
cxl-inject-correctable-error, device_del, device-sync-config,
query-stats, x-query-virtio-status, x-query-virtio-queue-status,
x-query-virtio-vhost-queue-status, x-query-virtio-queue-element, and
possibly more.

The only way their QOM path arguments can be used without relying on QOM
paths being ABI would be obtaining the argument value with a command or
from an event.  I doubt that would be possible even if we tried it,
which we haven't.

> I this specific case, one basically replaces /machine/unattached
> orphanage with explicit /machine one and many 'cpuN' children,
> which ain't any better than device[N].
>
> and in future I can imagine that at least in x86 case vcpus
> might have another parent depending on configuration.
> (i.e. being parented to cores instead)
>
> If goal is to get rid of /machine/unattached, that's fine.

/machine/unattached was a lazy mistake.

> But please not make brittle naming under /machine/unattached
> as a reason as 'cpu[N]' is the same just in different place
> and scattered all over code (hence doubts if it's any better than current way).

Can you suggest a better, workable naming scheme?

> (ps: don't we have exactly the same for peripheral-anon container)

Yes, but users can avoid that by passing an @id argument.

[...]
Zhao Liu Jan. 14, 2025, 2:38 p.m. UTC | #5
> I this specific case, one basically replaces /machine/unattached
> orphanage with explicit /machine one and many 'cpuN' children,
> which ain't any better than device[N].
> 
> and in future I can imagine that at least in x86 case vcpus
> might have another parent depending on configuration.
> (i.e. being parented to cores instead)

I remember that this was your idea all along, and I'm not sure if you're
also referring to my previous patches about hybrid topology :-), which I'll
continue to refresh afterward in future (after all, the hybrid architecture
will continue in x86). And I think, since socket/core/thread are the three
default QEMU topology hierarchies, I understand that it would be best for
thread to always have core as parent.
Igor Mammedov Jan. 15, 2025, 10:19 a.m. UTC | #6
On Tue, 14 Jan 2025 13:38:59 +0100
Markus Armbruster <armbru@redhat.com> wrote:

> Igor Mammedov <imammedo@redhat.com> writes:
> 
> > On Mon, 13 Jan 2025 17:00:55 +0100
> > Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
> >  
> >> On 13/1/25 13:28, Igor Mammedov wrote:  
> >> > On Sun, 12 Jan 2025 23:16:40 +0100
> >> > Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
> >> >     
> >> >> QDev objects created with object_new() need to manually add
> >> >> their parent relationship with object_property_add_child().
> >> >>
> >> >> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> >> >> Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
> >> >> Message-Id: <20240216110313.17039-22-philmd@linaro.org>
> >> >> ---
> >> >>   hw/i386/x86-common.c                     | 1 +
> >> >>   hw/microblaze/petalogix_ml605_mmu.c      | 1 +
> >> >>   hw/microblaze/petalogix_s3adsp1800_mmu.c | 1 +
> >> >>   hw/mips/cps.c                            | 1 +
> >> >>   hw/ppc/e500.c                            | 1 +
> >> >>   hw/ppc/spapr.c                           | 1 +
> >> >>   6 files changed, 6 insertions(+)
> >> >>
> >> >> diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
> >> >> index 97b4f7d4a0d..9c9ffb3484a 100644
> >> >> --- a/hw/i386/x86-common.c
> >> >> +++ b/hw/i386/x86-common.c
> >> >> @@ -60,6 +60,7 @@ static void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp)
> >> >>       if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) {
> >> >>           goto out;
> >> >>       }
> >> >> +    object_property_add_child(OBJECT(x86ms), "cpu[*]", OBJECT(cpu));    
> >> > 
> >> > I might  be missing something but why it needs to be done manually?
> >> > 
> >> > device_set_realized() will place any parent-less device under (1) /machine/unattached    
> >> 
> >> This is exactly what we want to avoid, to eventually remove
> >> the "/machine/unattached" container for good.
> >> 
> >> See "= Problem 4: The /machine/unattached/ orphanage =" in:
> >> https://lore.kernel.org/qemu-devel/87o7d1i7ky.fsf@pond.sub.org/  
> >
> >
> > QOM paths as far as I'm aware were never part ABI nor I'm aware of
> > of any proposal to make it or some parts of it a public interface.  
> 
> We've been waffling on this since forever.  QOM is not a public
> interface except when it is, and it is when somebody says so, and it
> isn't when somebody says so, resulting in a wave function that wobbles
> like an underdone souffle, but never quite collapses.
> 
> > IMHO for public ABI, QEMU provides explicit QMP commands while
> > QOM should stay a playground for developers.  
> 
> Plenty of commands take QOM paths as arguments: eject,
> blockdev-open-tray, blockdev-close-tray, blockdev-remove-medium,
> blockdev-insert-medium, blockdev-change-medium,
> block-latency-histogram-set, cxl-inject-general-media-event,
> cxl-inject-dram-event, cxl-inject-memory-module-event,
> cxl-inject-poison, cxl-inject-uncorrectable-errors,
> cxl-inject-correctable-error, device_del, device-sync-config,
> query-stats, x-query-virtio-status, x-query-virtio-queue-status,
> x-query-virtio-vhost-queue-status, x-query-virtio-queue-element, and
> possibly more.

well, unless draw a line somewhere it will never stop.
Perhaps we should find on some border where QOM exposure stops
and document it. So whenever question pops up again, one could be
sent there.

all x- commands could be ignored, prefix tells no promises whatsoever,
cxl- group all new and doesn't have excuse to expose QOM, but not
many pay attention it subsystem considering it as platform bring up effort

> The only way their QOM path arguments can be used without relying on QOM
> paths being ABI would be obtaining the argument value with a command or
> from an event.  I doubt that would be possible even if we tried it,
> which we haven't.

hotpluggable-cpu command might be an example (it returns vcpu path,
which is valid within vcpu lifetime). But then again it's for
devs convenience. 

What I don't like about exposing QOM is 

> > I this specific case, one basically replaces /machine/unattached
> > orphanage with explicit /machine one and many 'cpuN' children,
> > which ain't any better than device[N].
> >
> > and in future I can imagine that at least in x86 case vcpus
> > might have another parent depending on configuration.
> > (i.e. being parented to cores instead)
> >
> > If goal is to get rid of /machine/unattached, that's fine.  
> 
> /machine/unattached was a lazy mistake.

no argument here

> 
> > But please not make brittle naming under /machine/unattached
> > as a reason as 'cpu[N]' is the same just in different place
> > and scattered all over code (hence doubts if it's any better than current way).  
> 
> Can you suggest a better, workable naming scheme?

nope, that's why I'm not arguing against it (modulo voicing my doubts)

PS:
Another question is if it's safe to move/rename device withing QOM tree
wrt migration (i.e. when 1st instance has old QOM tree and 2nd a modified one)

quick smoke test works (migrating from old qemu to a new one with this patch)
But it's better to ask to be safe.

> > (ps: don't we have exactly the same for peripheral-anon container)  
> 
> Yes, but users can avoid that by passing an @id argument.
> 
> [...]
>
Igor Mammedov Jan. 15, 2025, 1:13 p.m. UTC | #7
On Tue, 14 Jan 2025 22:38:30 +0800
Zhao Liu <zhao1.liu@intel.com> wrote:

> > I this specific case, one basically replaces /machine/unattached
> > orphanage with explicit /machine one and many 'cpuN' children,
> > which ain't any better than device[N].
> > 
> > and in future I can imagine that at least in x86 case vcpus
> > might have another parent depending on configuration.
> > (i.e. being parented to cores instead)  
> 
> I remember that this was your idea all along, and I'm not sure if you're
> also referring to my previous patches about hybrid topology :-), which I'll

I'm sorry, I've should've reviewed it long time ago.
But it got lost in from my review queue, can you give me a pointer
to the latest you've posted, please? 

> continue to refresh afterward in future (after all, the hybrid architecture
> will continue in x86). And I think, since socket/core/thread are the three
> default QEMU topology hierarchies, I understand that it would be best for
> thread to always have core as parent.

I guess it's fine as /machine/cpu[N] for now,
what I've initially wished for is commit message that explains
how do we get there and why it's done, so that later, whoever has to
touch that code would have an idea why it's there.
Zhao Liu Jan. 15, 2025, 2:07 p.m. UTC | #8
> > I remember that this was your idea all along, and I'm not sure if you're
> > also referring to my previous patches about hybrid topology :-), which I'll
> 
> I'm sorry, I've should've reviewed it long time ago.
> But it got lost in from my review queue, can you give me a pointer
> to the latest you've posted, please? 

You are very kind, no need sorry :-). I have also been inspired by many
of your previous ideas (although my work may not fully meet your
expectations yet). Here are the links:

[1]: qom-topo series, which tries to abstract every topology levels as
     devices and build a topology tree:
     https://lore.kernel.org/qemu-devel/20240919015533.766754-1-zhao1.liu@intel.com/
[2]: hybird-topo series, based on [1], which allows i386 to customize
     topology tree:
     https://lore.kernel.org/qemu-devel/20240919061128.769139-1-zhao1.liu@intel.com/

Thanks,
Zhao
Peter Xu Jan. 15, 2025, 5:44 p.m. UTC | #9
On Wed, Jan 15, 2025 at 11:19:28AM +0100, Igor Mammedov wrote:
> Another question is if it's safe to move/rename device withing QOM tree
> wrt migration (i.e. when 1st instance has old QOM tree and 2nd a modified one)
> 
> quick smoke test works (migrating from old qemu to a new one with this patch)
> But it's better to ask to be safe.

I had a quick look, taking the simplest qemu64 cpu, I see two vmsds: "cpu"
+ "cpu_common", provided with different "instance_id" for each.  That's the
ABI for the migration stream so far to match devices on two sides.

From that POV it's okay to move CPU devices within the qom-tree, hence not
yet part of the ABI.  It matches with above tests that it would pass.

Though I'm not 100% sure this is wise either from migration POV.. because I
think we need to rely on strictly below on both sides of QEMU src/dst:

  - Exactly the same QEMU cmdlines to be used (e.g. -smp X should be the
    same on src/dst, or anything that creates the CPUs in cmdlines)

  - Exactly the same QMP command to do device_add / device_del on CPUs,
    with exactly the same parameters.

I suppose only above be guaranteed by the user (or, libvirt), could the
instance_id to be assigned be identical on both src/dst.  But I'm not 100%
sure Libvirt can guarantee that.  E.g., we have vhost-user bug that can see
different instance_id of some slirp instances after some plug/unplugs:

https://issues.redhat.com/browse/RHEL-56331

That might be slightly different topic, though, so the movement in the qom
tree so far looks ok..
diff mbox series

Patch

diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index 97b4f7d4a0d..9c9ffb3484a 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -60,6 +60,7 @@  static void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp)
     if (!object_property_set_uint(cpu, "apic-id", apic_id, errp)) {
         goto out;
     }
+    object_property_add_child(OBJECT(x86ms), "cpu[*]", OBJECT(cpu));
     qdev_realize(DEVICE(cpu), NULL, errp);
 
 out:
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index 8b44be75a22..b6be40915ac 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -83,6 +83,7 @@  petalogix_ml605_init(MachineState *machine)
 
     /* init CPUs */
     cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
+    object_property_add_child(OBJECT(machine), "cpu", OBJECT(cpu));
     object_property_set_str(OBJECT(cpu), "version", "8.10.a", &error_abort);
     /* Use FPU but don't use floating point conversion and square
      * root instructions
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index 2c0d8c34cd2..29629310ba2 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -73,6 +73,7 @@  petalogix_s3adsp1800_init(MachineState *machine)
     MemoryRegion *sysmem = get_system_memory();
 
     cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
+    object_property_add_child(OBJECT(machine), "cpu", OBJECT(cpu));
     object_property_set_str(OBJECT(cpu), "version", "7.10.d", &error_abort);
     object_property_set_bool(OBJECT(cpu), "little-endian",
                              !TARGET_BIG_ENDIAN, &error_abort);
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 0d8cbdc8924..293b405b965 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -87,6 +87,7 @@  static void mips_cps_realize(DeviceState *dev, Error **errp)
         /* All cores use the same clock tree */
         qdev_connect_clock_in(DEVICE(cpu), "clk-in", s->clock);
 
+        object_property_add_child(OBJECT(dev), "cpu[*]", OBJECT(cpu));
         if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
             return;
         }
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 4551157c011..17d63ced907 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -955,6 +955,7 @@  void ppce500_init(MachineState *machine)
          */
         object_property_set_bool(OBJECT(cs), "start-powered-off", i != 0,
                                  &error_abort);
+        object_property_add_child(OBJECT(machine), "cpu[*]", OBJECT(cpu));
         qdev_realize_and_unref(DEVICE(cs), NULL, &error_fatal);
 
         if (!firstenv) {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 623842f8064..125be6d29fd 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2705,6 +2705,7 @@  static void spapr_init_cpus(SpaprMachineState *spapr)
                                     &error_fatal);
             object_property_set_int(core, CPU_CORE_PROP_CORE_ID, core_id,
                                     &error_fatal);
+            object_property_add_child(OBJECT(spapr), "cpu[*]", OBJECT(core));
             qdev_realize(DEVICE(core), NULL, &error_fatal);
 
             object_unref(core);