[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 30/32] vmstate: Add preallocation for migrating array
From: |
Alexander Graf |
Subject: |
[Qemu-devel] [PULL 30/32] vmstate: Add preallocation for migrating arrays (VMS_ALLOC flag) |
Date: |
Fri, 27 Jun 2014 13:52:22 +0200 |
From: Alexey Kardashevskiy <address@hidden>
There are few helpers already to support array migration. However they all
require the destination side to preallocate arrays before migration which
is not always possible due to unknown array size as it might be some
sort of dynamic state. One of the examples is an array of MSIX-enabled
devices in SPAPR PHB - this array may vary from 0 to 65536 entries and
its size depends on guest's ability to enable MSIX or do PCI hotplug.
This adds new VMSTATE_VARRAY_STRUCT_ALLOC macro which is pretty similar to
VMSTATE_STRUCT_VARRAY_POINTER_INT32 but it can alloc memory for migratign
array on the destination side.
This defines VMS_ALLOC flag for a field.
This changes vmstate_base_addr() to do the allocation when receiving
migration.
Signed-off-by: Alexey Kardashevskiy <address@hidden>
Reviewed-by: Juan Quintela <address@hidden>
[agraf: drop g_malloc_n usage]
Signed-off-by: Alexander Graf <address@hidden>
---
include/migration/vmstate.h | 11 +++++++++++
vmstate.c | 13 ++++++++++---
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 71a8a95..9a001bd 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -101,6 +101,7 @@ enum VMStateFlags {
VMS_VARRAY_UINT8 = 0x400, /* Array with size in uint8_t field*/
VMS_VARRAY_UINT32 = 0x800, /* Array with size in uint32_t field*/
VMS_MUST_EXIST = 0x1000, /* Field must exist in input */
+ VMS_ALLOC = 0x2000, /* Alloc a buffer on the destination */
};
typedef struct {
@@ -429,6 +430,16 @@ extern const VMStateInfo vmstate_info_bitmap;
.offset = offsetof(_state, _field), \
}
+#define VMSTATE_STRUCT_VARRAY_ALLOC(_field, _state, _field_num, _version,
_vmsd, _type) {\
+ .name = (stringify(_field)), \
+ .version_id = (_version), \
+ .vmsd = &(_vmsd), \
+ .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \
+ .size = sizeof(_type), \
+ .flags = VMS_STRUCT|VMS_VARRAY_INT32|VMS_ALLOC|VMS_POINTER, \
+ .offset = vmstate_offset_pointer(_state, _field, _type), \
+}
+
#define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size)
{ \
.name = (stringify(_field)), \
.version_id = (_version), \
diff --git a/vmstate.c b/vmstate.c
index c996520..ef2f87b 100644
--- a/vmstate.c
+++ b/vmstate.c
@@ -43,11 +43,18 @@ static int vmstate_size(void *opaque, VMStateField *field)
return size;
}
-static void *vmstate_base_addr(void *opaque, VMStateField *field)
+static void *vmstate_base_addr(void *opaque, VMStateField *field, bool alloc)
{
void *base_addr = opaque + field->offset;
if (field->flags & VMS_POINTER) {
+ if (alloc && (field->flags & VMS_ALLOC)) {
+ int n_elems = vmstate_n_elems(opaque, field);
+ if (n_elems) {
+ gsize size = n_elems * field->size;
+ *((void **)base_addr + field->start) = g_malloc(size);
+ }
+ }
base_addr = *(void **)base_addr + field->start;
}
@@ -81,7 +88,7 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription
*vmsd,
field->field_exists(opaque, version_id)) ||
(!field->field_exists &&
field->version_id <= version_id)) {
- void *base_addr = vmstate_base_addr(opaque, field);
+ void *base_addr = vmstate_base_addr(opaque, field, true);
int i, n_elems = vmstate_n_elems(opaque, field);
int size = vmstate_size(opaque, field);
@@ -135,7 +142,7 @@ void vmstate_save_state(QEMUFile *f, const
VMStateDescription *vmsd,
while (field->name) {
if (!field->field_exists ||
field->field_exists(opaque, vmsd->version_id)) {
- void *base_addr = vmstate_base_addr(opaque, field);
+ void *base_addr = vmstate_base_addr(opaque, field, false);
int i, n_elems = vmstate_n_elems(opaque, field);
int size = vmstate_size(opaque, field);
--
1.8.1.4
- [Qemu-devel] [PULL 32/32] PPC: e500: Only create dt entries for existing serial ports, (continued)
- [Qemu-devel] [PULL 32/32] PPC: e500: Only create dt entries for existing serial ports, Alexander Graf, 2014/06/27
- [Qemu-devel] [PULL 21/32] spapr: Fix RTAS sysparm DIAGNOSTICS_RUN_MODE, Alexander Graf, 2014/06/27
- [Qemu-devel] [PULL 24/32] xics: Add flags for interrupts, Alexander Graf, 2014/06/27
- [Qemu-devel] [PULL 26/32] xics: Disable flags reset on xics reset, Alexander Graf, 2014/06/27
- [Qemu-devel] [PULL 16/32] uninorth: Fix PCI hole size, Alexander Graf, 2014/06/27
- [Qemu-devel] [PULL 06/32] target-ppc: fixed translation of mcrxr instruction, Alexander Graf, 2014/06/27
- [Qemu-devel] [PULL 31/32] spapr_pci: Use XICS interrupt allocator and do not cache interrupts in PHB, Alexander Graf, 2014/06/27
- [Qemu-devel] [PULL 28/32] spapr: Remove @next_irq, Alexander Graf, 2014/06/27
- [Qemu-devel] [PULL 20/32] spapr: Add rtas_st_buffer utility function, Alexander Graf, 2014/06/27
- [Qemu-devel] [PULL 27/32] spapr: Move interrupt allocator to xics, Alexander Graf, 2014/06/27
- [Qemu-devel] [PULL 30/32] vmstate: Add preallocation for migrating arrays (VMS_ALLOC flag),
Alexander Graf <=
- [Qemu-devel] [PULL 23/32] spapr: Add RTAS sysparm SPLPAR Characteristics, Alexander Graf, 2014/06/27
- Re: [Qemu-devel] [PULL 00/32] ppc patch queue 2014-06-27, Peter Maydell, 2014/06/29