The commit 317b0a6d8 fixed an issue which caused by the outdated env->tsc value, but the fix lead to cpu_synchronize_all_states called twice during live migration. The cpu_synchronize_all_states takes about 300us, which is a bit expensive. This patch tries to fix the issue in another way, and there is only one cpu_synchronize_all_states call during live migration.
Signed-off-by: Liang Li <liang.z...@intel.com> --- cpus.c | 8 ++++++++ hw/i386/kvm/clock.c | 17 ----------------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/cpus.c b/cpus.c index c1e74d9..cd5abef 100644 --- a/cpus.c +++ b/cpus.c @@ -634,6 +634,14 @@ static int do_vm_stop(RunState state) pause_all_vcpus(); runstate_set(state); vm_state_notify(0, state); + switch (state) { + case RUN_STATE_PAUSED: + case RUN_STATE_SUSPENDED: + cpu_synchronize_all_states(); + break; + default: + break; + } qapi_event_send_stop(&error_abort); } diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index efdf165..a9db073 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -17,7 +17,6 @@ #include "qemu/host-utils.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" -#include "sysemu/cpus.h" #include "hw/sysbus.h" #include "hw/kvm/clock.h" @@ -125,22 +124,6 @@ static void kvmclock_vm_state_change(void *opaque, int running, return; } - cpu_synchronize_all_states(); - /* In theory, the cpu_synchronize_all_states() call above wouldn't - * affect the rest of the code, as the VCPU state inside CPUState - * is supposed to always match the VCPU state on the kernel side. - * - * In practice, calling cpu_synchronize_state() too soon will load the - * kernel-side APIC state into X86CPU.apic_state too early, APIC state - * won't be reloaded later because CPUState.vcpu_dirty==true, and - * outdated APIC state may be migrated to another host. - * - * The real fix would be to make sure outdated APIC state is read - * from the kernel again when necessary. While this is not fixed, we - * need the cpu_clean_all_dirty() call below. - */ - cpu_clean_all_dirty(); - ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data); if (ret < 0) { fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret)); -- 1.9.1