diff mbox series

[v4,17/24] memory-device: add class function get_device_id()

Message ID 20180926094219.20322-18-david@redhat.com
State New
Headers show
Series memory-device: complete refactoring + virtio-pmem | expand

Commit Message

David Hildenbrand Sept. 26, 2018, 9:42 a.m. UTC
When reporting the id of virtio-based memory devices, we always have to
take the one of the proxy device (parent), not the one of the memory
device directly.

Let's generalize this by allowing memory devices to specify an optional
"get_device_id" function. This id can then be used to report errors to the
user from memory-device.c code, without having to special case e.g.
virtio devices. Provide a default function that can be overridden.

While at it, properly treat id == NULL and report "(unnamed)" instead.

Details:

When the user creates a virtio device (e.g.  virtio-balloon-pci), two
devices are actually created.

1. Virtio proxy device (e.g. TYPE_VIRTIO_BALLOON_PCI)
2. The "real" virtio device (e.g. TYPE_VIRTIO_BALLOON).

1. aliases all properties of 2, so 2. can be properly configured using 1.
1. gets the device ID set specified by the user. 2. gets no ID set.

If we want to make 2. a MemoryDevice but report errors/information to the
user, we always have to report the id of 1. (because that's the device the
user instantiated and configured).

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 hw/mem/memory-device.c         | 19 +++++++++++++++++--
 include/hw/mem/memory-device.h |  5 +++++
 2 files changed, 22 insertions(+), 2 deletions(-)

Comments

Igor Mammedov Sept. 27, 2018, 8:18 a.m. UTC | #1
On Wed, 26 Sep 2018 11:42:12 +0200
David Hildenbrand <david@redhat.com> wrote:

> When reporting the id of virtio-based memory devices, we always have to
> take the one of the proxy device (parent), not the one of the memory
> device directly.
> 
> Let's generalize this by allowing memory devices to specify an optional
> "get_device_id" function. This id can then be used to report errors to the
> user from memory-device.c code, without having to special case e.g.
> virtio devices. Provide a default function that can be overridden.
> 
> While at it, properly treat id == NULL and report "(unnamed)" instead.
> 
> Details:
> 
> When the user creates a virtio device (e.g.  virtio-balloon-pci), two
> devices are actually created.
> 
> 1. Virtio proxy device (e.g. TYPE_VIRTIO_BALLOON_PCI)
> 2. The "real" virtio device (e.g. TYPE_VIRTIO_BALLOON).
> 
> 1. aliases all properties of 2, so 2. can be properly configured using 1.
> 1. gets the device ID set specified by the user. 2. gets no ID set.
> 
> If we want to make 2. a MemoryDevice but report errors/information to the
> user, we always have to report the id of 1. (because that's the device the
> user instantiated and configured).
> 
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> Signed-off-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>

