qdev currently represents a device's realization state with a single boolean. This cannot distinguish a device that has never been realized from one whose realization has failed or that has been unrealized, nor can it represent realization in progress. Consequently, the same device can enter DeviceClass::realize() reentrantly or more than once. Supporting that complicates device implementations, and the behavior is untested and likely broken.
This series first clarifies the division of work between TypeInfo.instance_init, pre-realize property setting, and DeviceClass::realize, including the implications of device introspection and property-dependent child creation. The remaining direct reads of DeviceState::realized are then converted to qdev_is_realized(). Keeping users behind this accessor allows the underlying lifecycle representation to change without exposing it; the accessor is also made const so callers with a const DeviceState can use it. Before changing that representation, the series fixes an existing qdev invariant. qdev_realize() can attach an unparented device to a bus before giving it a QOM parent. A failure between those operations leaves a bus child that object_unparent() cannot remove, causing bus_unparent() to loop indefinitely. qdev_realize() now establishes the QOM parent before attaching the device to its bus and rolls the parent back on failure. Finally, DeviceState::realized and the QOM realized property are replaced with four explicit phases: initialized, realizing, realized, and retired. Entering the realizing phase before invoking callbacks prevents reentrant realization. A failure after realization starts, or the start of unrealization, moves the device to the terminal retired phase, so a device's realize method is invoked at most once. Signed-off-by: Akihiko Odaki <[email protected]> --- Changes in v3: - Ensured devices are QOM-parented before attaching them to a bus, avoiding unparentable bus children when realization fails. - Clarified property-dependent child creation. - Removed documentation references to the QOM realized property. - Replaced DeviceState::realized and the QOM realized property with device phases. The realizing phase prevents reentrant realization, and the terminal retired phase prevents another attempt after realization fails or unrealization begins. - Link to v2: https://lore.kernel.org/qemu-devel/[email protected] Changes in v2: - Clarified the ordering of #TypeInfo.instance_init, pre-realize property setting, and realization. - Clarified that #TypeInfo.instance_init is for per-instance properties, not class properties. - Link to v1: https://lore.kernel.org/qemu-devel/[email protected] --- Akihiko Odaki (15): qdev: Clarify instantiation and realization qdev: Make qdev_is_realized() take a const DeviceState * hw/hyperv/balloon: Use qdev_is_realized() hw/intc/apic: Use qdev_is_realized() hw/mem/memory-device: Use qdev_is_realized() hw/mem/pc-dimm: Use qdev_is_realized() hw/nvram: Use qdev_is_realized() hw/ppc/pnv_xscom: Use qdev_is_realized() hw/vfio: Use qdev_is_realized() hw/virtio/virtio-mem: Use qdev_is_realized() hw/virtio/virtio-qmp: Use qdev_is_realized() target/i386/cpu: Use qdev_is_realized() target/s390x: Use qdev_is_realized() hw/qdev: Parent device before setting parent bus hw/qdev: Prevent devices from being realized more than once qapi/common.json | 19 ++++++ include/hw/core/qdev.h | 62 ++++++++++--------- hw/core/qdev-clock.c | 4 +- hw/core/qdev-properties.c | 4 +- hw/core/qdev.c | 147 ++++++++++++++++++++++++++++----------------- hw/hyperv/hv-balloon.c | 2 +- hw/intc/apic_common.c | 2 +- hw/mem/memory-device.c | 4 +- hw/mem/pc-dimm.c | 2 +- hw/nvram/xlnx-bbram.c | 2 +- hw/nvram/xlnx-efuse.c | 2 +- hw/ppc/pnv_xscom.c | 2 +- hw/scsi/scsi-bus.c | 4 +- hw/vfio/container-legacy.c | 4 +- hw/vfio/device.c | 4 +- hw/vfio/iommufd.c | 2 +- hw/virtio/virtio-mem.c | 4 +- hw/virtio/virtio-qmp.c | 4 +- qom/qom-qmp-cmds.c | 2 +- system/qdev-monitor.c | 5 +- target/i386/cpu.c | 2 +- target/s390x/cpu_models.c | 4 +- tests/unit/test-qdev.c | 125 +++++++++++++++++++++++++++++++++++++- 23 files changed, 301 insertions(+), 111 deletions(-) --- base-commit: 499039798cdad7d86b787fec0eaf1da4151c0f05 change-id: 20250906-qdev-9e5cb7c06ffa Best regards, -- Akihiko Odaki <[email protected]>
