Re: [PATCH for-11.2 v3 01/15] qdev: Clarify instantiation and realization
Akihiko Odaki <[email protected]>
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
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