From: Markus Armbruster <armbru@redhat.com>
To: Peter Xu <peterx@redhat.com>
Cc: qemu-devel@nongnu.org, "Fabiano Rosas" <farosas@suse.de>,
"Igor Mammedov" <imammedo@redhat.com>,
"Juraj Marcin" <jmarcin@redhat.com>,
"Michael S . Tsirkin" <mst@redhat.com>,
"Dr . David Alan Gilbert" <dave@treblig.org>,
"Cédric Le Goater" <clg@redhat.com>,
"Eduardo Habkost" <eduardo@habkost.net>,
"Daniel P . Berrangé" <berrange@redhat.com>,
"Alex Williamson" <alex.williamson@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Peter Maydell" <peter.maydell@linaro.org>
Subject: Re: [PATCH 2/4] x86/iommu: Make x86-iommu a singleton object
Date: Thu, 07 Nov 2024 12:12:10 +0100 [thread overview]
Message-ID: <87jzdfl2lx.fsf@pond.sub.org> (raw)
In-Reply-To: <ZxwYBeLGDLkTL0PJ@x1n> (Peter Xu's message of "Fri, 25 Oct 2024 18:13:25 -0400")
Peter Xu <peterx@redhat.com> writes:
> On Fri, Oct 25, 2024 at 05:55:59PM -0400, Peter Xu wrote:
>> On Fri, Oct 25, 2024 at 11:25:23AM +0200, Markus Armbruster wrote:
>> > Peter Xu <peterx@redhat.com> writes:
>> >
>> > > X86 IOMMUs cannot be created more than one on a system yet. Make it a
>> > > singleton so it guards the system from accidentally create yet another
>> > > IOMMU object when one already presents.
>> > >
>> > > Now if someone tries to create more than one, e.g., via:
>> > >
>> > > ./qemu -M q35 -device intel-iommu -device intel-iommu
>> > >
>> > > The error will change from:
>> > >
>> > > qemu-system-x86_64: -device intel-iommu: QEMU does not support multiple vIOMMUs for x86 yet.
>> > >
>> > > To:
>> > >
>> > > qemu-system-x86_64: -device intel-iommu: Class 'intel-iommu' only supports one instance
>> > >
>> > > Unfortunately, yet we can't remove the singleton check in the machine
>> > > hook (pc_machine_device_pre_plug_cb), because there can also be
>> > > virtio-iommu involved, which doesn't share a common parent class yet.
>> > >
>> > > But with this, it should be closer to reach that goal to check singleton by
>> > > QOM one day.
>> > >
>> > > Signed-off-by: Peter Xu <peterx@redhat.com>
>> >
>> > $ qemu-system-x86_64 -device amd-iommu,help
>> > /work/armbru/qemu/include/hw/boards.h:24:MACHINE: Object 0x56473906f960 is not an instance of type machine
>> > Aborted (core dumped)
[...]
>> Thanks for the report!
>>
>> It turns out that qdev_get_machine() cannot be invoked too early, and the
>> singleton code can make it earlier..
>>
>> We may want a pre-requisite patch to allow qdev_get_machine() to be invoked
>> anytime, like:
>>
>> ===8<===
>> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
>> index db36f54d91..7ceae47139 100644
>> --- a/hw/core/qdev.c
>> +++ b/hw/core/qdev.c
>> @@ -831,6 +831,16 @@ Object *qdev_get_machine(void)
>> {
>> static Object *dev;
>>
>> + if (!phase_check(PHASE_MACHINE_CREATED)) {
>> + /*
>> + * When the machine is not created, below can wrongly create
>> + * /machine to be a container.. this enables qdev_get_machine() to
>> + * be used at any time and return NULL properly when machine is not
>> + * created.
>> + */
>> + return NULL;
>> + }
>> +
>> if (dev == NULL) {
>> dev = container_get(object_get_root(), "/machine");
>> }
>> ===8<===
>>
>> I hope it makes sense on its own.
>
> My apologies, spoke too soon here. This helper is used too after machine
> is created, but right before switching to PHASE_MACHINE_CREATE stage..
container_get() is a trap.
When the object to be gotten is always "container", it merely
complicates container creation: it's implicitly created on first get.
Which of the calls creates may be less than obvious.
When the object to be gotten is something else, such as a machine,
container_get() before creation is *wrong*, and will lead to trouble
later.
In my opinion:
* Hiding creation in getters is a bad idea unless creation has no
material side effects.
* Getting anything but a container with container_get() is in bad taste.
> So we need another way, like:
>
> ===8<===
>
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index db36f54d91..36a9fdb428 100644
> --- a/hw/core/qdev.c
> +++ b/hw/core/qdev.c
> @@ -832,7 +832,13 @@ Object *qdev_get_machine(void)
> static Object *dev;
>
> if (dev == NULL) {
> - dev = container_get(object_get_root(), "/machine");
> + /*
> + * NOTE: dev can keep being NULL if machine is not yet created!
> + * In which case the function will properly return NULL.
> + *
> + * Whenever machine object is created and found once, we cache it.
> + */
> + dev = object_resolve_path_component(object_get_root(), "machine");
> }
>
> return dev;
Now returns null instead of a bogus container when called before machine
creation. Improvement of sorts. But none of the callers expect null...
shouldn't we assert(dev) here?
Hmm, below you add a caller that checks for null.
Another nice mess.
> ===8<===
>
> The idea is still the same. Meanwhile I'll test more to see whether it has
> other issues.
>
> Thanks,
>
>> Then callers who can be invoked earlier
>> could then handle NULL properly, in this case..
>>
>> ===8<===
>> diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c
>> index 4bfeb08705..fceb7adfe0 100644
>> --- a/hw/i386/x86-iommu.c
>> +++ b/hw/i386/x86-iommu.c
>> @@ -80,9 +80,15 @@ void x86_iommu_irq_to_msi_message(X86IOMMUIrq *irq, MSIMessage *msg_out)
>>
>> X86IOMMUState *x86_iommu_get_default(void)
>> {
>> - MachineState *ms = MACHINE(qdev_get_machine());
>> - PCMachineState *pcms =
>> - PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE));
>> + Object *machine = qdev_get_machine();
>> + PCMachineState *pcms;
>> +
>> + /* If machine has not been created, so is the vIOMMU */
>> + if (!machine) {
>> + return NULL;
>> + }
>> +
>> + pcms = PC_MACHINE(object_dynamic_cast(machine, TYPE_PC_MACHINE));
>>
>> if (pcms &&
>> object_dynamic_cast(OBJECT(pcms->iommu), TYPE_X86_IOMMU_DEVICE)) {
>> ===8<===
>>
>> I'll make sure this works if I'll repost.
>>
>> Thanks,
>>
>> --
>> Peter Xu
next prev parent reply other threads:[~2024-11-07 11:12 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-24 16:56 [PATCH 0/4] QOM: Singleton interface Peter Xu
2024-10-24 16:56 ` [PATCH 1/4] qom: TYPE_SINGLETON interface Peter Xu
2024-10-24 20:02 ` Philippe Mathieu-Daudé
2024-10-24 20:53 ` Peter Xu
2024-10-25 15:11 ` Philippe Mathieu-Daudé
2024-10-25 16:21 ` Peter Xu
2024-10-25 8:07 ` Markus Armbruster
2024-10-25 15:17 ` Peter Xu
2024-10-25 9:51 ` Daniel P. Berrangé
2024-10-25 16:17 ` Peter Xu
2024-10-25 16:22 ` Daniel P. Berrangé
2024-10-25 22:10 ` Peter Xu
2024-10-29 0:01 ` Peter Xu
2024-10-25 16:37 ` Peter Xu
2024-10-24 16:56 ` [PATCH 2/4] x86/iommu: Make x86-iommu a singleton object Peter Xu
2024-10-25 9:25 ` Markus Armbruster
2024-10-25 21:55 ` Peter Xu
2024-10-25 22:13 ` Peter Xu
2024-11-07 11:12 ` Markus Armbruster [this message]
2024-11-07 15:29 ` Peter Xu
2024-11-08 8:50 ` Markus Armbruster
2024-10-29 10:47 ` Daniel P. Berrangé
2024-10-29 14:32 ` Peter Xu
2024-10-24 16:56 ` [PATCH 3/4] migration: Make migration object " Peter Xu
2024-10-24 19:20 ` Fabiano Rosas
2024-10-24 16:56 ` [PATCH 4/4] migration: Reset current_migration properly Peter Xu
2024-10-24 19:34 ` Fabiano Rosas
2024-10-24 20:15 ` Peter Xu
2024-10-24 20:51 ` Fabiano Rosas
2024-10-25 7:38 ` [PATCH 0/4] QOM: Singleton interface Markus Armbruster
2024-10-25 15:01 ` Peter Xu
2024-10-29 10:42 ` Daniel P. Berrangé
2024-10-29 14:45 ` Peter Xu
2024-10-29 16:04 ` Daniel P. Berrangé
2024-10-29 17:05 ` Peter Xu
2024-10-29 17:17 ` Daniel P. Berrangé
2024-12-11 8:19 ` Markus Armbruster
2024-12-11 22:10 ` Peter Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87jzdfl2lx.fsf@pond.sub.org \
--to=armbru@redhat.com \
--cc=alex.williamson@redhat.com \
--cc=berrange@redhat.com \
--cc=clg@redhat.com \
--cc=dave@treblig.org \
--cc=eduardo@habkost.net \
--cc=farosas@suse.de \
--cc=imammedo@redhat.com \
--cc=jmarcin@redhat.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=peterx@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.