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

Re: [PATCH v4 16/30] KVM: x86: Restructure kvm_guest_time_update() for TSC upscaling


  • To: David Woodhouse <dwmw2@xxxxxxxxxxxxx>, kvm@xxxxxxxxxxxxxxx
  • From: Dongli Zhang <dongli.zhang@xxxxxxxxxx>
  • Date: Tue, 19 May 2026 00:38:00 -0700
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=wVMIqXlaDGVHOYRt4HeJrHuQKFcLBAC9G+SLJY6E7yg=; b=Ytrk2TM1NpGEg9nKSLTgLvmjKKi5j0xRrFtu8mvDlVvMRKV6qQuL7Wb4iASYzc+nuzXCAx91RJ40pk0uBGLivmOV745yEZKUI4tgqucoG/edXhepLK+8RvjU1ytgy+3+cN/qTckDowlSogf/0Ifa04XPW+psOB22pj6Z1ShohSF2B+9wVzghF9qZQ3y12GLVr4XNt736LuFUKbDm4tZYeQd0+Iy+iscisu2GsU3g+TlhlWDeTNgsEQMEs7uXywGgIcuWF0bv80Ejo8dlEYkG1HQzINLOgYrFiy7+FehWlHuBqof3gTs75bgZWYq3Y9Gu0t4u9YwCOdoB6UV8TjQL/g==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FVAif0Ut5FV05g2UFy3L1fiiBVgPQ0n4d6+6S70MRF4iWCtal2bjGWPKhmoJzY/4SvfQHccEucOGUMy1qXzKjY89tJgWGdeuuDCgvbMNZsFYY0gpMc3G6dyAudFgqJHOFxXa/Gyyh9laI9mw7sAYxNRpkCqPEXCjg/Om2xu+u6gl2jQRD5EDjarZudoAa0xk+ldoGQQaD/hV0O4BscMNCvLl2Nq0SXdMpwqYJl7MUjLHrjrBT4p/xW7FgLw/yFddXcCYt4XaFutvEdbUM8Ld0KppdiROvP7I4XbSQF0LDEZvoUNODmQr9JaPOuDVH+P396UFL/OttKwwNJIDknmSMQ==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=corp-2025-04-25 header.d=oracle.com header.i="@oracle.com" header.h="Cc:Content-Transfer-Encoding:Content-Type:Date:From:In-Reply-To:Message-ID:MIME-Version:References:Subject:To"; dkim=pass header.s=selector2-oracle-onmicrosoft-com header.d=oracle.onmicrosoft.com header.i="@oracle.onmicrosoft.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx>, Jonathan Corbet <corbet@xxxxxxx>, Shuah Khan <skhan@xxxxxxxxxxxxxxxxxxx>, Sean Christopherson <seanjc@xxxxxxxxxx>, Thomas Gleixner <tglx@xxxxxxxxxx>, Ingo Molnar <mingo@xxxxxxxxxx>, Borislav Petkov <bp@xxxxxxxxx>, Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx>, x86@xxxxxxxxxx, "H. Peter Anvin" <hpa@xxxxxxxxx>, Vitaly Kuznetsov <vkuznets@xxxxxxxxxx>, Juergen Gross <jgross@xxxxxxxx>, Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>, Paul Durrant <paul@xxxxxxx>, Jonathan Cameron <jic23@xxxxxxxxxx>, Sascha Bischoff <Sascha.Bischoff@xxxxxxx>, Marc Zyngier <maz@xxxxxxxxxx>, Joey Gouly <joey.gouly@xxxxxxx>, Jack Allister <jalliste@xxxxxxxxxx>, joe.jin@xxxxxxxxxx, linux-doc@xxxxxxxxxxxxxxx, linux-kernel@xxxxxxxxxxxxxxx, xen-devel@xxxxxxxxxxxxxxxxxxxx, linux-kselftest@xxxxxxxxxxxxxxx
  • Delivery-date: Tue, 19 May 2026 07:39:02 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

I have encountered this build error with this patch.

Perhaps it is because all usage of "flags" are removed.

