git: 0e494a9e3fd8 - main - x86: Skip late calibration if our reference timer has low quality

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 03 Jan 2022 18:01:20 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=0e494a9e3fd86ef54899dcbe0268866629096c1e

commit 0e494a9e3fd86ef54899dcbe0268866629096c1e
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-01-03 15:14:41 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-01-03 18:00:50 +0000

    x86: Skip late calibration if our reference timer has low quality
    
    Some AMD Geode-based systems end up using the 8254 PIT to calibrate the
    TSC during late calibration, which doesn't work because that
    timecounter's mask (65535) is much smaller than its frequency (1193182).
    Moreover, early calibration is done against the 8254 timer anyway.
    
    Work around the problem by simply using early calibration results if no
    high-quality timecounters exist.
    
    PR:             260868
    Fixes:          22875f88799e ("x86: Implement deferred TSC calibration")
    Reported and tested by: mike@sentex.net, Stefan Hegnauer <stefan.hegnauer@gmx.ch>
    Reviewed by:    imp, kib
    MFC after:      3 days
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D33730
---
 sys/x86/x86/tsc.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/sys/x86/x86/tsc.c b/sys/x86/x86/tsc.c
index 29da37ca6874..3b2e044573f1 100644
--- a/sys/x86/x86/tsc.c
+++ b/sys/x86/x86/tsc.c
@@ -714,7 +714,14 @@ tsc_calibrate(void)
 	if (tsc_early_calib_exact)
 		goto calibrated;
 
+	/*
+	 * Avoid using a low-quality timecounter to re-calibrate.  In
+	 * particular, old 32-bit platforms might only have the 8254 timer to
+	 * calibrate against.
+	 */
 	tc = atomic_load_ptr(&timecounter);
+	if (tc->tc_quality <= 0)
+		goto calibrated;
 
 	flags = intr_disable();
 	cpu = curcpu;