All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>
To: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>, qemu-devel@nongnu.org
Cc: "BALATON Zoltan" <balaton@eik.bme.hu>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Daniel P. Berrangé" <berrange@redhat.com>,
	"Eduardo Habkost" <eduardo@habkost.net>,
	"Maciej S. Szmigiero" <maciej.szmigiero@oracle.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"David Hildenbrand" <david@kernel.org>,
	"Igor Mammedov" <imammedo@redhat.com>,
	"FangSheng Huang" <FangSheng.Huang@amd.com>,
	"Alistair Francis" <alistair@alistair23.me>,
	"Edgar E. Iglesias" <edgar.iglesias@gmail.com>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	qemu-arm@nongnu.org, "Nicholas Piggin" <npiggin@gmail.com>,
	"Aditya Gupta" <adityag@linux.ibm.com>,
	"Glenn Miles" <milesg@linux.ibm.com>,
	"Harsh Prateek Bora" <harshpb@linux.ibm.com>,
	qemu-ppc@nongnu.org, "Alex Williamson" <alex@shazbot.org>,
	"Cédric Le Goater" <clg@redhat.com>,
	"Zhao Liu" <zhao1.liu@intel.com>,
	"Hendrik Brueckner" <brueckner@linux.ibm.com>,
	"Richard Henderson" <richard.henderson@linaro.org>,
	"Ilya Leoshkevich" <iii@linux.ibm.com>,
	"Cornelia Huck" <cohuck@redhat.com>,
	"Eric Farman" <farman@linux.ibm.com>,
	"Matthew Rosato" <mjrosato@linux.ibm.com>,
	qemu-s390x@nongnu.org, "Luc Michel" <luc@lmichel.fr>,
	"Fam Zheng" <fam@euphon.net>, "Eric Blake" <eblake@redhat.com>,
	"Markus Armbruster" <armbru@redhat.com>
Subject: Re: [PATCH for-11.2 v3 15/15] hw/qdev: Prevent devices from being realized more than once
Date: Wed, 22 Jul 2026 11:57:36 +0200	[thread overview]
Message-ID: <8d979f89-374a-4b86-93c8-9d7dcc311ca6@oss.qualcomm.com> (raw)
In-Reply-To: <a5597a0e-c18c-4649-bfd1-20d77897ff88@rsg.ci.i.u-tokyo.ac.jp>

On 22/7/26 07:12, Akihiko Odaki wrote:
> On 2026/07/22 5:11, Philippe Mathieu-Daudé wrote:
>> Hi Akihiko,
>>
>> On 21/7/26 10:17, Akihiko Odaki wrote:
>>> qdev currently permits reentrant realization of the same device. It also
>>> permits another realization attempt after a device has been unrealized
>>> or a previous attempt has failed. Either path can invoke
>>> DeviceClass::realize() more than once. Supporting repeated realization
>>> adds complexity to device implementations. It is untested and likely
>>> broken.
>>>
>>> Replace the bool DeviceState::realized field with the enum-valued
>>> DeviceState::phase field. The enum has four values:
>>>
>>> - initialized
>>> - realizing
>>> - realized
>>> - retired
>>
>> Excellent.
>>
>> I have been working on something similar.
>>
>> I'd start the first patch only including:
>>
>> DEVICE_PHASE_UNREALIZED (false)
>> DEVICE_PHASE_REALIZED (true)
>>
>> Then gradually rename DEVICE_PHASE_REALIZED -> DEVICE_PHASE_CREATED
>> and add the DEVICE_PHASE_REALIZING and DEVICE_PHASE_RETIRED phases,
>> so we can discuss them during the review process.
> 
> A gradual conversion makes sense. I kept the "realized" phase as-is 
> because it maps exactly to the current external behavior. This patch 
> splits the internal "unrealized" state into three distinct phases, but 
> the external concept of being "realized" remains unchanged. This allows 
> us to avoid a tree-wide refactoring, which is also why 
> qdev_is_realized() is preserved.
> 
>>
>>> Realization can start only in the initialized phase. It moves the device
>>> to the realizing phase before invoking callbacks, preventing another
>>> realization attempt. Successful realization moves it to the realized
>>> phase; failure after realization has started moves it to the retired
>>> phase. Unrealization also moves a realized device to the retired phase.
>>
>> So what is the difference between 'initialized' and 'retired'?
> 
> The first statement in this paragraph differentiates 'initialized' from 
> everything else: realization can start only in the initialized phase. A 
> 'retired' device cannot be realized. This property avoids re-entrancy.

