Thomas Huth <[email protected]> writes:

> From: Thomas Huth <[email protected]>
>
> We still have a lot of devices that end up in /machine/unattached in
> case the caller forgot to use object_property_add_child() to add it
> to a proper location in the QOM tree.

This is QOM papering over sloppy modeling.  Predictably, it has enabled
us to remain sloppy slobs.

I think the decision to paper over sloppiness to get QOM off the ground
quickly was defensible back then.  It's a lot less defensible now that
QOM has been off the ground for more than a decade.

I believe people are by and large unaware of the need to add children.
This risks further accumulation of technical debt.

To really put a stop to it, we'd have to mark the existing misuses, then
warn or crash on umarked misuse.

None of the above is an objection to your patch.

>                                       But at least for the devices
> that get realized via qdev_realize() and that have a bus specified,
> we can do better: Add the device automatically as a child to the bus
> device instead! This way the QOM tree looks way more logical, with
> way less devices hanging around in the /machine/unattached space.
>
> While we're at it, use the type name as node name (instead of using
> "device" like we did in the "unattached" space). But since these
> entries might not be stable (they use a counting number in the square
> brackets), the code also uses a "x-" prefix here to indicate that
> this still might change in the course of time (once a board decides
> to manually attach the device with a proper name instead).
>
> Signed-off-by: Thomas Huth <[email protected]>
> ---
>  hw/core/qdev.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index 42641c5224e..5b773d0108a 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -266,9 +266,19 @@ bool qdev_realize(DeviceState *dev, BusState *bus, Error 
> **errp)
>      assert(!dev->realized && !dev->parent_bus);
>  
>      if (bus) {
> +        Object *obj = OBJECT(dev);
> +
>          if (!qdev_set_parent_bus(dev, bus, errp)) {
>              return false;
>          }
> +
> +        if (!obj->parent) {
> +            static int count;
> +            g_autofree char *name = g_strdup_printf("x-%s[%d]",
> +                                                    object_get_typename(obj),
> +                                                    count++);
> +            object_property_add_child(OBJECT(bus), name, obj);
> +        }
>      } else {
>          assert(!DEVICE_GET_CLASS(dev)->bus_type);
>      }

As a quick test, I ran

    $ qemu-system-x86_64 -S -display none -nodefaults -monitor stdio
    QEMU 10.2.50 monitor - type 'help' for more information
    (qemu) info qom-tree

before and after.  Diff of output appended.

Observations:

* 24 of 25 device[*] move out of /machine/unattached/.  Remaining:

  - /device[0] (qemu64-x86_64-cpu) because it doesn't plug into a bus.

  - /sysbus (System)

  - A bunch of memory regions and irqs.  Some of them smell like sloppy
    modeling: ide[*].

* The moved device[i] get renamed to x-type-name[j].  The number changes
  because the type-name[*] use their own global counter.  Changing the
  number is fine, but I wonder whether a counter local to the parent
  would be better.  BusClass does that for "automatically allocated bus
  ids".

--- info-qom-tree@master        2026-02-19 08:43:03.732267517 +0100
+++ -   2026-02-19 08:43:43.562332914 +0100
@@ -37,6 +37,156 @@
     /pci-conf-data[0] (memory-region)
     /pci-conf-idx[0] (memory-region)
     /pci.0 (PCI)
