From 2db82850ca8713d03a0a4614f78e84c4e9666326 Mon Sep 17 00:00:00 2001 From: kettenis Date: Tue, 31 Aug 2021 15:11:54 +0000 Subject: [PATCH] Use the TSC delay(9) backend earlier on machines where we can. Also use the TSC for delays even if there is a skew between the TSCs of the cores as this doesn't matter for delay(9). Gets rid of te unreasonable clock speed reports on Intel Tiget Lake CPUs where the i8254 behaves in weird ways. ok patrick@, deraadt@, mlarkin@ --- sys/arch/amd64/amd64/identcpu.c | 5 ++++- sys/arch/amd64/amd64/tsc.c | 23 +++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/sys/arch/amd64/amd64/identcpu.c b/sys/arch/amd64/amd64/identcpu.c index 0ed9962bbfd..b74955a6a61 100644 --- a/sys/arch/amd64/amd64/identcpu.c +++ b/sys/arch/amd64/amd64/identcpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: identcpu.c,v 1.118 2020/12/31 06:22:33 jsg Exp $ */ +/* $OpenBSD: identcpu.c,v 1.119 2021/08/31 15:11:54 kettenis Exp $ */ /* $NetBSD: identcpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */ /* @@ -48,6 +48,7 @@ void replacesmap(void); void replacemeltdown(void); uint64_t cpu_freq(struct cpu_info *); +void tsc_identify(struct cpu_info *); void tsc_timecounter_init(struct cpu_info *, uint64_t); #if NVMM > 0 void cpu_check_vmm_cap(struct cpu_info *); @@ -545,6 +546,8 @@ identifycpu(struct cpu_info *ci) /* Check if it's an invariant TSC */ if (cpu_apmi_edx & CPUIDEDX_ITSC) ci->ci_flags |= CPUF_INVAR_TSC; + + tsc_identify(ci); } freq = cpu_freq(ci); diff --git a/sys/arch/amd64/amd64/tsc.c b/sys/arch/amd64/amd64/tsc.c index c9b5e555227..32736b938aa 100644 --- a/sys/arch/amd64/amd64/tsc.c +++ b/sys/arch/amd64/amd64/tsc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tsc.c,v 1.23 2021/02/23 04:44:30 cheloha Exp $ */ +/* $OpenBSD: tsc.c,v 1.24 2021/08/31 15:11:54 kettenis Exp $ */ /* * Copyright (c) 2008 The NetBSD Foundation, Inc. * Copyright (c) 2016,2017 Reyk Floeter @@ -104,6 +104,21 @@ tsc_freq_cpuid(struct cpu_info *ci) return (0); } +void +tsc_identify(struct cpu_info *ci) +{ + if (!(ci->ci_flags & CPUF_PRIMARY) || + !(ci->ci_flags & CPUF_CONST_TSC) || + !(ci->ci_flags & CPUF_INVAR_TSC)) + return; + + tsc_is_invariant = 1; + + tsc_frequency = tsc_freq_cpuid(ci); + if (tsc_frequency > 0) + delay_func = tsc_delay; +} + static inline int get_tsc_and_timecount(struct timecounter *tc, uint64_t *tsc, uint64_t *count) { @@ -242,9 +257,6 @@ tsc_timecounter_init(struct cpu_info *ci, uint64_t cpufreq) !(ci->ci_flags & CPUF_INVAR_TSC)) return; - tsc_frequency = tsc_freq_cpuid(ci); - tsc_is_invariant = 1; - /* Newer CPUs don't require recalibration */ if (tsc_frequency > 0) { tsc_timecounter.tc_frequency = tsc_frequency; @@ -262,8 +274,7 @@ tsc_timecounter_init(struct cpu_info *ci, uint64_t cpufreq) tsc_timecounter.tc_quality = -1000; tsc_timecounter.tc_user = 0; tsc_is_invariant = 0; - } else - delay_func = tsc_delay; + } tc_init(&tsc_timecounter); } -- 2.20.1