Message ID | 20200923113900.72718-5-david@redhat.com |
---|---|
State | Accepted |
Commit | c726aa69419ba2ecd38ae14dc62aaa189c3510e5 |
Headers | show |
Series | virtio-mem: block size and address-assignment optimizations | expand |
> 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 --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. */
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(-)