From: Akihiko Odaki <[email protected]> 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 instance property setting and device introspection. The fact that initial instance 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 may 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. - Instance properties added during realization will not be configurable or introspectable before realization. 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. The statements regarding a future prospect to propagate the realization state change are removed. Device realization is propagated to child buses, but not to the devices on those buses. The proposed recursive propagation to child devices has not been achieved after 13 years, has been questioned [1], and is not relevant with the current API usage. [1] https://lore.kernel.org/qemu-devel/[email protected]/ Signed-off-by: Akihiko Odaki <[email protected]> Reviewed-by: Peter Maydell <[email protected]> Message-ID: <[email protected]> Signed-off-by: Philippe Mathieu-Daudé <[email protected]> --- include/hw/core/qdev.h | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/include/hw/core/qdev.h b/include/hw/core/qdev.h index 1f6bf3fc1ab..8e91e2fcb08 100644 --- a/include/hw/core/qdev.h +++ b/include/hw/core/qdev.h @@ -23,28 +23,27 @@ * Realization * ----------- * - * Devices are constructed in two stages: + * Devices are constructed in the following order: * - * 1) object instantiation via object_initialize() and - * 2) device realization via the #DeviceState.realized property + * 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, and must be re-entrant. + * + * #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. Any operations without special requirements + * should go into @realize so that they can be skipped during device + * introspection. It is possible to add properties during realization, + * but they will not be introspectable or configurable before realization. + * + * Child buses are automatically realized. Child devices must be manually + * realized (e.g. by calling qdev_realize()). * - * 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. * 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. - * * Any type may override the @realize and/or @unrealize callbacks but needs * to call the parent type's implementation if keeping their functionality * is desired. Refer to QOM documentation for further discussion and examples. @@ -102,10 +101,8 @@ typedef int (*DeviceSyncConfig)(DeviceState *dev, Error **errp); /** * struct DeviceClass - The base class for all devices. * @props: Properties accessing state fields. - * @realize: Callback function invoked when the #DeviceState:realized - * property is changed to %true. - * @unrealize: Callback function invoked when the #DeviceState:realized - * property is changed to %false. + * @realize: Callback function to realize the device. + * @unrealize: Callback function to unrealize the device. * @sync_config: Callback function invoked when QMP command device-sync-config * is called. Should synchronize device configuration from host to guest part * and notify the guest about the change. -- 2.53.0