+      /x-PIIX3[2] (PIIX3)
+        /bus master container[0] (memory-region)
+        /bus master[0] (memory-region)
+        /dma[0] (i8257)
+          /dma-chan[0] (memory-region)
+          /dma-cont[0] (memory-region)
+          /dma-page[0] (memory-region)
+          /dma-page[1] (memory-region)
+        /dma[1] (i8257)
+          /dma-chan[0] (memory-region)
+          /dma-cont[0] (memory-region)
+          /dma-page[0] (memory-region)
+          /dma-page[1] (memory-region)
+        /ide (piix3-ide)
+          /bmdma[0] (memory-region)
+          /bmdma[1] (memory-region)
+          /bus master container[0] (memory-region)
+          /bus master[0] (memory-region)
+          /ide.0 (IDE)
+          /ide.1 (IDE)
+          /piix-bmdma-container[0] (memory-region)
+          /piix-bmdma[0] (memory-region)
+          /piix-bmdma[1] (memory-region)
+        /isa.0 (ISA)
+          /x-i8042[9] (i8042)
+            /i8042-cmd[0] (memory-region)
+            /i8042-data[0] (memory-region)
+            /ps2-kbd-input-irq[0] (irq)
+            /ps2-mouse-input-irq[0] (irq)
+            /ps2kbd (ps2-kbd)
+            /ps2mouse (ps2-mouse)
+          /x-isa-fdc[8] (isa-fdc)
+            /fdc[0] (memory-region)
+            /fdc[1] (memory-region)
+            /floppy-bus.0 (floppy-bus)
+          /x-isa-i8259[3] (isa-i8259)
+            /elcr[0] (memory-region)
+            /pic[0] (memory-region)
+            /unnamed-gpio-in[0] (irq)
+            /unnamed-gpio-in[1] (irq)
+            /unnamed-gpio-in[2] (irq)
+            /unnamed-gpio-in[3] (irq)
+            /unnamed-gpio-in[4] (irq)
+            /unnamed-gpio-in[5] (irq)
+            /unnamed-gpio-in[6] (irq)
+            /unnamed-gpio-in[7] (irq)
+          /x-isa-i8259[4] (isa-i8259)
+            /elcr[0] (memory-region)
+            /pic[0] (memory-region)
+            /unnamed-gpio-in[0] (irq)
+            /unnamed-gpio-in[1] (irq)
+            /unnamed-gpio-in[2] (irq)
+            /unnamed-gpio-in[3] (irq)
+            /unnamed-gpio-in[4] (irq)
+            /unnamed-gpio-in[5] (irq)
+            /unnamed-gpio-in[6] (irq)
+            /unnamed-gpio-in[7] (irq)
+          /x-isa-pcspk[7] (isa-pcspk)
+            /pcspk[0] (memory-region)
+          /x-isa-pit[6] (isa-pit)
+            /pit[0] (memory-region)
+            /unnamed-gpio-in[0] (irq)
+          /x-port92[12] (port92)
+            /port92[0] (memory-region)
+          /x-vmmouse[11] (vmmouse)
+          /x-vmport[10] (vmport)
+            /vmport[0] (memory-region)
+        /piix-reset-control[0] (memory-region)
+        /pm (PIIX4_PM)
+          /acpi-cnt[0] (memory-region)
+          /acpi-cpu-hotplug[0] (memory-region)
+          /acpi-evt[0] (memory-region)
+          /acpi-gpe0[0] (memory-region)
+          /acpi-pci-hotplug[0] (memory-region)
+          /acpi-tmr[0] (memory-region)
+          /apm-io[0] (memory-region)
+          /bus master container[0] (memory-region)
+          /bus master[0] (memory-region)
+          /i2c (i2c-bus)
+            /x-smbus-eeprom[13] (smbus-eeprom)
+            /x-smbus-eeprom[14] (smbus-eeprom)
+            /x-smbus-eeprom[15] (smbus-eeprom)
+            /x-smbus-eeprom[16] (smbus-eeprom)
+            /x-smbus-eeprom[17] (smbus-eeprom)
+            /x-smbus-eeprom[18] (smbus-eeprom)
+            /x-smbus-eeprom[19] (smbus-eeprom)
+            /x-smbus-eeprom[20] (smbus-eeprom)
+          /piix4-pm[0] (memory-region)
+          /pm-smbus[0] (memory-region)
+        /rtc (mc146818rtc)
+          /rtc-index[0] (memory-region)
+          /rtc[0] (memory-region)
+      /x-i440FX[1] (i440FX)
+        /bus master container[0] (memory-region)
+        /bus master[0] (memory-region)
+        /pam-pci[0] (memory-region)
+        /pam-pci[10] (memory-region)
+        /pam-pci[11] (memory-region)
+        /pam-pci[12] (memory-region)
+        /pam-pci[13] (memory-region)
+        /pam-pci[14] (memory-region)
+        /pam-pci[15] (memory-region)
+        /pam-pci[16] (memory-region)
+        /pam-pci[17] (memory-region)
+        /pam-pci[18] (memory-region)
+        /pam-pci[19] (memory-region)
+        /pam-pci[1] (memory-region)
+        /pam-pci[20] (memory-region)
+        /pam-pci[21] (memory-region)
+        /pam-pci[22] (memory-region)
+        /pam-pci[23] (memory-region)
+        /pam-pci[24] (memory-region)
+        /pam-pci[25] (memory-region)
+        /pam-pci[2] (memory-region)
+        /pam-pci[3] (memory-region)
+        /pam-pci[4] (memory-region)
+        /pam-pci[5] (memory-region)
+        /pam-pci[6] (memory-region)
+        /pam-pci[7] (memory-region)
+        /pam-pci[8] (memory-region)
+        /pam-pci[9] (memory-region)
+        /pam-ram[0] (memory-region)
+        /pam-ram[10] (memory-region)
+        /pam-ram[11] (memory-region)
+        /pam-ram[12] (memory-region)
+        /pam-ram[1] (memory-region)
+        /pam-ram[2] (memory-region)
+        /pam-ram[3] (memory-region)
+        /pam-ram[4] (memory-region)
+        /pam-ram[5] (memory-region)
+        /pam-ram[6] (memory-region)
+        /pam-ram[7] (memory-region)
+        /pam-ram[8] (memory-region)
+        /pam-ram[9] (memory-region)
+        /pam-rom[0] (memory-region)
+        /pam-rom[10] (memory-region)
+        /pam-rom[11] (memory-region)
+        /pam-rom[12] (memory-region)
+        /pam-rom[1] (memory-region)
+        /pam-rom[2] (memory-region)
+        /pam-rom[3] (memory-region)
+        /pam-rom[4] (memory-region)
+        /pam-rom[5] (memory-region)
+        /pam-rom[6] (memory-region)
+        /pam-rom[7] (memory-region)
+        /pam-rom[8] (memory-region)
+        /pam-rom[9] (memory-region)
+        /smram-low[0] (memory-region)
+        /smram-region[0] (memory-region)
+        /smram[0] (memory-region)
   /peripheral (container)
   /peripheral-anon (container)
   /unattached (container)