But we do use unrealize -> realize again, in hotplug path.

So we need to be able to move from 'retired' to 'realizing'
again, thus my wonder what is the difference between 'realizing'
and 'initialized'.

I.e. this test should pass:

static void test_qdev_realize_hotplug(void)
{
     Object *mt = object_new(TYPE_MY_DEV);

     /* plug */
     g_assert_false(qdev_realize(DEVICE(mt), NULL, NULL));

     /* unplug */
     qdev_unrealize(DEVICE(mt));

     /* re-plug */
     g_assert_false(qdev_realize(DEVICE(mt), NULL, NULL));
     qdev_unrealize(DEVICE(mt));
     object_unparent(mt);
     object_unref(mt);
}

Maybe your 'retired' could be renamed as transient 'unrealizing',
similar to 'realizing' phase, then we could transition to the
'unrealized' initial phase?

> 
>>
>>> The QOM realized property is an internal lifecycle property, not for
>>> end users. Replace it with the enum-valued phase property.
>>>
>>> Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
>>> ---
>>>   qapi/common.json          |  19 ++++++++
>>>   include/hw/core/qdev.h    |  12 ++---
>>>   hw/core/qdev-clock.c      |   4 +-
>>>   hw/core/qdev-properties.c |   4 +-
>>>   hw/core/qdev.c            |  98 +++++++++++++++++++++++++ 
>>> +--------------
>>>   hw/scsi/scsi-bus.c        |   4 +-
>>>   qom/qom-qmp-cmds.c        |   2 +-
>>>   system/qdev-monitor.c     |   5 ++-
>>>   tests/unit/test-qdev.c    | 112 +++++++++++++++++++++++++++++++++++ 
>>> + +++++++++-
>>>   9 files changed, 212 insertions(+), 48 deletions(-)
>>>
>>> diff --git a/qapi/common.json b/qapi/common.json
>>> index af7e3d618a7c..88a308cbd172 100644
>>> --- a/qapi/common.json
>>> +++ b/qapi/common.json
>>> @@ -7,6 +7,25 @@
>>>   # *****************
>>>   ##
>>> +##
>>> +# @DevicePhase:
>>> +#
>>> +# An enumeration of the device phases
>>> +#
>>> +# @initialized: the initial phase
>>> +#
>>> +# @realizing: the phase during realization
>>> +#
>>> +# @realized: the phase after realization
>>> +#
>>> +# @retired: the terminal phase entered when unrealization begins or
>>> +#           realization fails after starting
>>> +#
>>> +# Since: 11.1
>>> +##
>>> +{ 'enum': 'DevicePhase',
>>> +  'data': [ 'initialized', 'realizing', 'realized', 'retired' ] }
>>> +
>>
>>
>>> @@ -477,10 +477,10 @@ bool qdev_unplug_blocked(DeviceState *dev, 
>>> Error **errp)
>>>       return false;
>>>   }
>>> -static bool device_get_realized(Object *obj, Error **errp)
>>> +static int device_get_phase(Object *obj, Error **errp)
>>
>> DevicePhase
> 
> device_get_phase() must return int to match the getter type required by
> object_class_property_add_enum():
> 
>      int (*get)(Object *, Error **)
> 
> Using DevicePhase there would not match the callback type.

Ah right.

