On Mon, 13 Jul 2026 at 12:21, Akihiko Odaki <[email protected]> wrote: > > On 2026/07/13 18:13, Peter Maydell wrote: > > On Mon, 29 Jun 2026 at 09:18, Akihiko Odaki > > <[email protected]> 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. > > > > Thanks for sending this. I think we definitely need to try to be > > clearer about what to do in instance_init and what to do in realize. > > > >> Signed-off-by: Akihiko Odaki <[email protected]> > > > >> * 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 via the #DeviceState.realized property > >> + * > >> + * #TypeInfo.instance_init may not fail, and realization may return > >> + * error information to the caller and must be re-entrant. > > > > I know this is in the existing text, but what do we mean by > > "must be re-entrant" here ? Does this mean "even if you return > > a failure from your realize method you must be able to handle the > > caller retrying the realize operation" ? (I'm not sure why that's > > a useful thing for the caller to be able to do...)> > > I assume we don't mean "even if you successfully realize you must > > handle (and treat as a no-op) a second call to realize", because > > none of our devices do that :-) > > If you take the code literally, device_set_realized() indeed avoids > calling realize after successful realization, but it doesn't report an > error when retrying, so I think this means to allow that. > > I don't think it's that useful, and it is likely to cause bunch of bugs. > I can also imagine that careful developers have written device code that > preserves this contract, though the added complexity is useless in practice. > > In my opinion, the property should be tristate: initialized, realized, > or retired. Then we would have only the following state transitions: > > Successful realization: initialized -> realized > Failed realization: initialized -> retired > Unrealization: realized -> retired > > This is another opportunity for refactoring, but for this particular > patch I'm planning to keep it out of scope.
OK. We could make the text clearer then, I think. Maybe "#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." ? > > > >> + * #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 > >> + * device introspection. > >> * After successful realization, setting static properties will fail. > >> * > >> * As an interim step, the #DeviceState.realized property can also be > >> @@ -40,9 +43,8 @@ > >> * 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. > >> + * initialize them via #TypeInfo.instance_init and forward the > >> + * realization events appropriately. > > > > This change doesn't seem to me to match the paragraph it's in. > > The intent of the paragraph is clearly "initialize child objects in > > your own instance_init method", so we want to say "in" the method. > > "via" here is for "how you do it"; we could make that say > > "initialize them (e.g. by calling object_initialize())" to be > > a bit clearer, something like: > > > > "Therefore > > devices must 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." > > That looks better. I'll use it for the next version. > > > > > This whole paragraph is one of those we sometimes like to put in, > > which is sketching out a design idea or direction we have not > > actually managed to achieve. So it's part aspiration and part > > reality. In particular, the flat "must not create children during > > realize" statement clashes with "operations depending on static > > properties should go into realize", because occasionally we need > > to create or not create children based on the value of a property... > > Honestly I would just replace "must" with "should". Hopefully people > would understand. We could maybe say "should not" and add an extra sentence at the end: "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." -- PMM
