Signed-off-by: Md Haris Iqbal <haris.p...@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 --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; -- 2.7.4