@@ -46,162 +196,6 @@
       /memory[0] (memory-region)
       /memory[1] (memory-region)
       /smram[0] (memory-region)
-    /device[10] (i8042)
-      /i8042-cmd[0] (memory-region)
-      /i8042-data[0] (memory-region)
-      /ps2-kbd-input-irq[0] (irq)
-      /ps2-mouse-input-irq[0] (irq)
-      /ps2kbd (ps2-kbd)
-      /ps2mouse (ps2-mouse)
-    /device[11] (vmport)
-      /vmport[0] (memory-region)
-    /device[12] (vmmouse)
-    /device[13] (port92)
-      /port92[0] (memory-region)
-    /device[14] (smbus-eeprom)
-    /device[15] (smbus-eeprom)
-    /device[16] (smbus-eeprom)
-    /device[17] (smbus-eeprom)
-    /device[18] (smbus-eeprom)
-    /device[19] (smbus-eeprom)
-    /device[1] (kvmvapic)
-      /kvmvapic[0] (memory-region)
-    /device[20] (smbus-eeprom)
-    /device[21] (smbus-eeprom)
-    /device[2] (i440FX)
-      /bus master container[0] (memory-region)
-      /bus master[0] (memory-region)
-      /pam-pci[0] (memory-region)
-      /pam-pci[10] (memory-region)
-      /pam-pci[11] (memory-region)
-      /pam-pci[12] (memory-region)
-      /pam-pci[13] (memory-region)
-      /pam-pci[14] (memory-region)
-      /pam-pci[15] (memory-region)
-      /pam-pci[16] (memory-region)
-      /pam-pci[17] (memory-region)
-      /pam-pci[18] (memory-region)
-      /pam-pci[19] (memory-region)
-      /pam-pci[1] (memory-region)
-      /pam-pci[20] (memory-region)
-      /pam-pci[21] (memory-region)
-      /pam-pci[22] (memory-region)
-      /pam-pci[23] (memory-region)
-      /pam-pci[24] (memory-region)
-      /pam-pci[25] (memory-region)
-      /pam-pci[2] (memory-region)
-      /pam-pci[3] (memory-region)
-      /pam-pci[4] (memory-region)
-      /pam-pci[5] (memory-region)
-      /pam-pci[6] (memory-region)
-      /pam-pci[7] (memory-region)
-      /pam-pci[8] (memory-region)
-      /pam-pci[9] (memory-region)
-      /pam-ram[0] (memory-region)
-      /pam-ram[10] (memory-region)
-      /pam-ram[11] (memory-region)
-      /pam-ram[12] (memory-region)
-      /pam-ram[1] (memory-region)
-      /pam-ram[2] (memory-region)
-      /pam-ram[3] (memory-region)
-      /pam-ram[4] (memory-region)
-      /pam-ram[5] (memory-region)
-      /pam-ram[6] (memory-region)
-      /pam-ram[7] (memory-region)
-      /pam-ram[8] (memory-region)
-      /pam-ram[9] (memory-region)
-      /pam-rom[0] (memory-region)
-      /pam-rom[10] (memory-region)
-      /pam-rom[11] (memory-region)
-      /pam-rom[12] (memory-region)
-      /pam-rom[1] (memory-region)
-      /pam-rom[2] (memory-region)
-      /pam-rom[3] (memory-region)
-      /pam-rom[4] (memory-region)
-      /pam-rom[5] (memory-region)
-      /pam-rom[6] (memory-region)
-      /pam-rom[7] (memory-region)
-      /pam-rom[8] (memory-region)
-      /pam-rom[9] (memory-region)
-      /smram-low[0] (memory-region)
-      /smram-region[0] (memory-region)
-      /smram[0] (memory-region)
-    /device[3] (PIIX3)
-      /bus master container[0] (memory-region)
-      /bus master[0] (memory-region)
-      /dma[0] (i8257)
-        /dma-chan[0] (memory-region)
-        /dma-cont[0] (memory-region)
-        /dma-page[0] (memory-region)
-        /dma-page[1] (memory-region)
-      /dma[1] (i8257)
-        /dma-chan[0] (memory-region)
-        /dma-cont[0] (memory-region)
-        /dma-page[0] (memory-region)
-        /dma-page[1] (memory-region)
-      /ide (piix3-ide)
-        /bmdma[0] (memory-region)
-        /bmdma[1] (memory-region)
-        /bus master container[0] (memory-region)
-        /bus master[0] (memory-region)
-        /ide.0 (IDE)
-        /ide.1 (IDE)
-        /piix-bmdma-container[0] (memory-region)
-        /piix-bmdma[0] (memory-region)
-        /piix-bmdma[1] (memory-region)
-      /isa.0 (ISA)
-      /piix-reset-control[0] (memory-region)
-      /pm (PIIX4_PM)
-        /acpi-cnt[0] (memory-region)
-        /acpi-cpu-hotplug[0] (memory-region)
-        /acpi-evt[0] (memory-region)
-        /acpi-gpe0[0] (memory-region)
-        /acpi-pci-hotplug[0] (memory-region)
-        /acpi-tmr[0] (memory-region)
-        /apm-io[0] (memory-region)
-        /bus master container[0] (memory-region)
-        /bus master[0] (memory-region)
-        /i2c (i2c-bus)
-        /piix4-pm[0] (memory-region)
-        /pm-smbus[0] (memory-region)
-      /rtc (mc146818rtc)
-        /rtc-index[0] (memory-region)
-        /rtc[0] (memory-region)
-    /device[4] (isa-i8259)
-      /elcr[0] (memory-region)
-      /pic[0] (memory-region)
-      /unnamed-gpio-in[0] (irq)
-      /unnamed-gpio-in[1] (irq)
-      /unnamed-gpio-in[2] (irq)
-      /unnamed-gpio-in[3] (irq)
-      /unnamed-gpio-in[4] (irq)
-      /unnamed-gpio-in[5] (irq)
-      /unnamed-gpio-in[6] (irq)
-      /unnamed-gpio-in[7] (irq)
-    /device[5] (isa-i8259)
-      /elcr[0] (memory-region)
-      /pic[0] (memory-region)
-      /unnamed-gpio-in[0] (irq)
-      /unnamed-gpio-in[1] (irq)
-      /unnamed-gpio-in[2] (irq)
-      /unnamed-gpio-in[3] (irq)
-      /unnamed-gpio-in[4] (irq)
-      /unnamed-gpio-in[5] (irq)
-      /unnamed-gpio-in[6] (irq)
-      /unnamed-gpio-in[7] (irq)
-    /device[6] (hpet)
-      /hpet[0] (memory-region)
-      /unnamed-gpio-in[0] (irq)
-      /unnamed-gpio-in[1] (irq)
-    /device[7] (isa-pit)
-      /pit[0] (memory-region)
-      /unnamed-gpio-in[0] (irq)
-    /device[8] (isa-pcspk)
-      /pcspk[0] (memory-region)
-    /device[9] (isa-fdc)
-      /fdc[0] (memory-region)
-      /fdc[1] (memory-region)
-      /floppy-bus.0 (floppy-bus)
     /ide[0] (memory-region)
     /ide[1] (memory-region)
     /ide[2] (memory-region)
@@ -243,5 +237,11 @@
     /pci[0] (memory-region)
     /ram-below-4g[0] (memory-region)
     /sysbus (System)
+      /x-hpet[5] (hpet)
+        /hpet[0] (memory-region)
+        /unnamed-gpio-in[0] (irq)
+        /unnamed-gpio-in[1] (irq)
+      /x-kvmvapic[0] (kvmvapic)
+        /kvmvapic[0] (memory-region)
     /system[0] (memory-region)


Reply via email to