diff mbox

[v7,24/42] Add qemu_savevm_state_complete_postcopy

Message ID 1434450415-11339-25-git-send-email-dgilbert@redhat.com
State New
Headers show

Commit Message

Dr. David Alan Gilbert June 16, 2015, 10:26 a.m. UTC
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

Add qemu_savevm_state_complete_postcopy to complement
qemu_savevm_state_complete_precopy together with a new
save_live_complete_postcopy method on devices.

The save_live_complete_precopy method is called on
all devices during a precopy migration, and all non-postcopy
devices during a postcopy migration at the transition.

The save_live_complete_postcopy method is called at
the end of postcopy for all postcopiable devices.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 include/migration/vmstate.h |  1 +
 include/sysemu/sysemu.h     |  1 +
 migration/ram.c             |  1 +
 migration/savevm.c          | 51 ++++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 51 insertions(+), 3 deletions(-)

Comments

Juan Quintela July 13, 2015, 11:35 a.m. UTC | #1
"Dr. David Alan Gilbert (git)" <dgilbert@redhat.com> wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> Add qemu_savevm_state_complete_postcopy to complement
> qemu_savevm_state_complete_precopy together with a new
> save_live_complete_postcopy method on devices.
>
> The save_live_complete_precopy method is called on
> all devices during a precopy migration, and all non-postcopy
> devices during a postcopy migration at the transition.
>
> The save_live_complete_postcopy method is called at
> the end of postcopy for all postcopiable devices.
>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

Reviewed-by: Juan Quintela <quintela@redhat.com>