> ---
>  hw/mem/memory-device.c         | 19 +++++++++++++++++--
>  include/hw/mem/memory-device.h |  5 +++++
>  2 files changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c
> index cf85199a72..6dc40e8764 100644
> --- a/hw/mem/memory-device.c
> +++ b/hw/mem/memory-device.c
> @@ -174,8 +174,10 @@ static uint64_t memory_device_get_free_addr(MachineState *ms,
>  
>          if (ranges_overlap(md_addr, md_size, new_addr, size)) {
>              if (hint) {
> -                const DeviceState *d = DEVICE(md);
> -                error_setg(errp, "address range conflicts with '%s'", d->id);
> +                const char *id = mdc->get_device_id(md);
> +
> +                error_setg(errp, "address range conflicts with '%s'",
> +                           id ? id : "(unnamed)");
>                  goto out;
>              }
>              new_addr = QEMU_ALIGN_UP(md_addr + md_size, align);
> @@ -328,10 +330,23 @@ uint64_t memory_device_get_region_size(const MemoryDeviceState *md,
>      return memory_region_size(mr);
>  }
>  
> +static const char *memory_device_get_device_id(const MemoryDeviceState *md)
> +{
> +    return DEVICE(md)->id;
> +}
> +
> +static void memory_device_class_init(ObjectClass *oc, void *data)
> +{
> +    MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc);
> +
> +    mdc->get_device_id = memory_device_get_device_id;
> +}
> +
>  static const TypeInfo memory_device_info = {
>      .name          = TYPE_MEMORY_DEVICE,
>      .parent        = TYPE_INTERFACE,
>      .class_size = sizeof(MemoryDeviceClass),
> +    .class_init =  memory_device_class_init,
>  };
>  
>  static void memory_device_register_types(void)
> diff --git a/include/hw/mem/memory-device.h b/include/hw/mem/memory-device.h
> index 97de693bca..52fc117ce2 100644
> --- a/include/hw/mem/memory-device.h
> +++ b/include/hw/mem/memory-device.h
> @@ -45,6 +45,10 @@ typedef struct MemoryDeviceState {
>   * successive memory regions, a covering memory region is to be used.
>   * Scattered memory regions are not supported for single devices.
>   * @fill_device_info: Translate current @md state into #MemoryDeviceInfo.
> + * @get_device_id: Allows memory devices behind proxy devices
> + * (e.g. virtio based) to report the id of the proxy device to the user
> + * instead of the (empty) id of the memory device. The default
> + * implementation (unless overridden) will return the ordinary device id.
>   */
>  typedef struct MemoryDeviceClass {
>      /* private */
> @@ -57,6 +61,7 @@ typedef struct MemoryDeviceClass {
>      MemoryRegion *(*get_memory_region)(MemoryDeviceState *md, Error **errp);
>      void (*fill_device_info)(const MemoryDeviceState *md,
>                               MemoryDeviceInfo *info);
> +    const char *(*get_device_id)(const MemoryDeviceState *md);
>  } MemoryDeviceClass;
>  
>  MemoryDeviceInfoList *qmp_memory_device_list(void);
Eric Auger Sept. 30, 2018, 4:19 p.m. UTC | #2
Hi David,

On 9/26/18 11:42 AM, David Hildenbrand wrote:
> When reporting the id of virtio-based memory devices, we always have to
> take the one of the proxy device (parent), not the one of the memory
> device directly.
> 
> Let's generalize this by allowing memory devices to specify an optional
> "get_device_id" function. This id can then be used to report errors to the
> user from memory-device.c code, without having to special case e.g.
> virtio devices. Provide a default function that can be overridden.
> 
> While at it, properly treat id == NULL and report "(unnamed)" instead.
> 
> Details:
> 
> When the user creates a virtio device (e.g.  virtio-balloon-pci), two
> devices are actually created.
> 
> 1. Virtio proxy device (e.g. TYPE_VIRTIO_BALLOON_PCI)
> 2. The "real" virtio device (e.g. TYPE_VIRTIO_BALLOON).
> 
> 1. aliases all properties of 2, so 2. can be properly configured using 1.
> 1. gets the device ID set specified by the user. 2. gets no ID set.
s/set// ?
> 
> If we want to make 2. a MemoryDevice but report errors/information to the
to be reworded?
> user, we always have to report the id of 1. (because that's the device the
> user instantiated and configured).
> 
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  hw/mem/memory-device.c         | 19 +++++++++++++++++--
>  include/hw/mem/memory-device.h |  5 +++++
>  2 files changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c
> index cf85199a72..6dc40e8764 100644
> --- a/hw/mem/memory-device.c
> +++ b/hw/mem/memory-device.c
> @@ -174,8 +174,10 @@ static uint64_t memory_device_get_free_addr(MachineState *ms,
>  
>          if (ranges_overlap(md_addr, md_size, new_addr, size)) {
>              if (hint) {
> -                const DeviceState *d = DEVICE(md);
> -                error_setg(errp, "address range conflicts with '%s'", d->id);
> +                const char *id = mdc->get_device_id(md);
> +
> +                error_setg(errp, "address range conflicts with '%s'",
address range conflicts with memory device id='%s"?

Thanks

Eric
> +                           id ? id : "(unnamed)")>                  goto out;
>              }
>              new_addr = QEMU_ALIGN_UP(md_addr + md_size, align);
> @@ -328,10 +330,23 @@ uint64_t memory_device_get_region_size(const MemoryDeviceState *md,
>      return memory_region_size(mr);
>  }
>  
> +static const char *memory_device_get_device_id(const MemoryDeviceState *md)
> +{
> +    return DEVICE(md)->id;
> +}
> +
> +static void memory_device_class_init(ObjectClass *oc, void *data)
> +{
> +    MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc);
> +
> +    mdc->get_device_id = memory_device_get_device_id;
> +}
> +
>  static const TypeInfo memory_device_info = {
>      .name          = TYPE_MEMORY_DEVICE,
>      .parent        = TYPE_INTERFACE,
>      .class_size = sizeof(MemoryDeviceClass),
> +    .class_init =  memory_device_class_init,
>  };
>  
>  static void memory_device_register_types(void)
> diff --git a/include/hw/mem/memory-device.h b/include/hw/mem/memory-device.h
> index 97de693bca..52fc117ce2 100644
> --- a/include/hw/mem/memory-device.h
> +++ b/include/hw/mem/memory-device.h
> @@ -45,6 +45,10 @@ typedef struct MemoryDeviceState {
>   * successive memory regions, a covering memory region is to be used.
>   * Scattered memory regions are not supported for single devices.
>   * @fill_device_info: Translate current @md state into #MemoryDeviceInfo.
> + * @get_device_id: Allows memory devices behind proxy devices
> + * (e.g. virtio based) to report the id of the proxy device to the user
> + * instead of the (empty) id of the memory device. The default
> + * implementation (unless overridden) will return the ordinary device id.
>   */
>  typedef struct MemoryDeviceClass {
>      /* private */
> @@ -57,6 +61,7 @@ typedef struct MemoryDeviceClass {
>      MemoryRegion *(*get_memory_region)(MemoryDeviceState *md, Error **errp);
>      void (*fill_device_info)(const MemoryDeviceState *md,
>                               MemoryDeviceInfo *info);
> +    const char *(*get_device_id)(const MemoryDeviceState *md);
>  } MemoryDeviceClass;
>  
>  MemoryDeviceInfoList *qmp_memory_device_list(void);
>
David Hildenbrand Oct. 1, 2018, 8:36 a.m. UTC | #3
On 30/09/2018 18:19, Auger Eric wrote:
> Hi David,
> 
> On 9/26/18 11:42 AM, David Hildenbrand wrote:
>> When reporting the id of virtio-based memory devices, we always have to
>> take the one of the proxy device (parent), not the one of the memory
>> device directly.
>>
>> Let's generalize this by allowing memory devices to specify an optional
>> "get_device_id" function. This id can then be used to report errors to the
>> user from memory-device.c code, without having to special case e.g.
>> virtio devices. Provide a default function that can be overridden.
>>
>> While at it, properly treat id == NULL and report "(unnamed)" instead.
>>
>> Details:
>>
>> When the user creates a virtio device (e.g.  virtio-balloon-pci), two
>> devices are actually created.
>>
>> 1. Virtio proxy device (e.g. TYPE_VIRTIO_BALLOON_PCI)
>> 2. The "real" virtio device (e.g. TYPE_VIRTIO_BALLOON).
>>
>> 1. aliases all properties of 2, so 2. can be properly configured using 1.
>> 1. gets the device ID set specified by the user. 2. gets no ID set.
> s/set// ?
>>
>> If we want to make 2. a MemoryDevice but report errors/information to the
> to be reworded?
>> user, we always have to report the id of 1. (because that's the device the
>> user instantiated and configured).

Both parts slightly reworded.

>>
>> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>> Signed-off-by: David Hildenbrand <david@redhat.com>
>> ---
>>  hw/mem/memory-device.c         | 19 +++++++++++++++++--
>>  include/hw/mem/memory-device.h |  5 +++++
>>  2 files changed, 22 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c
>> index cf85199a72..6dc40e8764 100644
>> --- a/hw/mem/memory-device.c
>> +++ b/hw/mem/memory-device.c
>> @@ -174,8 +174,10 @@ static uint64_t memory_device_get_free_addr(MachineState *ms,
>>  
>>          if (ranges_overlap(md_addr, md_size, new_addr, size)) {
>>              if (hint) {
>> -                const DeviceState *d = DEVICE(md);
>> -                error_setg(errp, "address range conflicts with '%s'", d->id);
>> +                const char *id = mdc->get_device_id(md);
>> +
>> +                error_setg(errp, "address range conflicts with '%s'",
> address range conflicts with memory device id='%s"?

Yes, I can do that.

Thanks!
diff mbox series

Patch

diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c
index cf85199a72..6dc40e8764 100644
--- a/hw/mem/memory-device.c
+++ b/hw/mem/memory-device.c
@@ -174,8 +174,10 @@  static uint64_t memory_device_get_free_addr(MachineState *ms,
 
         if (ranges_overlap(md_addr, md_size, new_addr, size)) {
             if (hint) {
-                const DeviceState *d = DEVICE(md);
-                error_setg(errp, "address range conflicts with '%s'", d->id);
+                const char *id = mdc->get_device_id(md);
+
+                error_setg(errp, "address range conflicts with '%s'",
+                           id ? id : "(unnamed)");
                 goto out;
             }
             new_addr = QEMU_ALIGN_UP(md_addr + md_size, align);
@@ -328,10 +330,23 @@  uint64_t memory_device_get_region_size(const MemoryDeviceState *md,
     return memory_region_size(mr);
 }
 
+static const char *memory_device_get_device_id(const MemoryDeviceState *md)
+{
+    return DEVICE(md)->id;
+}
+
+static void memory_device_class_init(ObjectClass *oc, void *data)
+{
+    MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc);
+
+    mdc->get_device_id = memory_device_get_device_id;
+}
+
 static const TypeInfo memory_device_info = {
     .name          = TYPE_MEMORY_DEVICE,
     .parent        = TYPE_INTERFACE,
     .class_size = sizeof(MemoryDeviceClass),
+    .class_init =  memory_device_class_init,
 };
 
 static void memory_device_register_types(void)
diff --git a/include/hw/mem/memory-device.h b/include/hw/mem/memory-device.h
index 97de693bca..52fc117ce2 100644
--- a/include/hw/mem/memory-device.h
+++ b/include/hw/mem/memory-device.h
@@ -45,6 +45,10 @@  typedef struct MemoryDeviceState {
  * successive memory regions, a covering memory region is to be used.
  * Scattered memory regions are not supported for single devices.
  * @fill_device_info: Translate current @md state into #MemoryDeviceInfo.
+ * @get_device_id: Allows memory devices behind proxy devices
+ * (e.g. virtio based) to report the id of the proxy device to the user
+ * instead of the (empty) id of the memory device. The default
+ * implementation (unless overridden) will return the ordinary device id.
  */
 typedef struct MemoryDeviceClass {
     /* private */
@@ -57,6 +61,7 @@  typedef struct MemoryDeviceClass {
     MemoryRegion *(*get_memory_region)(MemoryDeviceState *md, Error **errp);
     void (*fill_device_info)(const MemoryDeviceState *md,
                              MemoryDeviceInfo *info);
+    const char *(*get_device_id)(const MemoryDeviceState *md);
 } MemoryDeviceClass;
 
 MemoryDeviceInfoList *qmp_memory_device_list(void);