|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v4 1/4] x86/APIC: calibrate against platform timer when possible
On Thu, Mar 31, 2022 at 11:29:44AM +0200, Jan Beulich wrote:
> Use the original calibration against PIT only when the platform timer
> is PIT. This implicitly excludes the "xen_guest" case from using the PIT
> logic (init_pit() fails there, and as of 5e73b2594c54 ["x86/time: minor
> adjustments to init_pit()"] using_pit also isn't being set too early
> anymore), so the respective hack there can be dropped at the same time.
> This also reduces calibration time from 100ms to 50ms, albeit this step
> is being skipped as of 0731a56c7c72 ("x86/APIC: no need for timer
> calibration when using TDT") anyway.
>
> While re-indenting the PIT logic in calibrate_APIC_clock(), besides
> adjusting style also switch around the 2nd TSC/TMCCT read pair, to match
> the order of the 1st one, yielding more consistent deltas.
>
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
> ---
> Open-coding apic_read() in apic_tmcct_read() isn't overly nice, but I
> wanted to avoid x2apic_enabled being evaluated twice in close
> succession. And I also wouldn't want to have the barrier there even for
> the (uncached) MMIO read.
>
> Unlike the CPU frequencies enumerated in CPUID leaf 0x16 (which aren't
> precise), using CPUID[0x15].ECX - if populated - may be an option to
> skip calibration altogether. Aiui the value there is precise, but using
> the systems I have easy access to I cannot verify this: In the sample
> of three I have, none have ECX populated.
>
> I wonder whether the secondary CPU freq measurement (used for display
> purposes only) wouldn't better be dropped at this occasion.
I don't have a strong opinion re those informative messages.
> --- a/xen/arch/x86/include/asm/apic.h
> +++ b/xen/arch/x86/include/asm/apic.h
> @@ -192,6 +192,9 @@ extern void record_boot_APIC_mode(void);
> extern enum apic_mode current_local_apic_mode(void);
> extern void check_for_unexpected_msi(unsigned int vector);
>
> +uint64_t calibrate_apic_timer(void);
> +uint32_t apic_tmcct_read(void);
> +
> extern void check_nmi_watchdog(void);
>
> extern unsigned int nmi_watchdog;
> --- a/xen/arch/x86/time.c
> +++ b/xen/arch/x86/time.c
> @@ -26,6 +26,7 @@
> #include <xen/symbols.h>
> #include <xen/keyhandler.h>
> #include <xen/guest_access.h>
> +#include <asm/apic.h>
> #include <asm/io.h>
> #include <asm/iocap.h>
> #include <asm/msr.h>
> @@ -1018,6 +1019,67 @@ static u64 __init init_platform_timer(vo
> return rc;
> }
>
> +static uint64_t __init read_pt_and_tmcct(uint32_t *tmcct)
> +{
> + uint32_t tmcct_prev = *tmcct = apic_tmcct_read(), tmcct_min = ~0;
> + uint64_t best = best;
> + unsigned int i;
> +
> + for ( i = 0; ; ++i )
> + {
> + uint64_t pt = plt_src.read_counter();
> + uint32_t tmcct_cur = apic_tmcct_read();
> + uint32_t tmcct_delta = tmcct_prev - tmcct_cur;
> +
> + if ( tmcct_delta < tmcct_min )
> + {
> + tmcct_min = tmcct_delta;
> + *tmcct = tmcct_cur;
> + best = pt;
> + }
> + else if ( i > 2 )
> + break;
> +
> + tmcct_prev = tmcct_cur;
> + }
> +
> + return best;
> +}
> +
> +uint64_t __init calibrate_apic_timer(void)
> +{
> + uint32_t start, end;
> + uint64_t count = read_pt_and_tmcct(&start), elapsed;
> + uint64_t target = CALIBRATE_VALUE(plt_src.frequency), actual;
> + uint64_t mask = (uint64_t)~0 >> (64 - plt_src.counter_bits);
> +
> + /*
> + * PIT cannot be used here as it requires the timer interrupt to maintain
> + * its 32-bit software counter, yet here we run with IRQs disabled.
> + */
> + if ( using_pit )
> + return 0;
> +
> + while ( ((plt_src.read_counter() - count) & mask) < target )
> + continue;
> +
> + actual = read_pt_and_tmcct(&end) - count;
Don't you need to apply the pt mask here?
> + elapsed = start - end;
> +
> + if ( likely(actual > target) )
> + {
> + /* See the comment in calibrate_tsc(). */
I would maybe add that the counters used here might have > 32 bits,
and hence we need to trim the values for muldiv64 to scale properly.
Thanks, Roger.
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |