diff mbox series

[v1,4/5] memory-device: Add get_min_alignment() callback

Message ID 20200923113900.72718-5-david@redhat.com
State Accepted
Commit c726aa69419ba2ecd38ae14dc62aaa189c3510e5
Headers show
Series virtio-mem: block size and address-assignment optimizations | expand

Commit Message

David Hildenbrand Sept. 23, 2020, 11:38 a.m. UTC
Will be used by virtio-mem to express special alignment requirements due
to manually configured, big block sizes. This avoids failing later when
realizing, because auto-detection wasn't able to assign a properly
aligned address.

Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Wei Yang <richardw.yang@linux.intel.com>
Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Pankaj Gupta <pankaj.gupta.linux@gmail.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 hw/mem/memory-device.c         | 11 +++++++++--
 include/hw/mem/memory-device.h | 11 +++++++++++
 2 files changed, 20 insertions(+), 2 deletions(-)

Comments

Pankaj Gupta Sept. 26, 2020, 9:07 p.m. UTC | #1
> Will be used by virtio-mem to express special alignment requirements due

> to manually configured, big block sizes. This avoids failing later when

> realizing, because auto-detection wasn't able to assign a properly

> aligned address.

>

> Cc: "Michael S. Tsirkin" <mst@redhat.com>

> Cc: Wei Yang <richardw.yang@linux.intel.com>

> Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>

> Cc: Igor Mammedov <imammedo@redhat.com>

> Cc: Pankaj Gupta <pankaj.gupta.linux@gmail.com>

> Signed-off-by: David Hildenbrand <david@redhat.com>

> ---

>  hw/mem/memory-device.c         | 11 +++++++++--

>  include/hw/mem/memory-device.h | 11 +++++++++++

>  2 files changed, 20 insertions(+), 2 deletions(-)

>

> diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c

> index 8a736f1a26..cf0627fd01 100644

> --- a/hw/mem/memory-device.c

> +++ b/hw/mem/memory-device.c

> @@ -259,7 +259,7 @@ void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms,

>  {

>      const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);

>      Error *local_err = NULL;

> -    uint64_t addr, align;

> +    uint64_t addr, align = 0;

>      MemoryRegion *mr;

>

>      mr = mdc->get_memory_region(md, &local_err);

> @@ -267,7 +267,14 @@ void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms,

>          goto out;

>      }

>

> -    align = legacy_align ? *legacy_align : memory_region_get_alignment(mr);

> +    if (legacy_align) {

> +        align = *legacy_align;

> +    } else {

> +        if (mdc->get_min_alignment) {

> +            align = mdc->get_min_alignment(md);

> +        }

> +        align = MAX(align, memory_region_get_alignment(mr));

> +    }

>      addr = mdc->get_addr(md);

>      addr = memory_device_get_free_addr(ms, !addr ? NULL : &addr, align,

>                                         memory_region_size(mr), &local_err);

> diff --git a/include/hw/mem/memory-device.h b/include/hw/mem/memory-device.h

> index cde52e83c9..563893854a 100644

> --- a/include/hw/mem/memory-device.h

> +++ b/include/hw/mem/memory-device.h

> @@ -88,6 +88,17 @@ struct MemoryDeviceClass {

>       */

>      MemoryRegion *(*get_memory_region)(MemoryDeviceState *md, Error **errp);

>

> +    /*

> +     * Optional: Return the desired minimum alignment of the device in guest

> +     * physical address space, ignoring the alignment requirements of the

> +     * memory region (e.g., based on the page size). The final alignment is

> +     * computed by selecting the maximum of both alignments.

> +     *

> +     * Called when plugging the memory device to detect the required alignment

> +     * during address assignment.

> +     */

> +    uint64_t (*get_min_alignment)(const MemoryDeviceState *md);

> +

>      /*

>       * Translate the memory device into #MemoryDeviceInfo.

>       */

> --


Reviewed-by: Pankaj Gupta <pankaj.gupta.linux@gmail.com>
diff mbox series

Patch

diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c
index 8a736f1a26..cf0627fd01 100644
--- a/hw/mem/memory-device.c
+++ b/hw/mem/memory-device.c
@@ -259,7 +259,7 @@  void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms,
 {
     const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
     Error *local_err = NULL;
-    uint64_t addr, align;
+    uint64_t addr, align = 0;
     MemoryRegion *mr;
 
     mr = mdc->get_memory_region(md, &local_err);
@@ -267,7 +267,14 @@  void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms,
         goto out;
     }
 
-    align = legacy_align ? *legacy_align : memory_region_get_alignment(mr);
+    if (legacy_align) {
+        align = *legacy_align;
+    } else {
+        if (mdc->get_min_alignment) {
+            align = mdc->get_min_alignment(md);
+        }
+        align = MAX(align, memory_region_get_alignment(mr));
+    }
     addr = mdc->get_addr(md);
     addr = memory_device_get_free_addr(ms, !addr ? NULL : &addr, align,
                                        memory_region_size(mr), &local_err);
diff --git a/include/hw/mem/memory-device.h b/include/hw/mem/memory-device.h
index cde52e83c9..563893854a 100644
--- a/include/hw/mem/memory-device.h
+++ b/include/hw/mem/memory-device.h
@@ -88,6 +88,17 @@  struct MemoryDeviceClass {
      */
     MemoryRegion *(*get_memory_region)(MemoryDeviceState *md, Error **errp);
 
+    /*
+     * Optional: Return the desired minimum alignment of the device in guest
+     * physical address space, ignoring the alignment requirements of the
+     * memory region (e.g., based on the page size). The final alignment is
+     * computed by selecting the maximum of both alignments.
+     *
+     * Called when plugging the memory device to detect the required alignment
+     * during address assignment.
+     */
+    uint64_t (*get_min_alignment)(const MemoryDeviceState *md);
+
     /*
      * Translate the memory device into #MemoryDeviceInfo.
      */