qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* hw/qdev: Can qdev_unrealize() ever fail?
@ 2024-02-12  8:35 Philippe Mathieu-Daudé
  2024-02-12  9:48 ` Akihiko Odaki
  0 siblings, 1 reply; 2+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-02-12  8:35 UTC (permalink / raw)
  To: QEMU Developers
  Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell,
	Markus Armbruster, Mark Cave-Ayland, Marcel Apfelbaum,
	Alex Williamson, Cédric Le Goater, Eduardo Habkost,
	Jason Wang, Akihiko Odaki, Knut Omang, Knut Omang,
	Alex Bennée

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.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-02-12  9:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-12  8:35 hw/qdev: Can qdev_unrealize() ever fail? Philippe Mathieu-Daudé
2024-02-12  9:48 ` Akihiko Odaki

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).