[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v3 8/9] vmstate: Add preallocation for migrating
From: |
Alexey Kardashevskiy |
Subject: |
Re: [Qemu-devel] [PATCH v3 8/9] vmstate: Add preallocation for migrating arrays (VMS_ALLOC flag) |
Date: |
Sun, 08 Jun 2014 09:59:56 +1000 |
User-agent: |
Mozilla/5.0 (X11; Linux i686 on x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 |
On 06/03/2014 11:19 PM, Alexey Kardashevskiy wrote:
> On 05/30/2014 07:34 PM, Alexey Kardashevskiy wrote:
>> 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.
>
>
>
> Juan, Peter? No hurry, just pinging in order not to forget :) Thanks!
Hi, anyone? :)
>
>
>>
>> Signed-off-by: Alexey Kardashevskiy <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 7e45048..e794694 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 b5882fa..fb95e39 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) {
>> + *((void **)base_addr + field->start) = g_malloc_n(n_elems,
>> +
>> field->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);
>>
>> @@ -131,7 +138,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);
>>
>>
>
>
--
Alexey