On 27/09/2018 15:01, Igor Mammedov wrote:
> On Wed, 26 Sep 2018 11:42:13 +0200
> David Hildenbrand <[email protected]> wrote:
>
>> The unplug and unplug_request handlers are special: They are not
>> executed when unrealizing a device, but rather trigger the removal of a
>> device from device_del() via object_unparent() - to effectively
>> unrealize a device.
>>
>> If such a device has a child bus and another device attached to
>> that bus (e.g. how virtio devices are created with their proxy device),
>> we will not get a call to the unplug handler. As we want to support
>> hotplug handlers (and especially also some unplug logic to undo resource
>> assignment) for such devices, we cannot simply call the unplug handler
>> when unrealizing - it has a different semantic ("trigger removal").
>>
>> To handle this scenario, we need a do_unplug handler, that will be
>> executed for all devices with a hotplug handler.
> could you clarify what would be call flow for unplug in this case
> starting from 'device_del'?
Let's work it through for virtio-pmem:
qemu-system-x86_64 -machine pc -m 8G,maxmem=20G \
[...] \
-object memory-backend-file,id=mem1,share,mem-path=/dev/zero,size=4G \
-device virtio-pmem-pci,id=vp1,memdev=mem1 -monitor stdio
info qtree gives us:
bus: pci.0
type PCI
dev: virtio-pmem-pci, id "vp1"
[...]
bus: virtio-bus
type virtio-pci-bus
dev: virtio-pmem, id ""
memaddr = 9663676416 (0x240000000)
memdev = "/objects/mem1"
[...]
"device_del vp1":
qmp_device_del(vp1)->qdev_unplug(vp1)->hotplug_handler_unplug_request(vp1)
piix4_device_unplug_request_cb(vp1)->acpi_pcihp_device_unplug_cb(vp1)
-> Guest has to process the request and respond
acpi_pcihp_eject_slot(vp1)->object_unparent(vp1)
Now, this triggers the unplug of the device hierarchy:
object_unparent(vp1)->device_unparent(vp1)>device_set_realized(vp1, 0)
->bus_set_realized(virtio-bus, 0)->device_set_realized(virtio-pmem, 0)
This is the place where this hooks is comes into play:
->hotplug_handler_do_unplug(virtio-pmem)->machine
handler->virtio_pmem_do_unplug(virtio-pmem)
Followed by object_unparent(virtio-bus)->bus_unparent(virtio-bus)
Followed by object_unparent(virtio-pmem)->device_unparent(virtio-pmem)
At this place, the hierarchy is gone. Hotplug succeeded and the
virtio-pmem device (memory device) has been properly unplugged.
--
Thanks,
David / dhildenb