diff mbox series

[v1,16/17] virtio-mem: Allow notifiers for size changes

Message ID 20200506094948.76388-17-david@redhat.com (mailing list archive)
State New, archived
Headers show
Series virtio-mem: Paravirtualized memory hot(un)plug | expand

Commit Message

David Hildenbrand May 6, 2020, 9:49 a.m. UTC
We want to send qapi events in case the size of a virtio-mem device
changes. This allows upper layers to always know how much memory is
actually currently consumed via a virtio-mem device.

Unfortuantely, we have to report the id of our proxy device. Let's provide
an easy way for our proxy device to register, so it can send the qapi
events. Piggy-backing on the notifier infrastructure (although we'll
only ever have one notifier registered) seems to be an easy way.

Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 hw/virtio/virtio-mem.c         | 21 ++++++++++++++++++++-
 include/hw/virtio/virtio-mem.h |  5 +++++
 2 files changed, 25 insertions(+), 1 deletion(-)

Comments

Dr. David Alan Gilbert May 15, 2020, 4:46 p.m. UTC | #1
* David Hildenbrand (david@redhat.com) wrote:
> We want to send qapi events in case the size of a virtio-mem device
> changes. This allows upper layers to always know how much memory is
> actually currently consumed via a virtio-mem device.
> 
> Unfortuantely, we have to report the id of our proxy device. Let's provide
> an easy way for our proxy device to register, so it can send the qapi
> events. Piggy-backing on the notifier infrastructure (although we'll
> only ever have one notifier registered) seems to be an easy way.
> 
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> Cc: Igor Mammedov <imammedo@redhat.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>

Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

> ---
>  hw/virtio/virtio-mem.c         | 21 ++++++++++++++++++++-
>  include/hw/virtio/virtio-mem.h |  5 +++++
>  2 files changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
> index e25b2c74f2..88a99a0d90 100644
> --- a/hw/virtio/virtio-mem.c
> +++ b/hw/virtio/virtio-mem.c
> @@ -198,6 +198,7 @@ static int virtio_mem_state_change_request(VirtIOMEM *vmem, uint64_t gpa,
>      } else {
>          vmem->size -= size;
>      }
> +    notifier_list_notify(&vmem->size_change_notifiers, &vmem->size);
>      return VIRTIO_MEM_RESP_ACK;
>  }
>  
> @@ -253,7 +254,10 @@ static int virtio_mem_unplug_all(VirtIOMEM *vmem)
>          return -EBUSY;
>      }
>      bitmap_clear(vmem->bitmap, 0, vmem->bitmap_size);
> -    vmem->size = 0;
> +    if (vmem->size != 0) {
> +        vmem->size = 0;
> +        notifier_list_notify(&vmem->size_change_notifiers, &vmem->size);
> +    }
>  
>      virtio_mem_resize_usable_region(vmem, vmem->requested_size, true);
>      return 0;
> @@ -594,6 +598,18 @@ static MemoryRegion *virtio_mem_get_memory_region(VirtIOMEM *vmem, Error **errp)
>      return &vmem->memdev->mr;
>  }
>  
> +static void virtio_mem_add_size_change_notifier(VirtIOMEM *vmem,
> +                                                Notifier *notifier)
> +{
> +    notifier_list_add(&vmem->size_change_notifiers, notifier);
> +}
> +
> +static void virtio_mem_remove_size_change_notifier(VirtIOMEM *vmem,
> +                                                   Notifier *notifier)
> +{
> +    notifier_remove(notifier);
> +}
> +
>  static void virtio_mem_get_size(Object *obj, Visitor *v, const char *name,
>                                  void *opaque, Error **errp)
>  {
> @@ -705,6 +721,7 @@ static void virtio_mem_instance_init(Object *obj)
>      VirtIOMEM *vmem = VIRTIO_MEM(obj);
>  
>      vmem->block_size = VIRTIO_MEM_MIN_BLOCK_SIZE;
> +    notifier_list_init(&vmem->size_change_notifiers);
>  
>      object_property_add(obj, VIRTIO_MEM_SIZE_PROP, "size", virtio_mem_get_size,
>                          NULL, NULL, NULL, &error_abort);
> @@ -743,6 +760,8 @@ static void virtio_mem_class_init(ObjectClass *klass, void *data)
>  
>      vmc->fill_device_info = virtio_mem_fill_device_info;
>      vmc->get_memory_region = virtio_mem_get_memory_region;
> +    vmc->add_size_change_notifier = virtio_mem_add_size_change_notifier;
> +    vmc->remove_size_change_notifier = virtio_mem_remove_size_change_notifier;
>  }
>  
>  static const TypeInfo virtio_mem_info = {
> diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h
> index 27158cb611..5820b5c23e 100644
> --- a/include/hw/virtio/virtio-mem.h
> +++ b/include/hw/virtio/virtio-mem.h
> @@ -66,6 +66,9 @@ typedef struct VirtIOMEM {
>      /* block size and alignment */
>      uint32_t block_size;
>      uint32_t migration_block_size;
> +
> +    /* notifiers to notify when "size" changes */
> +    NotifierList size_change_notifiers;
>  } VirtIOMEM;
>  
>  typedef struct VirtIOMEMClass {
> @@ -75,6 +78,8 @@ typedef struct VirtIOMEMClass {
>      /* public */
>      void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi);
>      MemoryRegion *(*get_memory_region)(VirtIOMEM *vmem, Error **errp);
> +    void (*add_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
> +    void (*remove_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
>  } VirtIOMEMClass;
>  
>  #endif
> -- 
> 2.25.3
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
diff mbox series

Patch

diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index e25b2c74f2..88a99a0d90 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -198,6 +198,7 @@  static int virtio_mem_state_change_request(VirtIOMEM *vmem, uint64_t gpa,
     } else {
         vmem->size -= size;
     }
+    notifier_list_notify(&vmem->size_change_notifiers, &vmem->size);
     return VIRTIO_MEM_RESP_ACK;
 }
 
@@ -253,7 +254,10 @@  static int virtio_mem_unplug_all(VirtIOMEM *vmem)
         return -EBUSY;
     }
     bitmap_clear(vmem->bitmap, 0, vmem->bitmap_size);
-    vmem->size = 0;
+    if (vmem->size != 0) {
+        vmem->size = 0;
+        notifier_list_notify(&vmem->size_change_notifiers, &vmem->size);
+    }
 
     virtio_mem_resize_usable_region(vmem, vmem->requested_size, true);
     return 0;
@@ -594,6 +598,18 @@  static MemoryRegion *virtio_mem_get_memory_region(VirtIOMEM *vmem, Error **errp)
     return &vmem->memdev->mr;
 }
 
