diff mbox

[03/17] savevm: Implement VMS_DIVIDE flag

Message ID 1372315560-5478-4-git-send-email-aik@ozlabs.ru
State New
Headers show

Commit Message

Alexey Kardashevskiy June 27, 2013, 6:45 a.m. UTC
From: David Gibson <david@gibson.dropbear.id.au>

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 <david@gibson.dropbear.id.au>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
 include/migration/vmstate.h |   13 +++++++++++++
 savevm.c                    |    8 ++++++++
 2 files changed, 21 insertions(+)

Comments

Anthony Liguori July 8, 2013, 6:27 p.m. UTC | #1
Alexey Kardashevskiy <aik@ozlabs.ru> writes:

> From: David Gibson <david@gibson.dropbear.id.au>
>
> 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.

Why?  What's the point of sending the total size vs. the element count?

It's not like we have legacy that we have to support here...

Regards,

Anthony Liguori

>
> 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 <david@gibson.dropbear.id.au>
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
>  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 48cc2a9..c0fb4a3 100644
> --- a/savevm.c
> +++ b/savevm.c
> @@ -1658,6 +1658,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;
> @@ -1722,6 +1726,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;
> -- 
> 1.7.10.4
David Gibson July 8, 2013, 11:57 p.m. UTC | #2
On Mon, Jul 08, 2013 at 01:27:05PM -0500, Anthony Liguori wrote:
> Alexey Kardashevskiy <aik@ozlabs.ru> writes:
> 
> > From: David Gibson <david@gibson.dropbear.id.au>
> >
> > 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.
> 
> Why?  What's the point of sending the total size vs. the element
> count?

Because it's more convenient to work with the total size at runtime,
and because the VMSTATE stuff works with actual structure fields,
there's not really a way to convert it at migrate time, short of this.
Anthony Liguori July 9, 2013, 2:06 p.m. UTC | #3
David Gibson <david@gibson.dropbear.id.au> writes:

> On Mon, Jul 08, 2013 at 01:27:05PM -0500, Anthony Liguori wrote:
>> Alexey Kardashevskiy <aik@ozlabs.ru> writes:
>> 
>> > From: David Gibson <david@gibson.dropbear.id.au>
>> >
>> > 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.
>> 
>> Why?  What's the point of sending the total size vs. the element
>> count?
>
> Because it's more convenient to work with the total size at runtime,
> and because the VMSTATE stuff works with actual structure fields,
> there's not really a way to convert it at migrate time, short of this.

The only thing I see using it is the tce array which is broken anyway.

Regards,

Anthony Liguori

>
> -- 
> 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
David Gibson July 9, 2013, 2:38 p.m. UTC | #4
On Tue, Jul 09, 2013 at 09:06:21AM -0500, Anthony Liguori wrote:
> David Gibson <david@gibson.dropbear.id.au> writes:
> 
> > On Mon, Jul 08, 2013 at 01:27:05PM -0500, Anthony Liguori wrote:
> >> Alexey Kardashevskiy <aik@ozlabs.ru> writes:
> >> 
> >> > From: David Gibson <david@gibson.dropbear.id.au>
> >> >
> >> > 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.
> >> 
> >> Why?  What's the point of sending the total size vs. the element
> >> count?
> >
> > Because it's more convenient to work with the total size at runtime,
> > and because the VMSTATE stuff works with actual structure fields,
> > there's not really a way to convert it at migrate time, short of this.
> 
> The only thing I see using it is the tce array which is broken
> anyway.

It's only broken due to a bug elsewhere.  Whatever is done there it
will still be some sort of VBUFFER arrangement, and the window will
still be a more convenient thing to work with than the number of
entries.
diff mbox

Patch

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 48cc2a9..c0fb4a3 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1658,6 +1658,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;
@@ -1722,6 +1726,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;