> 
>>
>>>   {
>>>       DeviceState *dev = DEVICE(obj);
>>> -    return dev->realized;
>>> +    return dev->phase;
>>>   }


  reply	other threads:[~2026-07-22  9:58 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-21  8:16 [PATCH for-11.2 v3 00/15] qdev: Clarify and enforce the device realization lifecycle Akihiko Odaki
2026-07-21  8:16 ` [PATCH for-11.2 v3 01/15] qdev: Clarify instantiation and realization Akihiko Odaki
2026-07-21 11:14   ` BALATON Zoltan
2026-07-21 11:38     ` Akihiko Odaki
2026-07-21  8:16 ` [PATCH for-11.2 v3 02/15] qdev: Make qdev_is_realized() take a const DeviceState * Akihiko Odaki
2026-07-21 19:49   ` Philippe Mathieu-Daudé
2026-07-21  8:16 ` [PATCH for-11.2 v3 03/15] hw/hyperv/balloon: Use qdev_is_realized() Akihiko Odaki
2026-07-21 19:56   ` Philippe Mathieu-Daudé
2026-07-21  8:16 ` [PATCH for-11.2 v3 04/15] hw/intc/apic: " Akihiko Odaki
2026-07-21 19:51   ` Philippe Mathieu-Daudé
2026-07-21  8:16 ` [PATCH for-11.2 v3 05/15] hw/mem/memory-device: " Akihiko Odaki
2026-07-21 19:56   ` Philippe Mathieu-Daudé
2026-07-21  8:16 ` [PATCH for-11.2 v3 06/15] hw/mem/pc-dimm: " Akihiko Odaki
2026-07-21 19:52   ` Philippe Mathieu-Daudé
2026-07-21  8:16 ` [PATCH for-11.2 v3 07/15] hw/nvram: " Akihiko Odaki
2026-07-21 19:53   ` Philippe Mathieu-Daudé
2026-07-21  8:16 ` [PATCH for-11.2 v3 08/15] hw/ppc/pnv_xscom: " Akihiko Odaki
2026-07-21 19:53   ` Philippe Mathieu-Daudé
2026-07-21  8:16 ` [PATCH for-11.2 v3 09/15] hw/vfio: " Akihiko Odaki
2026-07-21 19:55   ` Philippe Mathieu-Daudé
2026-07-21  8:17 ` [PATCH for-11.2 v3 10/15] hw/virtio/virtio-mem: " Akihiko Odaki
2026-07-21 19:55   ` Philippe Mathieu-Daudé
2026-07-21  8:17 ` [PATCH for-11.2 v3 11/15] hw/virtio/virtio-qmp: " Akihiko Odaki
2026-07-21 19:52   ` Philippe Mathieu-Daudé
2026-07-21  8:17 ` [PATCH for-11.2 v3 12/15] target/i386/cpu: " Akihiko Odaki
2026-07-21 19:52   ` Philippe Mathieu-Daudé
2026-07-21  8:17 ` [PATCH for-11.2 v3 13/15] target/s390x: " Akihiko Odaki
2026-07-21 19:52   ` Philippe Mathieu-Daudé
2026-07-21  8:17 ` [PATCH for-11.2 v3 14/15] hw/qdev: Parent device before setting parent bus Akihiko Odaki
2026-07-21 20:15   ` Philippe Mathieu-Daudé
2026-07-21  8:17 ` [PATCH for-11.2 v3 15/15] hw/qdev: Prevent devices from being realized more than once Akihiko Odaki
2026-07-21 20:11   ` Philippe Mathieu-Daudé
2026-07-22  5:12     ` Akihiko Odaki
2026-07-22  9:57       ` Philippe Mathieu-Daudé [this message]
2026-07-22 11:08         ` Akihiko Odaki
2026-07-22 12:05           ` Philippe Mathieu-Daudé
2026-07-24 11:44 ` [PATCH for-11.2 v3 00/15] qdev: Clarify and enforce the device realization lifecycle Markus Armbruster
2026-07-25  8:20   ` Akihiko Odaki
2026-08-15 13:59 ` Philippe Mathieu-Daudé
2026-08-16 14:33   ` Philippe Mathieu-Daudé

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=8d979f89-374a-4b86-93c8-9d7dcc311ca6@oss.qualcomm.com \
    --to=philmd@oss.qualcomm.com \
    --cc=FangSheng.Huang@amd.com \
    --cc=adityag@linux.ibm.com \
    --cc=alex@shazbot.org \
    --cc=alistair@alistair23.me \
    --cc=armbru@redhat.com \
    --cc=balaton@eik.bme.hu \
    --cc=berrange@redhat.com \
    --cc=brueckner@linux.ibm.com \
    --cc=clg@redhat.com \
    --cc=cohuck@redhat.com \
    --cc=david@kernel.org \
    --cc=eblake@redhat.com \
    --cc=edgar.iglesias@gmail.com \
    --cc=eduardo@habkost.net \
    --cc=fam@euphon.net \
    --cc=farman@linux.ibm.com \
    --cc=harshpb@linux.ibm.com \
    --cc=iii@linux.ibm.com \
    --cc=imammedo@redhat.com \
    --cc=luc@lmichel.fr \
    --cc=maciej.szmigiero@oracle.com \
    --cc=milesg@linux.ibm.com \
    --cc=mjrosato@linux.ibm.com \
    --cc=mst@redhat.com \
    --cc=npiggin@gmail.com \
    --cc=odaki@rsg.ci.i.u-tokyo.ac.jp \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=qemu-s390x@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=zhao1.liu@intel.com \
    /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.