> @@ -947,13 +987,15 @@ void qemu_savevm_state_complete_precopy(QEMUFile *f)
>      int vmdesc_len;
>      SaveStateEntry *se;
>      int ret;
> +    bool in_postcopy = migration_postcopy_phase(migrate_get_current());
>  
>      trace_savevm_state_complete_precopy();
>  
>      cpu_synchronize_all_states();
>  
>      QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
> -        if (!se->ops || !se->ops->save_live_complete_precopy) {
> +        if (!se->ops || !se->ops->save_live_complete_precopy ||
> +            (in_postcopy && se->ops->save_live_complete_postcopy)) {
>              continue;
>          }

I would change the formatting to something like:

       if (!se->ops ||
           (in_postcopy && se->ops->save_live_complete_postcopy)
           !se->ops->save_live_complete_precopy) {
              continue
           }

Just to make easier to see when we exit?

Later, Juan.
Dr. David Alan Gilbert July 13, 2015, 3:33 p.m. UTC | #2
* Juan Quintela (quintela@redhat.com) wrote:
> "Dr. David Alan Gilbert (git)" <dgilbert@redhat.com> wrote:
> > From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> >
> > Add qemu_savevm_state_complete_postcopy to complement
> > qemu_savevm_state_complete_precopy together with a new
> > save_live_complete_postcopy method on devices.
> >
> > The save_live_complete_precopy method is called on
> > all devices during a precopy migration, and all non-postcopy
> > devices during a postcopy migration at the transition.
> >
> > The save_live_complete_postcopy method is called at
> > the end of postcopy for all postcopiable devices.
> >
> > Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> 
> Reviewed-by: Juan Quintela <quintela@redhat.com>

Thanks.

> 
> > @@ -947,13 +987,15 @@ void qemu_savevm_state_complete_precopy(QEMUFile *f)
> >      int vmdesc_len;
> >      SaveStateEntry *se;
> >      int ret;
> > +    bool in_postcopy = migration_postcopy_phase(migrate_get_current());
> >  
> >      trace_savevm_state_complete_precopy();
> >  
> >      cpu_synchronize_all_states();
> >  
> >      QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
> > -        if (!se->ops || !se->ops->save_live_complete_precopy) {
> > +        if (!se->ops || !se->ops->save_live_complete_precopy ||
> > +            (in_postcopy && se->ops->save_live_complete_postcopy)) {
> >              continue;
> >          }
> 
> I would change the formatting to something like:
> 
>        if (!se->ops ||
>            (in_postcopy && se->ops->save_live_complete_postcopy)
>            !se->ops->save_live_complete_precopy) {
>               continue
>            }
> 
> Just to make easier to see when we exit?

Done

Dave (Starting with the easy fix first :-)

> 
> Later, Juan.
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
Amit Shah July 21, 2015, 10:42 a.m. UTC | #3
On (Tue) 16 Jun 2015 [11:26:37], Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> 
> Add qemu_savevm_state_complete_postcopy to complement
> qemu_savevm_state_complete_precopy together with a new
> save_live_complete_postcopy method on devices.
> 
> The save_live_complete_precopy method is called on
> all devices during a precopy migration, and all non-postcopy
> devices during a postcopy migration at the transition.
> 
> The save_live_complete_postcopy method is called at
> the end of postcopy for all postcopiable devices.
> 
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

Reviewed-by: Amit Shah <amit.shah@redhat.com>

But:

> --- a/migration/savevm.c
> +++ b/migration/savevm.c
> @@ -938,7 +938,47 @@ int qemu_savevm_state_iterate(QEMUFile *f)
>  static bool should_send_vmdesc(void)
>  {
>      MachineState *machine = MACHINE(qdev_get_machine());
> -    return !machine->suppress_vmdesc;
> +    bool in_postcopy = migration_postcopy_phase(migrate_get_current());
> +    return !machine->suppress_vmdesc && !in_postcopy;
> +}

This should be split in its own patch.


		Amit
Dr. David Alan Gilbert July 27, 2015, 5:58 p.m. UTC | #4
* Amit Shah (amit.shah@redhat.com) wrote:
> On (Tue) 16 Jun 2015 [11:26:37], Dr. David Alan Gilbert (git) wrote:
> > From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> > 
> > Add qemu_savevm_state_complete_postcopy to complement
> > qemu_savevm_state_complete_precopy together with a new
> > save_live_complete_postcopy method on devices.
> > 
> > The save_live_complete_precopy method is called on
> > all devices during a precopy migration, and all non-postcopy
> > devices during a postcopy migration at the transition.
> > 
> > The save_live_complete_postcopy method is called at
> > the end of postcopy for all postcopiable devices.
> > 
> > Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> 
> Reviewed-by: Amit Shah <amit.shah@redhat.com>
> 
> But:
> 
> > --- a/migration/savevm.c
> > +++ b/migration/savevm.c
> > @@ -938,7 +938,47 @@ int qemu_savevm_state_iterate(QEMUFile *f)
> >  static bool should_send_vmdesc(void)
> >  {
> >      MachineState *machine = MACHINE(qdev_get_machine());
> > -    return !machine->suppress_vmdesc;
> > +    bool in_postcopy = migration_postcopy_phase(migrate_get_current());
> > +    return !machine->suppress_vmdesc && !in_postcopy;
> > +}
> 
> This should be split in its own patch.

Thanks, split.

Dave
> 
> 
> 		Amit
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
diff mbox

Patch

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 7257196..dddeadd 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -40,6 +40,7 @@  typedef struct SaveVMHandlers {
     SaveStateHandler *save_state;
 
     void (*cancel)(void *opaque);
+    int (*save_live_complete_postcopy)(QEMUFile *f, void *opaque);
     int (*save_live_complete_precopy)(QEMUFile *f, void *opaque);
 
     /* This runs both outside and inside the iothread lock.  */
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index ff6bb2c..1af2ea0 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -108,6 +108,7 @@  void qemu_savevm_state_begin(QEMUFile *f,
                              const MigrationParams *params);
 void qemu_savevm_state_header(QEMUFile *f);
 int qemu_savevm_state_iterate(QEMUFile *f);
+void qemu_savevm_state_complete_postcopy(QEMUFile *f);
 void qemu_savevm_state_complete_precopy(QEMUFile *f);
 void qemu_savevm_state_cancel(void);
 void qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size,
diff --git a/migration/ram.c b/migration/ram.c
index fb24954..ff1a2fb 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1608,6 +1608,7 @@  static int ram_load(QEMUFile *f, void *opaque, int version_id)
 static SaveVMHandlers savevm_ram_handlers = {
     .save_live_setup = ram_save_setup,
     .save_live_iterate = ram_save_iterate,
+    .save_live_complete_postcopy = ram_save_complete,
     .save_live_complete_precopy = ram_save_complete,
     .save_live_pending = ram_save_pending,
     .load_state = ram_load,
diff --git a/migration/savevm.c b/migration/savevm.c
index f324c6e..b7f17b4 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -938,7 +938,47 @@  int qemu_savevm_state_iterate(QEMUFile *f)
 static bool should_send_vmdesc(void)
 {
     MachineState *machine = MACHINE(qdev_get_machine());
-    return !machine->suppress_vmdesc;
+    bool in_postcopy = migration_postcopy_phase(migrate_get_current());
+    return !machine->suppress_vmdesc && !in_postcopy;
+}
+
+/*
+ * Calls the save_live_complete_postcopy methods
+ * causing the last few pages to be sent immediately and doing any associated
+ * cleanup.
+ * Note postcopy also calls qemu_savevm_state_complete_precopy to complete
+ * all the other devices, but that happens at the point we switch to postcopy.
+ */
+void qemu_savevm_state_complete_postcopy(QEMUFile *f)
+{
+    SaveStateEntry *se;
+    int ret;
+
+    QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
+        if (!se->ops || !se->ops->save_live_complete_postcopy) {
+            continue;
+        }
+        if (se->ops && se->ops->is_active) {
+            if (!se->ops->is_active(se->opaque)) {
+                continue;
+            }
+        }
+        trace_savevm_section_start(se->idstr, se->section_id);
+        /* Section type */
+        qemu_put_byte(f, QEMU_VM_SECTION_END);
+        qemu_put_be32(f, se->section_id);
+
+        ret = se->ops->save_live_complete_postcopy(f, se->opaque);
+        trace_savevm_section_end(se->idstr, se->section_id, ret);
+        save_section_footer(f, se);
+        if (ret < 0) {
+            qemu_file_set_error(f, ret);
+            return;
+        }
+    }
+
+    qemu_put_byte(f, QEMU_VM_EOF);
+    qemu_fflush(f);
 }
 
 void qemu_savevm_state_complete_precopy(QEMUFile *f)
@@ -947,13 +987,15 @@  void qemu_savevm_state_complete_precopy(QEMUFile *f)
     int vmdesc_len;
     SaveStateEntry *se;
     int ret;
+    bool in_postcopy = migration_postcopy_phase(migrate_get_current());
 
     trace_savevm_state_complete_precopy();
 
     cpu_synchronize_all_states();
 
     QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
-        if (!se->ops || !se->ops->save_live_complete_precopy) {
+        if (!se->ops || !se->ops->save_live_complete_precopy ||
+            (in_postcopy && se->ops->save_live_complete_postcopy)) {
             continue;
         }
         if (se->ops && se->ops->is_active) {
@@ -997,7 +1039,10 @@  void qemu_savevm_state_complete_precopy(QEMUFile *f)
         save_section_footer(f, se);
     }
 
-    qemu_put_byte(f, QEMU_VM_EOF);
+    if (!in_postcopy) {
+        /* Postcopy stream will still be going */
+        qemu_put_byte(f, QEMU_VM_EOF);
+    }
 
     json_end_array(vmdesc);
     qjson_finish(vmdesc);