qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <philmd@linaro.org>
To: QEMU Developers <qemu-devel@nongnu.org>
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Markus Armbruster" <armbru@redhat.com>,
	"Mark Cave-Ayland" <mark.cave-ayland@ilande.co.uk>,
	"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
	"Alex Williamson" <alex.williamson@redhat.com>,
	"Cédric Le Goater" <clg@redhat.com>,
	"Eduardo Habkost" <eduardo@habkost.net>,
	"Jason Wang" <jasowang@redhat.com>,
	"Akihiko Odaki" <akihiko.odaki@daynix.com>,
	"Knut Omang" <knut.omang@oracle.com>,
	"Knut Omang" <knuto@ifi.uio.no>,
	"Alex Bennée" <alex.bennee@linaro.org>
Subject: hw/qdev: Can qdev_unrealize() ever fail?
Date: Mon, 12 Feb 2024 09:35:53 +0100	[thread overview]
Message-ID: <152c09f3-c33e-4bf7-92ba-516dc4c128c7@linaro.org> (raw)

Hi,

QDev base class doesn't expect UNREALIZE to fail, and this
handler is only recommended for hot-plug devices:

/**
  * qdev_unrealize: Unrealize a device
  * @dev: device to unrealize
  *
  * Warning: most devices in QEMU do not expect to be unrealized. Only
  * devices which are hot-unpluggable should be unrealized (as part of
  * the unplugging process); all other devices are expected to last for
  * the life of the simulation and should not be unrealized and freed.
  */


   void qdev_unrealize(DeviceState *dev)
   {
       object_property_set_bool(OBJECT(dev), "realized",
                                false, &error_abort);
                                       ^^^^^^^^^^^^
   }

   static void device_unparent(Object *obj)
   {
       DeviceState *dev = DEVICE(obj);
       BusState *bus;

       if (dev->realized) {
           qdev_unrealize(dev);
       }
       while (dev->num_child_bus) {
           bus = QLIST_FIRST(&dev->child_bus);
           object_unparent(OBJECT(bus));
       }
       if (dev->parent_bus) {
           bus_remove_child(dev->parent_bus, dev);
           object_unref(OBJECT(dev->parent_bus));
           dev->parent_bus = NULL;
       }
   }

Now apparently some devices expect failures, see commit 7c0fa8dff8
("pcie: Add support for Single Root I/O Virtualization (SR/IOV)"):

   static void unregister_vfs(PCIDevice *dev)
   {
       uint16_t num_vfs = dev->exp.sriov_pf.num_vfs;
       uint16_t i;

       for (i = 0; i < num_vfs; i++) {
           Error *err = NULL;
           PCIDevice *vf = dev->exp.sriov_pf.vf[i];
           if (!object_property_set_bool(OBJECT(vf), "realized",
                                         false, &err)) {
                                                ^^^^
               error_reportf_err(err, "Failed to unplug: ");
           }
           object_unparent(OBJECT(vf));
           object_unref(OBJECT(vf));
       }
       ...
   }

(Note the failure path only emits a warning).

So instead of calling the QDev unrealize layer, this function is
calling the lower layer, QOM, bypassing the class handlers, leading
to further cleanups such commit 08f6328480 ("pcie: Release references
of virtual functions") or recent patch
https://lore.kernel.org/qemu-devel/20240210-reuse-v2-6-24ba2a502692@daynix.com/.

I couldn't find any explicit possible failure in:
  pci_qdev_unrealize()
  do_pci_unregister_device()
  pci_bus_unrealize()
so, what is the failure unregister_vfs() is trying to recover from?

I understand if a device is in a odd state, the kernel could reject
an unplug request. If so, how to deal with that cleanly?

Thanks,

Phil.


             reply	other threads:[~2024-02-12  8:36 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-12  8:35 Philippe Mathieu-Daudé [this message]
2024-02-12  9:48 ` hw/qdev: Can qdev_unrealize() ever fail? Akihiko Odaki

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=152c09f3-c33e-4bf7-92ba-516dc4c128c7@linaro.org \
    --to=philmd@linaro.org \
    --cc=akihiko.odaki@daynix.com \
    --cc=alex.bennee@linaro.org \
    --cc=alex.williamson@redhat.com \
    --cc=armbru@redhat.com \
    --cc=clg@redhat.com \
    --cc=eduardo@habkost.net \
    --cc=jasowang@redhat.com \
    --cc=knut.omang@oracle.com \
    --cc=knuto@ifi.uio.no \
    --cc=marcel.apfelbaum@gmail.com \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).