$ make -j32 > /dev/null
arch/x86/kvm/x86.c: In function ‘kvm_guest_time_update’:
arch/x86/kvm/x86.c:3359:23: error: unused variable ‘flags’ 
[-Werror=unused-variable]
 3359 |         unsigned long flags;
      |                       ^~~~~
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:289: arch/x86/kvm/x86.o] Error 1
make[3]: *** [scripts/Makefile.build:548: arch/x86/kvm] Error 2
make[2]: *** [scripts/Makefile.build:548: arch/x86] Error 2
make[1]: *** [/home/opc/ext4/mainline-linux/Makefile:2143: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2

Thank you very much!

Dongli Zhang

On 2026-05-09 3:46 PM, David Woodhouse wrote:
> From: David Woodhouse <dwmw@xxxxxxxxxxxx>
> 
> Restructure kvm_guest_time_update() so that kernel_ns/host_tsc are
> always "now" when doing TSC catchup, then swap in the master clock
> reference values afterward for the hv_clock.
> 
> This makes the TSC upscaling code considerably simpler: the catchup
> adjustment is computed as the delta between what the guest TSC *should*
> be at "now" and what it actually is, rather than mixing "now" and
> "master clock reference" timestamps.
> 
> The seqcount loop now also contains the kvm_get_time_and_clockread()
> call (matching get_kvmclock's pattern), with the same WARN for
> unexpected failure.
> 
> Based on a suggestion by Sean Christopherson.
> 
> Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
> ---
>  arch/x86/kvm/x86.c | 67 ++++++++++++++++++++++++++++++++--------------
>  1 file changed, 47 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index e281c49561fa..8e4993ef4f6b 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -3363,39 +3363,51 @@ int kvm_guest_time_update(struct kvm_vcpu *v)
>       struct kvm_arch *ka = &v->kvm->arch;
>       s64 kernel_ns;
>       u64 tsc_timestamp, host_tsc;
> +     u64 master_host_tsc = 0;
> +     s64 master_kernel_ns = 0;
>       bool use_master_clock;
>  
> -     kernel_ns = 0;
> -     host_tsc = 0;
> -
>       /*
>        * If the host uses TSC clock, then passthrough TSC as stable
>        * to the guest.
>        */
>       do {
>               seq = read_seqcount_begin(&ka->pvclock_sc);
> +
>               use_master_clock = ka->use_master_clock;
> -             if (use_master_clock) {
> -                     host_tsc = ka->master_cycle_now;
> -                     kernel_ns = ka->master_kernel_ns;
> -             }
> +
> +             /*
> +              * The TSC read and the call to get_cpu_tsc_khz() must happen
> +              * on the same CPU.
> +              */
> +             get_cpu();
> +
> +             tgt_tsc_hz = (u64)get_cpu_tsc_khz() * 1000;
> +
> +             if (use_master_clock &&
> +                 !kvm_get_time_and_clockread(&kernel_ns, &host_tsc) &&
> +                 WARN_ON_ONCE(!read_seqcount_retry(&ka->pvclock_sc, seq)))
> +                     use_master_clock = false;
> +
> +             put_cpu();
> +
> +             if (!use_master_clock)
> +                     break;
> +
> +             master_host_tsc = ka->master_cycle_now;
> +             master_kernel_ns = ka->master_kernel_ns;
>       } while (read_seqcount_retry(&ka->pvclock_sc, seq));
>  
> -     /* Keep irq disabled to prevent changes to the clock */
> -     local_irq_save(flags);
> -     tgt_tsc_hz = (u64)get_cpu_tsc_khz() * 1000;
>       if (unlikely(tgt_tsc_hz == 0)) {
> -             local_irq_restore(flags);
>               kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
>               return 1;
>       }
> +
>       if (!use_master_clock) {
>               host_tsc = rdtsc();
>               kernel_ns = get_kvmclock_base_ns();
>       }
>  
> -     tsc_timestamp = kvm_read_l1_tsc(v, host_tsc);
> -
>       /*
>        * We may have to catch up the TSC to match elapsed wall clock
>        * time for two reasons, even if kvmclock is used.
> @@ -3404,17 +3416,32 @@ int kvm_guest_time_update(struct kvm_vcpu *v)
>        *      entry to avoid unknown leaps of TSC even when running
>        *      again on the same CPU.  This may cause apparent elapsed
>        *      time to disappear, and the guest to stand still or run
> -      *      very slowly.
> +      *      very slowly.
>        */
>       if (vcpu->tsc_catchup) {
> -             u64 tsc = compute_guest_tsc(v, kernel_ns);
> -             if (tsc > tsc_timestamp) {
> -                     adjust_tsc_offset_guest(v, tsc - tsc_timestamp);
> -                     tsc_timestamp = tsc;
> -             }
> +             s64 adjustment;
> +
> +             /*
> +              * Calculate the delta between what the guest TSC *should* be
> +              * and what it actually is according to kvm_read_l1_tsc().
> +              */
> +             adjustment = compute_guest_tsc(v, kernel_ns) -
> +                          kvm_read_l1_tsc(v, host_tsc);
> +             if (adjustment > 0)
> +                     adjust_tsc_offset_guest(v, adjustment);
>       }
>  
> -     local_irq_restore(flags);
> +     /*
> +      * Now that TSC upscaling is out of the way, the remaining calculations
> +      * are all relative to the reference time that's placed in hv_clock.
> +      * If the master clock is NOT in use, the reference time is "now".  If
> +      * master clock is in use, the reference time comes from there.
> +      */
> +     if (use_master_clock) {
> +             host_tsc = master_host_tsc;
> +             kernel_ns = master_kernel_ns;
> +     }
> +     tsc_timestamp = kvm_read_l1_tsc(v, host_tsc);
>  
>       /* With all the info we got, fill in the values */
>  




 


Rackspace

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