virtio-pci: Send qapi events when the virtio-mem size changes

Let's register the notifier and trigger the qapi event with the right
device id.

MEMORY_DEVICE_SIZE_CHANGE is similar to BALLOON_CHANGE, however on a
memory device level.

Don't unregister the notifier (we neither have finalize() nor unrealize()
for VirtIOPCIProxy, so it's not that simple to do it) - both devices are
expected to vanish at the same time.

Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: Eric Blake <eblake@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20200626072248.78761-18-david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
David Hildenbrand 2020-06-26 09:22:44 +02:00 committed by Michael S. Tsirkin
parent c95b4437da
commit 722a3c783e
4 changed files with 55 additions and 0 deletions

View File

@ -14,6 +14,7 @@
#include "virtio-mem-pci.h" #include "virtio-mem-pci.h"
#include "hw/mem/memory-device.h" #include "hw/mem/memory-device.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qapi-events-misc.h"
static void virtio_mem_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) static void virtio_mem_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
{ {
@ -74,6 +75,21 @@ static void virtio_mem_pci_fill_device_info(const MemoryDeviceState *md,
info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM; info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_MEM;
} }
static void virtio_mem_pci_size_change_notify(Notifier *notifier, void *data)
{
VirtIOMEMPCI *pci_mem = container_of(notifier, VirtIOMEMPCI,
size_change_notifier);
DeviceState *dev = DEVICE(pci_mem);
const uint64_t * const size_p = data;
const char *id = NULL;
if (dev->id) {
id = g_strdup(dev->id);
}
qapi_event_send_memory_device_size_change(!!id, id, *size_p);
}
static void virtio_mem_pci_class_init(ObjectClass *klass, void *data) static void virtio_mem_pci_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
@ -98,9 +114,21 @@ static void virtio_mem_pci_class_init(ObjectClass *klass, void *data)
static void virtio_mem_pci_instance_init(Object *obj) static void virtio_mem_pci_instance_init(Object *obj)
{ {
VirtIOMEMPCI *dev = VIRTIO_MEM_PCI(obj); VirtIOMEMPCI *dev = VIRTIO_MEM_PCI(obj);
VirtIOMEMClass *vmc;
VirtIOMEM *vmem;
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev), virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_MEM); TYPE_VIRTIO_MEM);
dev->size_change_notifier.notify = virtio_mem_pci_size_change_notify;
vmem = VIRTIO_MEM(&dev->vdev);
vmc = VIRTIO_MEM_GET_CLASS(vmem);
/*
* We never remove the notifier again, as we expect both devices to
* disappear at the same time.
*/
vmc->add_size_change_notifier(vmem, &dev->size_change_notifier);
object_property_add_alias(obj, VIRTIO_MEM_BLOCK_SIZE_PROP, object_property_add_alias(obj, VIRTIO_MEM_BLOCK_SIZE_PROP,
OBJECT(&dev->vdev), VIRTIO_MEM_BLOCK_SIZE_PROP); OBJECT(&dev->vdev), VIRTIO_MEM_BLOCK_SIZE_PROP);
object_property_add_alias(obj, VIRTIO_MEM_SIZE_PROP, OBJECT(&dev->vdev), object_property_add_alias(obj, VIRTIO_MEM_SIZE_PROP, OBJECT(&dev->vdev),

View File

@ -28,6 +28,7 @@ typedef struct VirtIOMEMPCI VirtIOMEMPCI;
struct VirtIOMEMPCI { struct VirtIOMEMPCI {
VirtIOPCIProxy parent_obj; VirtIOPCIProxy parent_obj;
VirtIOMEM vdev; VirtIOMEM vdev;
Notifier size_change_notifier;
}; };
#endif /* QEMU_VIRTIO_MEM_PCI_H */ #endif /* QEMU_VIRTIO_MEM_PCI_H */

View File

@ -235,6 +235,7 @@ static MonitorQAPIEventConf monitor_qapi_event_conf[QAPI_EVENT__MAX] = {
[QAPI_EVENT_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS }, [QAPI_EVENT_QUORUM_REPORT_BAD] = { 1000 * SCALE_MS },
[QAPI_EVENT_QUORUM_FAILURE] = { 1000 * SCALE_MS }, [QAPI_EVENT_QUORUM_FAILURE] = { 1000 * SCALE_MS },
[QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS }, [QAPI_EVENT_VSERPORT_CHANGE] = { 1000 * SCALE_MS },
[QAPI_EVENT_MEMORY_DEVICE_SIZE_CHANGE] = { 1000 * SCALE_MS },
}; };
/* /*

View File

@ -1434,6 +1434,31 @@
## ##
{ 'command': 'query-memory-devices', 'returns': ['MemoryDeviceInfo'] } { 'command': 'query-memory-devices', 'returns': ['MemoryDeviceInfo'] }
##
# @MEMORY_DEVICE_SIZE_CHANGE:
#
# Emitted when the size of a memory device changes. Only emitted for memory
# devices that can actually change the size (e.g., virtio-mem due to guest
# action).
#
# @id: device's ID
# @size: the new size of memory that the device provides
#
# Note: this event is rate-limited.
#
# Since: 5.1
#
# Example:
#
# <- { "event": "MEMORY_DEVICE_SIZE_CHANGE",
# "data": { "id": "vm0", "size": 1073741824},
# "timestamp": { "seconds": 1588168529, "microseconds": 201316 } }
#
##
{ 'event': 'MEMORY_DEVICE_SIZE_CHANGE',
'data': { '*id': 'str', 'size': 'size' } }
## ##
# @MEM_UNPLUG_ERROR: # @MEM_UNPLUG_ERROR:
# #