On Sat, Jun 22, 2024 at 1:43 AM Markus Armbruster <arm...@redhat.com> wrote:

> Patrick Leis <vent...@google.com> writes:
>
> > Corey and Peter,
> >
> > My team builds lots of configurations for Qemu boards, and one pain point
> > has been that the qom path for a device depends on the device insertion
> > order, child[0], child[1] and the like.
>
> Yes.
>
> Discussed in my "Dynamic & heterogeneous machines, initial
> configuration: problems" memo, under "Problem 4: The
> /machine/unattached/ orphanage".
>
> Copy of the "Problem 4" part appended for your your convenience.  Full
> memo archived at
> https://lore.kernel.org/qemu-devel/87o7d1i7ky....@pond.sub.org/
>
> >                                          I noticed that the qdev paths
> for
> > devices also exist by their device id property.  By default, this ends up
> > being the device type name.
>
> Which kind of devices?
>
> There are onboard devices and user-created devices.
>
> A user-created device's QOM path is "/machine/peripheral/ID" when it was
> created with a qdev ID, and "/machine/peripheral-anon/device[N]" (where
> N counts up from zero) when it was created without a qdev ID.  N depends
> on creation order, which is under the user's control.  Users can and
> should avoid relying on their order by supplying an ID.
>
> An onboard device's QOM path is chosen by board code.  For instance, q35
> puts the mch device at "/machine/q35/mch".  However, if the board code
> neglects to put the device anywhere, the system puts it at
> "/machine/unattached/device[N]" (where N counts up from zero).  N
> depends on creation order.
>
> N can change at the drop of a hat.  Whether "device[N]" is a stable
> interface is unclear.  It would clearly be a bad one.
>
> If (part of) your problem is "/machine/peripheral-anon/device[N]",
> supply IDs to bypass it.
>
> If (part of) your problem is "/machine/unattached/device[N]", all I can
> offer is the proper solution: fix the board code to put the device in
> its proper place instead of abandoning it to the "/machine/unattached/"
> orphanage.
>
> >                              I was wondering if it made sense to override
> > this with the device type plus the smbus address?  I did something
> similar
> > with the i2c mux device, to resolve part of this issue.
>
> I doubt it.
>
> Questions?
>
>
>
> = Problem 4: The /machine/unattached/ orphanage =
>
> Is it okay for a QOM object to have no parent?
>
> An object without a parent is not part of the composition tree; it has
> no canonical path, and object_get_canonical_path() returns null.
>
> Such objects can behave in wonky ways.  For instance,
> object_property_set_link() treats a target object without a parent as
> null.  If a linked object somehow loses its parent,
> object_property_get_link() will return null even though the underlying C
> pointer still points to the poor orphan.
>
> This strongly suggests QOM was designed with the assumption that objects
> always have a parent, except during initialization (before they are
> connected to anything) and finalization (when no longer connected to
> anything).  object_property_try_add_child()'s contract seems to confirm
> this:
>
>  * Child properties form the composition tree.  All objects need to be a
> child
>  * of another object.  Objects can only be a child of one object.
>
> Some functions to create objects take the new object's parent as a
> parameter.  Example: object_new_with_props(), object_new_with_propv(),
> clock_new(), ...
>
> Others set a fixed parent.  For instance, we always add character
> backends to "/chardevs/", objects created with object-add in
> "/objects/", devices created with device_add in "/machine/peripheral/"
> (with ID) or "/machine/peripheral-anon/" (without ID), ...
>
> There are also functions that don't set a parent: object_new(),
> object_new_with_class(), qdev_new(), qdev_try_new(), ...  Setting a
> parent is the callers job then.  Invites misuse.  I'm aware of one
> instance: @current_migration remains without a parent forever.
>
> Not all callers care to set a parent themselves.  Instead, they rely on
> the "/machine/unattached/" orphanage:
>
> * qdev_connect_gpio_out_named() needs the input pin to have a parent.
>   If it lacks one, it gets added to "/machine/unattached/" with a
>   made-up name.
>
> * device_set_realized() ensures realized devices have a parent by adding
>   devices lacking one to "/machine/unattached/" with a made-up name.
>
> * portio_list_add() adds a memory region.  If the caller doesn't specify
>   the parent, "/machine/unattached/" is assumed.
>
> * memory_region_init() adds a memory region, and may set the parent.  If
>   the caller requests setting a parent without specifying one,
>   "/machine/unattached/" is assumed.
>
> * qemu_create_machine() adds the main system bus to
>   "/machine/unattached/".
>
> Except for the last one, the child names depend on execution order.  For
> instance, device_set_realized() uses "device[N]", where N counts up from
> zero.
>
> These brittle, made-up names are visible in QMP QOM introspection.
> Whether that's a stable interface is unclear.  Better not.
>
> We don't rely on these names in C.  We follow pointers instead.
>
> When we replace C code by configuration, we switch from pointers to
> names.  Brittle names become a problem.
>

Thank you for the explanation and related documentation.

Reply via email to