From patchwork Fri May 3 01:38:05 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 241126 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 4F27D2C00D4 for ; Fri, 3 May 2013 11:38:55 +1000 (EST) Received: from localhost ([::1]:35411 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UY4xZ-0002hO-Gh for incoming@patchwork.ozlabs.org; Thu, 02 May 2013 21:38:53 -0400 Received: from eggs.gnu.org ([208.118.235.92]:58217) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UY4x2-0002g1-NP for qemu-devel@nongnu.org; Thu, 02 May 2013 21:38:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UY4wz-0000Bh-32 for qemu-devel@nongnu.org; Thu, 02 May 2013 21:38:20 -0400 Received: from ozlabs.org ([203.10.76.45]:39790) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UY4wy-0000BJ-GO; Thu, 02 May 2013 21:38:17 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 3D1682C00BD; Fri, 3 May 2013 11:38:14 +1000 (EST) From: David Gibson To: agraf@suse.de, quintela@redhat.com Date: Fri, 3 May 2013 11:38:05 +1000 Message-Id: <1367545092-19980-2-git-send-email-david@gibson.dropbear.id.au> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1367545092-19980-1-git-send-email-david@gibson.dropbear.id.au> References: <1367545092-19980-1-git-send-email-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 203.10.76.45 Cc: aik@ozlabs.ru, qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Subject: [Qemu-devel] [PATCH 1/8] savevm: Implement VMS_DIVIDE flag X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The vmstate infrastructure includes a VMS_MULTIPY flag, and associated VMSTATE_VBUFFER_MULTIPLY helper macro. These can be used to save a variably sized buffer where the size in bytes of the buffer isn't directly accessible as a structure field, but an element count from which the size can be derived is. This patch adds an analogous VMS_DIVIDE option, which handles a variably sized buffer whose size is a submultiple of a field, rather than a multiple. For example a buffer containing per-page structures whose size is derived from a field storing the total address space described by the structures could use this construct. Signed-off-by: David Gibson --- include/migration/vmstate.h | 13 +++++++++++++ savevm.c | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index ebc4d09..787f1cb 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -98,6 +98,7 @@ enum VMStateFlags { VMS_MULTIPLY = 0x200, /* multiply "size" field by field_size */ VMS_VARRAY_UINT8 = 0x400, /* Array with size in uint8_t field*/ VMS_VARRAY_UINT32 = 0x800, /* Array with size in uint32_t field*/ + VMS_DIVIDE = 0x1000, /* divide "size" field by field_size */ }; typedef struct { @@ -420,6 +421,18 @@ extern const VMStateInfo vmstate_info_bitmap; .start = (_start), \ } +#define VMSTATE_VBUFFER_DIVIDE(_field, _state, _version, _test, _start, _field_size, _divide) { \ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .field_exists = (_test), \ + .size_offset = vmstate_offset_value(_state, _field_size, uint32_t),\ + .size = (_divide), \ + .info = &vmstate_info_buffer, \ + .flags = VMS_VBUFFER|VMS_POINTER|VMS_DIVIDE, \ + .offset = offsetof(_state, _field), \ + .start = (_start), \ +} + #define VMSTATE_VBUFFER(_field, _state, _version, _test, _start, _field_size) { \ .name = (stringify(_field)), \ .version_id = (_version), \ diff --git a/savevm.c b/savevm.c index 31dcce9..750b1cb 100644 --- a/savevm.c +++ b/savevm.c @@ -1655,6 +1655,10 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, if (field->flags & VMS_MULTIPLY) { size *= field->size; } + if (field->flags & VMS_DIVIDE) { + assert((size % field->size) == 0); + size /= field->size; + } } if (field->flags & VMS_ARRAY) { n_elems = field->num; @@ -1719,6 +1723,10 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, if (field->flags & VMS_MULTIPLY) { size *= field->size; } + if (field->flags & VMS_DIVIDE) { + assert((size % field->size) == 0); + size /= field->size; + } } if (field->flags & VMS_ARRAY) { n_elems = field->num;