From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51262) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b8Jsy-00069o-Bf for qemu-devel@nongnu.org; Thu, 02 Jun 2016 00:05:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b8Jsv-0005qc-Ar for qemu-devel@nongnu.org; Thu, 02 Jun 2016 00:05:31 -0400 Date: Thu, 2 Jun 2016 13:58:00 +1000 From: David Gibson Message-ID: <20160602035800.GA22284@voom.fritz.box> References: <1464717764-9040-1-git-send-email-duanj@linux.vnet.ibm.com> <1464717764-9040-5-git-send-email-duanj@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="CE+1k2dSO48ffgeK" Content-Disposition: inline In-Reply-To: <1464717764-9040-5-git-send-email-duanj@linux.vnet.ibm.com> Subject: Re: [Qemu-devel] [QEMU RFC PATCH v3 4/6] Migration: migrate QTAILQ List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Jianjun Duan Cc: qemu-devel@nongnu.org, qemu-ppc@nongnu.org, dmitry@daynix.com, peter.maydell@linaro.org, kraxel@redhat.com, mst@redhat.com, pbonzini@redhat.com, veroniabahaa@gmail.com, quintela@redhat.com, amit.shah@redhat.com, mreitz@redhat.com, kwolf@redhat.com, rth@twiddle.net, aurelien@aurel32.net, leon.alrae@imgtec.com, blauwirbel@gmail.com, mark.cave-ayland@ilande.co.uk, mdroth@linux.vnet.ibm.com, dgilbert@redhat.com --CE+1k2dSO48ffgeK Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, May 31, 2016 at 11:02:42AM -0700, Jianjun Duan wrote: > Currently we cannot directly transfer a QTAILQ instance because of the > limitation in the migration code. Here we introduce an approach to > transfer such structures. In our approach such a structure is tagged > with VMS_CSTM. We then modified vmstate_save_state and vmstate_load_state > so that when VMS_CSTM is encountered, put and get from VMStateInfo are > called respectively. This approach will be used to transfer pending_events > and ccs_list in spapr state. >=20 > We also create some macros in qemu/queue.h to access a QTAILQ using point= er > arithmetic. This ensures that we do not depend on the implementation > details about QTAILQ in the migration code. >=20 > Signed-off-by: Jianjun Duan I'm comfortable with 3&4 of 6, but I'd prefer to see them merged via the migration tree. Juan, Dave, are you ok to merge these? > --- > include/migration/vmstate.h | 22 +++++++++++++ > include/qemu/queue.h | 32 ++++++++++++++++++ > migration/vmstate.c | 79 +++++++++++++++++++++++++++++++++++++++= ++++++ > 3 files changed, 133 insertions(+) >=20 > diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h > index 56a4171..da4ef7f 100644 > --- a/include/migration/vmstate.h > +++ b/include/migration/vmstate.h > @@ -185,6 +185,8 @@ enum VMStateFlags { > * to determine the number of entries in the array. Only valid in > * combination with one of VMS_VARRAY*. */ > VMS_MULTIPLY_ELEMENTS =3D 0x4000, > + /* For fields which need customized handling, such as QTAILQ in queu= e.h*/ > + VMS_CSTM =3D 0x8000, > }; > =20 > struct VMStateField { > @@ -245,6 +247,7 @@ extern const VMStateInfo vmstate_info_timer; > extern const VMStateInfo vmstate_info_buffer; > extern const VMStateInfo vmstate_info_unused_buffer; > extern const VMStateInfo vmstate_info_bitmap; > +extern const VMStateInfo vmstate_info_qtailq; > =20 > #define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0) > #define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0) > @@ -656,6 +659,25 @@ extern const VMStateInfo vmstate_info_bitmap; > .offset =3D offsetof(_state, _field), \ > } > =20 > +/* For QTAILQ that need customized handling > + * _type: type of QTAILQ element > + * _next: name of QTAILQ entry field in QTAILQ element > + * _vmsd: VMSD for QTAILQ element > + * size: size of QTAILQ element > + * start: offset of QTAILQ entry in QTAILQ element > + */ > +#define VMSTATE_QTAILQ_V(_field, _state, _version, _vmsd, _type, _next) = \ > +{ = \ > + .name =3D (stringify(_field)), = \ > + .version_id =3D (_version), = \ > + .vmsd =3D &(_vmsd), = \ > + .size =3D sizeof(_type), = \ > + .info =3D &vmstate_info_qtailq, = \ > + .flags =3D VMS_CSTM, = \ > + .offset =3D offsetof(_state, _field), = \ > + .start =3D offsetof(_type, _next), = \ > +} > + > /* _f : field name > _f_n : num of elements field_name > _n : num of elements > diff --git a/include/qemu/queue.h b/include/qemu/queue.h > index f781aa2..003e368 100644 > --- a/include/qemu/queue.h > +++ b/include/qemu/queue.h > @@ -437,3 +437,35 @@ struct { = \ > (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) > =20 > #endif /* !QEMU_SYS_QUEUE_H_ */ > + > +/* > + * Offsets of layout of a tail queue head. > + */ > +#define QTAILQ_FIRST_OFFSET 0 > +#define QTAILQ_LAST_OFFSET (sizeof(void *)) > + > +/* > + * Offsets of layout of a tail queue element. > + */ > +#define QTAILQ_NEXT_OFFSET 0 > +#define QTAILQ_PREV_OFFSET (sizeof(void *)) > + > +/* > + * Tail queue tranversal using pointer arithmetic. > + */ > +#define QTAILQ_RAW_FOREACH(elm, head, entry) = \ > + for ((elm) =3D *((void **) ((char *) (head) + QTAILQ_FIRST_OFFSE= T)); \ > + (elm); = \ > + (elm) =3D = \ > + *((void **) ((char *) (elm) + (entry) + QTAILQ_NEXT_OFF= SET))) > +/* > + * Tail queue insertion using pointer arithmetic. > + */ > +#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do { = \ > + *((void **) ((char *) (elm) + (entry) + QTAILQ_NEXT_OFFSET)) =3D= NULL; \ > + *((void **) ((char *) (elm) + (entry) + QTAILQ_PREV_OFFSET)) =3D= \ > + *((void **) ((char *) (head) +QTAILQ_LAST_OFFSET)); = \ > + **((void ***)((char *) (head) +QTAILQ_LAST_OFFSET)) =3D (elm); = \ > + *((void **) ((char *) (head) + QTAILQ_LAST_OFFSET)) =3D = \ > + (void *) ((char *) (elm) + (entry) + QTAILQ_NEXT_OFFSET); = \ > +} while (/*CONSTCOND*/0) > diff --git a/migration/vmstate.c b/migration/vmstate.c > index 644ba1f..ff56650 100644 > --- a/migration/vmstate.c > +++ b/migration/vmstate.c > @@ -5,7 +5,9 @@ > #include "migration/vmstate.h" > #include "qemu/bitops.h" > #include "qemu/error-report.h" > +#include "qemu/queue.h" > #include "trace.h" > +#include "migration/qjson.h" > =20 > static void vmstate_subsection_save(QEMUFile *f, const VMStateDescriptio= n *vmsd, > void *opaque, QJSON *vmdesc); > @@ -120,6 +122,8 @@ int vmstate_load_state(QEMUFile *f, const VMStateDesc= ription *vmsd, > if (field->flags & VMS_STRUCT) { > ret =3D vmstate_load_state(f, field->vmsd, addr, > field->vmsd->version_id); > + } else if (field->flags & VMS_CSTM) { > + ret =3D field->info->get(f, addr, size, field); > } else { > ret =3D field->info->get(f, addr, size, NULL); > =20 > @@ -192,6 +196,8 @@ static const char *vmfield_get_type_name(VMStateField= *field) > =20 > if (field->flags & VMS_STRUCT) { > type =3D "struct"; > + } else if (field->flags & VMS_CSTM) { > + type =3D "customized"; > } else if (field->info->name) { > type =3D field->info->name; > } > @@ -326,6 +332,8 @@ void vmstate_save_state(QEMUFile *f, const VMStateDes= cription *vmsd, > } > if (field->flags & VMS_STRUCT) { > vmstate_save_state(f, field->vmsd, addr, vmdesc_loop= ); > + } else if (field->flags & VMS_CSTM) { > + field->info->put(f, addr, size, field, vmdesc_loop); > } else { > field->info->put(f, addr, size, NULL, NULL); > } > @@ -938,3 +946,74 @@ const VMStateInfo vmstate_info_bitmap =3D { > .get =3D get_bitmap, > .put =3D put_bitmap, > }; > + > +/*get for QTAILQ */ > +static int get_qtailq(QEMUFile *f, void *pv, size_t unused_size, > + VMStateField *field) > +{ > + bool link; > + int ret =3D 0; > + const VMStateDescription *vmsd =3D field->vmsd; > + size_t size =3D field->size; > + size_t entry =3D field->start; > + int version_id =3D field->version_id; > + void *elm; > + > + trace_vmstate_load_state(vmsd->name, version_id); > + if (version_id > vmsd->version_id) { > + trace_vmstate_load_state_end(vmsd->name, "too new", -EINVAL); > + return -EINVAL; > + } > + if (version_id < vmsd->minimum_version_id) { > + trace_vmstate_load_state_end(vmsd->name, "too old", -EINVAL); > + return -EINVAL; > + } > + > + while (true) { > + vmstate_info_bool.get(f, &link, sizeof(bool), NULL); > + if (!link) { > + break; > + } > + > + elm =3D g_malloc(size); > + ret =3D vmstate_load_state(f, vmsd, elm, version_id); > + if (ret) { > + return ret; > + } > + QTAILQ_RAW_INSERT_TAIL(pv, elm, entry); > + } > + > + trace_vmstate_load_state_end(vmsd->name, "end", ret); > + return ret; > +} > + > +/* put for QTAILQ */ > +static void put_qtailq(QEMUFile *f, void *pv, size_t unused_size, > + VMStateField *field, QJSON *vmdesc) > +{ > + bool link =3D true; > + const VMStateDescription *vmsd =3D field->vmsd; > + size_t entry =3D field->start; > + void *elm; > + > + if (vmdesc) { > + json_prop_str(vmdesc, "vmsd_name", vmsd->name); > + json_prop_int(vmdesc, "version", vmsd->version_id); > + json_start_array(vmdesc, "fields"); > + } > + > + QTAILQ_RAW_FOREACH(elm, pv, entry) { > + vmstate_info_bool.put(f, &link, sizeof(bool), NULL, NULL); > + vmstate_save_state(f, vmsd, elm, vmdesc); > + } > + link =3D false; > + vmstate_info_bool.put(f, &link, sizeof(bool), NULL, NULL); > + if (vmdesc) { > + json_end_array(vmdesc); > + } > +} > +const VMStateInfo vmstate_info_qtailq =3D { > + .name =3D "qtailq", > + .get =3D get_qtailq, > + .put =3D put_qtailq, > +}; --=20 David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson --CE+1k2dSO48ffgeK Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBAgAGBQJXT67IAAoJEGw4ysog2bOSi4YP/0zyrqaO4so1Sy1XloyeIYUg 1KEFxj0bAcIv8an1TAjsunHtSKoOEDdQWl9JzL3FEFLxtKktLonMOwVbR7pft6mj tdA8uqR1AGJ92V72BCg4bzNHfIPaWnLVS952gmZUDLX9V1Hoqpp59MpyUGwQOivS 9R/z5EqoerKz29Bet2enwQm3b/OA9iIfOZTS0lHjEEclOVuiATAInYLSY+QmMt7T DPr5NdLwedh5vSGFfLpo/I8nLPAvrvTlpSE7miHrMuAjQe5WAvrHVE7RqHOq19ne I4z1g1zvz6bjsHpgi5EK3gIK8DyETln+L9GDPXiCByntEL4fpYjgurTbIiszJVOG LIixtuoLU3O9ZvIB/fQtKHS++/QjYNeOel4MYNd+d9ySd/F6qtGcSsYt9pe0HU/X RDOdPdwngAMPqA/5NbPjaz+x9Kcc9i5MYPcdG06Ckpc8JTf+lK8RU8M98UHMS0qp 5+R7pf9i0xZ0IPLE6epXiSd+qYxu6kArSohTq/3aXeexNriipnxf4Wfc7g1uvwH1 KPJGXNQIfcKYY9pGGD2TL5gKbnSYEKC0Jyufev1OdXnCmVbv76QNTL5i+QSFxRnb nLMzLZiDb+6q/5Qvh3JLFeGlH8kNygo+B/fCd49wgqMkYQ7MCSSNzRWBixV2QnXB w558VLZMCh4JfYeN/J4b =2caA -----END PGP SIGNATURE----- --CE+1k2dSO48ffgeK--