Re: [KVM Clock Synchronization 2/4] Keep TSC synchronized across host suspend

Previous thread: [KVM Clock Synchronization 1/4] Make cyc_to_nsec conversions more reliable by Zachary Amsden on Tuesday, December 28, 2010 - 10:38 pm. (1 message)

Next thread: [KVM Clock Synchronization 4/4] Add master clock for KVM clock by Zachary Amsden on Tuesday, December 28, 2010 - 10:38 pm. (3 messages)
From: Zachary Amsden
Date: Tuesday, December 28, 2010 - 10:38 pm

During a host suspend, TSC may go backwards, which KVM interprets
as an unstable TSC.  Technically, KVM should not be marking the
TSC unstable, which causes the TSC clocksource to go bad, but
should be adjusting the TSC offsets in such a case.

Signed-off-by: Zachary Amsden <zamsden@redhat.com>
---
 arch/x86/include/asm/kvm_host.h |    1 +
 arch/x86/kvm/x86.c              |   66 +++++++++++++++++++++++++++++++++++---
 2 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 9e6fe39..63a82b0 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -386,6 +386,7 @@ struct kvm_vcpu_arch {
 	u64 last_kernel_ns;
 	u64 last_tsc_nsec;
 	u64 last_tsc_write;
+	u64 tsc_offset_adjustment;
 	bool tsc_catchup;
 
 	bool nmi_pending;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b9118f4..b509c01 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2042,12 +2042,20 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	}
 
 	kvm_x86_ops->vcpu_load(vcpu, cpu);
+
+	/* Apply any externally detected TSC adjustments (due to suspend) */
+	if (unlikely(vcpu->arch.tsc_offset_adjustment)) {
+		kvm_x86_ops->adjust_tsc_offset(vcpu,
+			vcpu->arch.tsc_offset_adjustment);
+		vcpu->arch.tsc_offset_adjustment = 0;
+		kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
+	}
 	if (unlikely(vcpu->cpu != cpu) || check_tsc_unstable()) {
 		/* Make sure TSC doesn't go backwards */
 		s64 tsc_delta = !vcpu->arch.last_host_tsc ? 0 :
 				native_read_tsc() - vcpu->arch.last_host_tsc;
 		if (tsc_delta < 0)
-			mark_tsc_unstable("KVM discovered backwards TSC");
+			WARN_ON(!check_tsc_unstable());
 		if (check_tsc_unstable()) {
 			kvm_x86_ops->adjust_tsc_offset(vcpu, -tsc_delta);
 			vcpu->arch.tsc_catchup = 1;
@@ -5778,14 +5786,60 @@ int kvm_arch_hardware_enable(void *garbage)
 {
 	struct kvm *kvm;
 	struct kvm_vcpu *vcpu;
-	int i;
+	int i, ret;
+	u64 local_tsc;
+	u64 ...
From: Marcelo Tosatti
Date: Tuesday, January 4, 2011 - 8:36 am

Wouldnt it be simpler to use cyc2ns_offset (or something equivalent)? In
any case, you forgot to compare smp_processor_id.

--

Previous thread: [KVM Clock Synchronization 1/4] Make cyc_to_nsec conversions more reliable by Zachary Amsden on Tuesday, December 28, 2010 - 10:38 pm. (1 message)

Next thread: [KVM Clock Synchronization 4/4] Add master clock for KVM clock by Zachary Amsden on Tuesday, December 28, 2010 - 10:38 pm. (3 messages)