Use the TSC delay(9) backend earlier on machines where we can. Also use
authorkettenis <kettenis@openbsd.org>
Tue, 31 Aug 2021 15:11:54 +0000 (15:11 +0000)
committerkettenis <kettenis@openbsd.org>
Tue, 31 Aug 2021 15:11:54 +0000 (15:11 +0000)
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
sys/arch/amd64/amd64/tsc.c

index 0ed9962..b74955a 100644 (file)
@@ -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);
index c9b5e55..32736b9 100644 (file)
@@ -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 <reyk@openbsd.org>
@@ -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);
 }