[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v4 24/30] KVM: x86: Avoid gratuitous global clock updates



From: David Woodhouse <dwmw@xxxxxxxxxxxx>

Eliminate three sources of unnecessary KVM_REQ_GLOBAL_CLOCK_UPDATE:

1. kvm_write_system_time(): The global clock update was a workaround for
   ever-drifting clocks based on the host's CLOCK_MONOTONIC subject to
   NTP skew. On booting or resuming a guest, it just leads to running
   kvm_guest_time_update() twice for each vCPU for no good reason. Use
   KVM_REQ_CLOCK_UPDATE on the vCPU itself, and only when the clock is
   being enabled, not disabled.

2. kvm_arch_vcpu_load(): Use KVM_REQ_CLOCK_UPDATE instead of
   KVM_REQ_GLOBAL_CLOCK_UPDATE. There is no need to update all vCPUs'
   clocks when one vCPU is loaded.

3. kvm_gen_kvmclock_update(): Skip the periodic global update entirely
   when in master clock mode, since the clock is defined precisely by
   the guest TSC and doesn't drift.

Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
Reviewed-by: Paul Durrant <paul@xxxxxxx>
---
 arch/x86/kvm/x86.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0656d901fe79..7d9ec0638d28 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2457,13 +2457,13 @@ static void kvm_write_system_time(struct kvm_vcpu 
*vcpu, gpa_t system_time,
        }
 
        vcpu->arch.time = system_time;
-       kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu);
 
        /* we verify if the enable bit is set... */
-       if (system_time & 1)
+       if (system_time & 1) {
                kvm_gpc_activate(&vcpu->arch.pv_time, system_time & ~1ULL,
                                 sizeof(struct pvclock_vcpu_time_info));
-       else
+               kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
+       } else
                kvm_gpc_deactivate(&vcpu->arch.pv_time);
 
        return;
@@ -3638,6 +3638,10 @@ static void kvm_gen_kvmclock_update(struct kvm_vcpu *v)
        struct kvm_vcpu *vcpu;
        struct kvm *kvm = v->kvm;
 
+       /* In master clock mode, the clock doesn't need periodic updates. */
+       if (kvm->arch.use_master_clock)
+               return;
+
        kvm_for_each_vcpu(i, vcpu, kvm) {
                kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
                kvm_vcpu_kick(vcpu);
@@ -5339,7 +5343,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
                 * kvmclock on vcpu->cpu migration
                 */
                if (!vcpu->kvm->arch.use_master_clock || vcpu->cpu == -1)
-                       kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu);
+                       kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
                if (vcpu->cpu != cpu)
                        kvm_make_request(KVM_REQ_MIGRATE_TIMER, vcpu);
                vcpu->cpu = cpu;
-- 
2.51.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.