]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: x86: Rate-limit global clock updates on vCPU load
authorLei Chen <lei.chen@smartx.com>
Thu, 9 Apr 2026 14:22:26 +0000 (22:22 +0800)
committerSean Christopherson <seanjc@google.com>
Wed, 13 May 2026 16:57:44 +0000 (09:57 -0700)
commit 446fcce2a52b ("Revert "x86: kvm: rate-limit global clock updates"")
dropped the rate limiting for KVM_REQ_GLOBAL_CLOCK_UPDATE.

As a result, kvm_arch_vcpu_load() can queue global clock update requests
every time a vCPU is scheduled when the master clock is disabled or when
the vCPU is loaded for the first time.

Restore the throttling with a per-VM ratelimit state and gate
KVM_REQ_GLOBAL_CLOCK_UPDATE through __ratelimit(), so frequent vCPU
scheduling does not generate a steady stream of redundant clock update
requests.

Fixes: 446fcce2a52b ("Revert "x86: kvm: rate-limit global clock updates"")
Signed-off-by: Lei Chen <lei.chen@smartx.com>
Reported-by: Jaroslav Pulchart <jaroslav.pulchart@gooddata.com>
Closes: https://lore.kernel.org/all/CAK8fFZ5gY8_Mw2A=iZVFNVKQNrXQzVsn-HTd+Me9K6ZfmdgA+Q@mail.gmail.com/
Link: https://patch.msgid.link/20260409142226.2581-1-lei.chen@smartx.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/x86.c

index c470e40a00aa45a062348aaaab18fe7556eb1733..f14009f25a3b6afd3aec7103515e6b06e2fa2725 100644 (file)
@@ -1504,6 +1504,7 @@ struct kvm_arch {
        bool use_master_clock;
        u64 master_kernel_ns;
        u64 master_cycle_now;
+       struct ratelimit_state kvmclock_update_rs;
 
 #ifdef CONFIG_KVM_HYPERV
        struct kvm_hv hyperv;
index 0a1b63c63d1a9cdf6c2f1748ebf8c1e5f28f8bb6..e01d6984ed04f175d877ad160378fbd4a1f09d3d 100644 (file)
@@ -5227,8 +5227,13 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
                 * On a host with synchronized TSC, there is no need to update
                 * kvmclock on vcpu->cpu migration
                 */
-               if (!vcpu->kvm->arch.use_master_clock || vcpu->cpu == -1)
-                       kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu);
+               if (!vcpu->kvm->arch.use_master_clock || vcpu->cpu == -1) {
+                       if (__ratelimit(&vcpu->kvm->arch.kvmclock_update_rs))
+                               kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu);
+                       else
+                               kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
+               }
+
                if (vcpu->cpu != cpu)
                        kvm_make_request(KVM_REQ_MIGRATE_TIMER, vcpu);
                vcpu->cpu = cpu;
@@ -13366,6 +13371,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
        raw_spin_lock_init(&kvm->arch.tsc_write_lock);
        mutex_init(&kvm->arch.apic_map_lock);
        seqcount_raw_spinlock_init(&kvm->arch.pvclock_sc, &kvm->arch.tsc_write_lock);
+       ratelimit_state_init(&kvm->arch.kvmclock_update_rs, HZ, 10);
+       ratelimit_set_flags(&kvm->arch.kvmclock_update_rs, RATELIMIT_MSG_ON_RELEASE);
        kvm->arch.kvmclock_offset = -get_kvmclock_base_ns();
 
        raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);