+static void virtio_mem_add_size_change_notifier(VirtIOMEM *vmem,
+                                                Notifier *notifier)
+{
+    notifier_list_add(&vmem->size_change_notifiers, notifier);
+}
+
+static void virtio_mem_remove_size_change_notifier(VirtIOMEM *vmem,
+                                                   Notifier *notifier)
+{
+    notifier_remove(notifier);
+}
+
 static void virtio_mem_get_size(Object *obj, Visitor *v, const char *name,
                                 void *opaque, Error **errp)
 {
@@ -705,6 +721,7 @@  static void virtio_mem_instance_init(Object *obj)
     VirtIOMEM *vmem = VIRTIO_MEM(obj);
 
     vmem->block_size = VIRTIO_MEM_MIN_BLOCK_SIZE;
+    notifier_list_init(&vmem->size_change_notifiers);
 
     object_property_add(obj, VIRTIO_MEM_SIZE_PROP, "size", virtio_mem_get_size,
                         NULL, NULL, NULL, &error_abort);
@@ -743,6 +760,8 @@  static void virtio_mem_class_init(ObjectClass *klass, void *data)
 
     vmc->fill_device_info = virtio_mem_fill_device_info;
     vmc->get_memory_region = virtio_mem_get_memory_region;
+    vmc->add_size_change_notifier = virtio_mem_add_size_change_notifier;
+    vmc->remove_size_change_notifier = virtio_mem_remove_size_change_notifier;
 }
 
 static const TypeInfo virtio_mem_info = {
diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h
index 27158cb611..5820b5c23e 100644
--- a/include/hw/virtio/virtio-mem.h
+++ b/include/hw/virtio/virtio-mem.h
@@ -66,6 +66,9 @@  typedef struct VirtIOMEM {
     /* block size and alignment */
     uint32_t block_size;
     uint32_t migration_block_size;
+
+    /* notifiers to notify when "size" changes */
+    NotifierList size_change_notifiers;
 } VirtIOMEM;
 
 typedef struct VirtIOMEMClass {
@@ -75,6 +78,8 @@  typedef struct VirtIOMEMClass {
     /* public */
     void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi);
     MemoryRegion *(*get_memory_region)(VirtIOMEM *vmem, Error **errp);
+    void (*add_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
+    void (*remove_size_change_notifier)(VirtIOMEM *vmem, Notifier *notifier);
 } VirtIOMEMClass;
 
 #endif