On 2026/07/21 20:14, BALATON Zoltan wrote:
On Tue, 21 Jul 2026, Akihiko Odaki wrote:
The distinction of instantiation and realization was vague in the old
documentation so this change clarifies it.

The old documentation said:
The former may not fail (and must not abort or exit, since it is
called during device introspection already), and the latter may return
error information to the caller and must be re-entrant.
Trivial field initializations should go into #TypeInfo.instance_init.
Operations depending on @props static properties should go into
@realize.

The first problem with the old documentation is that it is unclear what
"trivial field initializations" means and why triviality makes
initialization appropriate for #TypeInfo.instance_init. Another problem
is that the documentation is not comprehensive enough; for example, it
mentions @props static properties, but it does not say anything about
the other properties.

The keys to distinguish instantiation and realization are property
setting and device introspection. The fact that property setting happens
after #TypeInfo.instance_init and before realization implies that
operations depending on properties should go into @realize.

The fact that instantiation happens during device introspection but
realization does not implies:
- Instance properties should be added in #TypeInfo.instance_init.
- Instantiation must not have any side effect not contained in the
 instance.
- Any operations without special requirements should go into @realize so
 that they can be skipped during device introspection.

Note these two facts to guide appropriate instantiation and realization.

We also omit mention of the realized property because it is a QOM
interface detail, not part of the device API.

Signed-off-by: Akihiko Odaki <[email protected]>
---
include/hw/core/qdev.h | 52 +++++++++++++++++++++++++++ +----------------------
1 file changed, 29 insertions(+), 23 deletions(-)

diff --git a/include/hw/core/qdev.h b/include/hw/core/qdev.h
index e14762234115..aba7072131c4 100644
--- a/include/hw/core/qdev.h
+++ b/include/hw/core/qdev.h
@@ -22,27 +22,35 @@
 * Realization
 * -----------
 *
- * Devices are constructed in two stages:
- *
- * 1) object instantiation via object_initialize() and
- * 2) device realization via the #DeviceState.realized property
- *
- * The former may not fail (and must not abort or exit, since it is called
- * during device introspection already), and the latter may return error
- * information to the caller and must be re-entrant.
- * Trivial field initializations should go into #TypeInfo.instance_init.
- * Operations depending on @props static properties should go into @realize.
+ * Devices are constructed in the following order:
+ *
+ * 1) #TypeInfo.instance_init
+ * 2) pre-realize property value setting
+ * 3) device realization
+ *
+ * #TypeInfo.instance_init may not fail. #DeviceClass.realize can
+ * fail, returning error information to the caller. A device realize
+ * method should handle being called again after it has failed once.

Doesn't the last patch in this series contradict this sentence? Maybe it should be removed and say instead that after failed realize the object can only be destroyed, no other methods can be called.

The last patch updates it.


+ * #TypeInfo.instance_init should add instance properties but must not
+ * have any side effect not contained in the instance, since it happens
+ * during device introspection already. Any operations without special
+ * requirements should go @realize so that they can be skipped during

You need something between go and @realize such as to or into?

This is another existing quirk, but we can fix it now.


+ * device introspection.
 * After successful realization, setting static properties will fail.
 *
- * As an interim step, the #DeviceState.realized property can also be
- * set with qdev_realize(). In the future, devices will propagate this
- * state change to their children and along busses they expose. The
- * point in time will be deferred to machine creation, so that values
- * set in @realize will not be introspectable beforehand. Therefore
- * devices must not create children during @realize; they should
- * initialize them via object_initialize() in their own
- * #TypeInfo.instance_init and forward the realization events
- * appropriately.
+ * In the future, devices will propagate this state change to their
+ * children and along busses they expose. The point in time will be
+ * deferred to machine creation, so that values set in @realize will not
+ * be introspectable beforehand. Therefore devices should not create
+ * children during @realize; they should initialize them (e.g. by
+ * calling object_initialize_child()) in their own
+ * #TypeInfo.instance_init method, and then realize them (e.g. by
+ * calling qdev_realize()) in their own #DeviceClass.realize method.

This complicates devices...

+ * Occasionally a device may need to decide whether or not to create
+ * a child object based on the value of a property. In this case it
+ * will need to both create and realize the child in its realize method,
+ * because the property value is not known until that point.

...and not always possible. So can we relax this so that only children that add properties that need to be introspectable and settable has to be created in init and otherwise it can be deferred to realize? That way most simple devices don't need an init method at all. I'd really say by default do everyting in realize unless it needs to be available before realize such as properties that change what realize does and avoid splitting creating objects between init and realize when not absolutely needed.

I remember that there was a similar discussion regarding the timing to call memory_region_init(), and I don't have a strong opinion here, so I'll relax this requirement unless someone suggests otherwise.

Regards,
Akihiko Odaki

Reply via email to