Message ID | 1377069536-12658-16-git-send-email-lilei@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
Il 21/08/2013 09:18, Lei Li ha scritto: > Integrate localhost migration thread to migration_thread. As the mechanism > of local migration is different than the current migration, and it does > not need to do iterate. > > So the whole thread can split into two stages, it will send all the ram > pages in qemu_savevm_state_begin stage, and send the device states in > qemu_save_device_state stage. This is not needed. Skipping the iteration should happen automatically if you stop the VM before invoking migration. Paolo > Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com> > --- > migration.c | 73 ++++++++++++++++++++++++++++++++++++---------------------- > 1 files changed, 45 insertions(+), 28 deletions(-) > > diff --git a/migration.c b/migration.c > index 2f85358..2471664 100644 > --- a/migration.c > +++ b/migration.c > @@ -565,37 +565,54 @@ static void *migration_thread(void *opaque) > while (s->state == MIG_STATE_ACTIVE) { > int64_t current_time; > uint64_t pending_size; > + int ret; > > - if (!qemu_file_rate_limit(s->file)) { > - DPRINTF("iterate\n"); > - pending_size = qemu_savevm_state_pending(s->file, max_size); > - DPRINTF("pending size %lu max %lu\n", pending_size, max_size); > - if (pending_size && pending_size >= max_size) { > - qemu_savevm_state_iterate(s->file); > - } else { > - int ret; > - > - DPRINTF("done iterating\n"); > - qemu_mutex_lock_iothread(); > - start_time = qemu_get_clock_ms(rt_clock); > - qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); > - old_vm_running = runstate_is_running(); > - > - ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); > - if (ret >= 0) { > - qemu_file_set_rate_limit(s->file, INT_MAX); > - qemu_savevm_state_complete(s->file); > - } > - qemu_mutex_unlock_iothread(); > + if (s->enabled_capabilities[MIGRATION_CAPABILITY_LOCALHOST]) { > + DPRINTF("local migration start\n"); > > - if (ret < 0) { > - migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR); > - break; > - } > + ret = qemu_save_device_state(s->file); > + if (ret < 0) { > + migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR); > + break; > + } > > - if (!qemu_file_get_error(s->file)) { > - migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_COMPLETED); > - break; > + if (!qemu_file_get_error(s->file)) { > + DPRINTF("local migration completed\n"); > + migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_COMPLETED); > + break; > + } > + } else { > + if (!qemu_file_rate_limit(s->file)) { > + DPRINTF("iterate\n"); > + pending_size = qemu_savevm_state_pending(s->file, max_size); > + DPRINTF("pending size %lu max %lu\n", pending_size, max_size); > + if (pending_size && pending_size >= max_size) { > + qemu_savevm_state_iterate(s->file); > + } else { > + int ret; > + > + DPRINTF("done iterating\n"); > + qemu_mutex_lock_iothread(); > + start_time = qemu_get_clock_ms(rt_clock); > + qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); > + old_vm_running = runstate_is_running(); > + > + ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); > + if (ret >= 0) { > + qemu_file_set_rate_limit(s->file, INT_MAX); > + qemu_savevm_state_complete(s->file); > + } > + qemu_mutex_unlock_iothread(); > + > + if (ret < 0) { > + migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR); > + break; > + } > + > + if (!qemu_file_get_error(s->file)) { > + migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_COMPLETED); > + break; > + } > } > } > } >
diff --git a/migration.c b/migration.c index 2f85358..2471664 100644 --- a/migration.c +++ b/migration.c @@ -565,37 +565,54 @@ static void *migration_thread(void *opaque) while (s->state == MIG_STATE_ACTIVE) { int64_t current_time; uint64_t pending_size; + int ret; - if (!qemu_file_rate_limit(s->file)) { - DPRINTF("iterate\n"); - pending_size = qemu_savevm_state_pending(s->file, max_size); - DPRINTF("pending size %lu max %lu\n", pending_size, max_size); - if (pending_size && pending_size >= max_size) { - qemu_savevm_state_iterate(s->file); - } else { - int ret; - - DPRINTF("done iterating\n"); - qemu_mutex_lock_iothread(); - start_time = qemu_get_clock_ms(rt_clock); - qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); - old_vm_running = runstate_is_running(); - - ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); - if (ret >= 0) { - qemu_file_set_rate_limit(s->file, INT_MAX); - qemu_savevm_state_complete(s->file); - } - qemu_mutex_unlock_iothread(); + if (s->enabled_capabilities[MIGRATION_CAPABILITY_LOCALHOST]) { + DPRINTF("local migration start\n"); - if (ret < 0) { - migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR); - break; - } + ret = qemu_save_device_state(s->file); + if (ret < 0) { + migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR); + break; + } - if (!qemu_file_get_error(s->file)) { - migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_COMPLETED); - break; + if (!qemu_file_get_error(s->file)) { + DPRINTF("local migration completed\n"); + migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_COMPLETED); + break; + } + } else { + if (!qemu_file_rate_limit(s->file)) { + DPRINTF("iterate\n"); + pending_size = qemu_savevm_state_pending(s->file, max_size); + DPRINTF("pending size %lu max %lu\n", pending_size, max_size); + if (pending_size && pending_size >= max_size) { + qemu_savevm_state_iterate(s->file); + } else { + int ret; + + DPRINTF("done iterating\n"); + qemu_mutex_lock_iothread(); + start_time = qemu_get_clock_ms(rt_clock); + qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); + old_vm_running = runstate_is_running(); + + ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); + if (ret >= 0) { + qemu_file_set_rate_limit(s->file, INT_MAX); + qemu_savevm_state_complete(s->file); + } + qemu_mutex_unlock_iothread(); + + if (ret < 0) { + migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR); + break; + } + + if (!qemu_file_get_error(s->file)) { + migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_COMPLETED); + break; + } } } }
Integrate localhost migration thread to migration_thread. As the mechanism of local migration is different than the current migration, and it does not need to do iterate. So the whole thread can split into two stages, it will send all the ram pages in qemu_savevm_state_begin stage, and send the device states in qemu_save_device_state stage. Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com> --- migration.c | 73 ++++++++++++++++++++++++++++++++++++---------------------- 1 files changed, 45 insertions(+), 28 deletions(-)