From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58715) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wv6Ws-0004va-Eb for qemu-devel@nongnu.org; Thu, 12 Jun 2014 11:03:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Wv6Wl-0000rx-KI for qemu-devel@nongnu.org; Thu, 12 Jun 2014 11:03:02 -0400 Received: from mail-pd0-f181.google.com ([209.85.192.181]:61000) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wv6Wl-0000rD-Cs for qemu-devel@nongnu.org; Thu, 12 Jun 2014 11:02:55 -0400 Received: by mail-pd0-f181.google.com with SMTP id v10so172761pde.40 for ; Thu, 12 Jun 2014 08:02:54 -0700 (PDT) Message-ID: <5399C112.2090205@ozlabs.ru> Date: Fri, 13 Jun 2014 01:02:42 +1000 From: Alexey Kardashevskiy MIME-Version: 1.0 References: <1401442460-32648-1-git-send-email-aik@ozlabs.ru> <1401442460-32648-9-git-send-email-aik@ozlabs.ru> <538DCB4C.4040905@ozlabs.ru> <5393A77C.80202@ozlabs.ru> In-Reply-To: <5393A77C.80202@ozlabs.ru> Content-Type: text/plain; charset=KOI8-R Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v3 8/9] vmstate: Add preallocation for migrating arrays (VMS_ALLOC flag) List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, Juan Quintela Cc: Peter Maydell , qemu-ppc@nongnu.org, Alexander Graf On 06/08/2014 09:59 AM, Alexey Kardashevskiy wrote: > 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? :) Ping? > > > >> >> >>> >>> Signed-off-by: Alexey Kardashevskiy >>> --- >>> 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