diff mbox

[6/6] Migration: Recovering pages lost due to n/w failure during pc migration (destination)

Message ID 1471813132-13836-7-git-send-email-haris.phnx@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Md Haris Iqbal Aug. 21, 2016, 8:58 p.m. UTC
Signed-off-by: Md Haris Iqbal <haris.phnx@gmail.com>
---
 include/migration/migration.h |  1 +
 include/sysemu/sysemu.h       |  1 +
 migration/ram.c               | 35 +++++++++++++++++++++++++++++++++++
 migration/savevm.c            | 12 ++++++++++++
 4 files changed, 49 insertions(+)
diff mbox

Patch

diff --git a/include/migration/migration.h b/include/migration/migration.h
index 5533832..cda5ece 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -366,6 +366,7 @@  int qemu_migrate_postcopy_incoming_recovery(QEMUFile **f,MigrationIncomingState*
 void migrate_incoming_ram_bitmap_init(void);
 void migrate_incoming_ram_bitmap_update(RAMBlock *rb, ram_addr_t addr);
 void migrate_incoming_ram_bitmap_free(void);
+void *migrate_incoming_ram_req_pages(void *opaque);
 
 PostcopyState postcopy_state_get(void);
 /* Set the state and return the old state */
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index ee7c760..af5630c 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -100,6 +100,7 @@  enum qemu_vm_cmd {
                                       were previously sent during
                                       precopy but are dirty. */
     MIG_CMD_PACKAGED,          /* Send a wrapped stream within this stream */
+    MIG_CMD_POSTCOPY_RECOVERY,  /* Send pages lost due to n/w failure */
     MIG_CMD_MAX
 };
 
diff --git a/migration/ram.c b/migration/ram.c
index ea1382b..28381b6 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2649,6 +2649,41 @@  void migrate_incoming_ram_bitmap_free(void)
     }
 }
 
+void *migrate_incoming_ram_req_pages(void* opaque)
+{
+    MigrationIncomingState *mis = opaque;
+    struct RAMBlock *rb;
+    size_t hostpagesize = getpagesize();
+    uint64_t addr;
+    unsigned long base;
+    unsigned long nr;
+    unsigned long rb_end;
+    unsigned long next;
+    unsigned long *not_received;
+
+    not_received = atomic_rcu_read(&migration_bitmap_rcu)->not_received;
+    QLIST_FOREACH_RCU(rb, &ram_list.blocks, next) {
+        addr = 0;
+        base = rb->offset >> TARGET_PAGE_BITS;
+        rb_end = base + (rb->used_length >> TARGET_PAGE_BITS);
+        while (true) {
+            nr = base + (addr >> TARGET_PAGE_BITS);
+            next = find_next_bit(not_received, rb_end, nr);
+            addr = (next - base) << TARGET_PAGE_BITS;
+
+            if (addr >= rb->used_length) {
+                break;
+            }
+            else {
+                migrate_send_rp_req_pages(mis, qemu_ram_get_idstr(rb),
+                                     addr, hostpagesize);
+                addr++;
+            }
+        }
+    }
+    return NULL;
+}
+
 static SaveVMHandlers savevm_ram_handlers = {
     .save_live_setup = ram_save_setup,
     .save_live_iterate = ram_save_iterate,
diff --git a/migration/savevm.c b/migration/savevm.c
index aa4f777..2301b74 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1621,6 +1621,7 @@  static int loadvm_process_command(QEMUFile *f)
     uint16_t cmd;
     uint16_t len;
     uint32_t tmp32;
+    QemuThread req_pages_not_received;
 
     cmd = qemu_get_be16(f);
     len = qemu_get_be16(f);
@@ -1677,6 +1678,17 @@  static int loadvm_process_command(QEMUFile *f)
 
     case MIG_CMD_POSTCOPY_RAM_DISCARD:
         return loadvm_postcopy_ram_handle_discard(mis, len);
+
+    case MIG_CMD_POSTCOPY_RECOVERY:
+        /*
+         * This case will only be used when migration recovers from a
+         * network failure during a postcopy migration.
+         * Now, send the requests for pages that were lost due to the
+         * network failure.
+         */
+        qemu_thread_create(&req_pages_not_received, "pc/recovery",
+                       migrate_incoming_ram_req_pages, mis, QEMU_THREAD_DETACHED);
+            break;
     }
 
     return 0;