From nobody Wed Dec 31 18:39:58 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 772E7C4332F for ; Mon, 30 Oct 2023 16:01:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233775AbjJ3QBH (ORCPT ); Mon, 30 Oct 2023 12:01:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58218 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233773AbjJ3QBC (ORCPT ); Mon, 30 Oct 2023 12:01:02 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B96CFEA for ; Mon, 30 Oct 2023 09:00:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Type:MIME-Version:Message-ID: Subject:Cc:To:From:Date:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description:In-Reply-To:References; bh=0+qFdwwFeIeTDlmcKhFsT4JEWXz4TvtGEXLhaLsK2tQ=; b=O8+03RLdBjmceNy3pKcecsMxdh nuBamGXiNJfYrUAT2sPZf1r4gfQo70C3zvjVgfy7HEOtnxYWBu3J9K9s6MR6601fFPXHxgt5MBmcC C/GobWvxsjRzx1Kbuh4YAV98Bq6FTYHEwmBDC9XSRPvP7NInllKkt8O53ctaHZ4gWIISe7cU82EJO GLIqPqd2xzwMSEPQQ4ka9KUVj9OK7ZtMsNKHA20ljGbza0N1cqBgEchyE5ESEldhuyIxyhZlnbLl4 VtWayoihUV9Vq+L5oGsZM+O1mRIEKG8abfegKkHx/X4X2lt02Z8+1x5khWvhot/Ddst1SLKDL6DkA yqkJs7hQ==; Received: from j130084.upc-j.chello.nl ([24.132.130.84] helo=noisy.programming.kicks-ass.net) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1qxUh8-004zQE-Ow; Mon, 30 Oct 2023 16:00:51 +0000 Received: by noisy.programming.kicks-ass.net (Postfix, from userid 1000) id 435AB300478; Mon, 30 Oct 2023 17:00:50 +0100 (CET) Date: Mon, 30 Oct 2023 17:00:50 +0100 From: Peter Zijlstra To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Thomas Gleixner , Arjan van de Ven , feng.tang@intel.com Subject: [PATCH] x86/tsc: Have tsc=recalibrate override things Message-ID: <20231030160050.GA15024@noisy.programming.kicks-ass.net> MIME-Version: 1.0 Content-Disposition: inline Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Hi, My brand-spanking new SPR supermicro workstation was reporting NTP failures: Oct 30 13:00:26 spr ntpd[3517]: CLOCK: kernel reports TIME_ERROR: 0x41: Clo= ck Unsynchronized Oct 30 13:00:58 spr ntpd[3517]: CLOCK: time stepped by 32.316775 Oct 30 13:00:58 spr ntpd[3517]: CLOCK: frequency error 41699 PPM exceeds to= lerance 500 PPM CPUID provides: Time Stamp Counter/Core Crystal Clock Information (0x15): TSC/clock ratio =3D 200/2 nominal core crystal clock =3D 25000000 Hz Processor Frequency Information (0x16): Core Base Frequency (MHz) =3D 0x9c4 (2500) Core Maximum Frequency (MHz) =3D 0x12c0 (4800) Bus (Reference) Frequency (MHz) =3D 0x64 (100) and the kernel believes this. Since commit a7ec817d5542 ("x86/tsc: Add option to force frequency recalibration with HW timer") there is the tsc=3Drecalibrate option, which forces the recalibrate. This duely reports: Oct 30 12:42:39 spr kernel: tsc: Warning: TSC freq calibrated by CPUID/MSR = differs from what is calibrated by HW timer, please check with vendor!! Oct 30 12:42:39 spr kernel: tsc: Previous calibrated TSC freq: 2500= .000 MHz Oct 30 12:42:39 spr kernel: tsc: TSC freq recalibrated by [HPET]: 2= 399.967 MHz but then continues running at 2500, offering no solace and keeping NTP upset -- drifting ~30 seconds for every 15 minutes. Have tsc=3Drecalibrate override the CPUID provided numbers. This makes the machine usable and keeps NTP 'happy': Oct 30 16:48:44 spr ntpd[2200]: CLOCK: time stepped by -0.768679 Signed-off-by: Peter Zijlstra (Intel) --- arch/x86/kernel/tsc.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 15f97c0abc9d..ebca304ecea0 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -1430,14 +1430,13 @@ static void tsc_refine_calibration_work(struct work= _struct *work) hpet ? "HPET" : "PM_TIMER", (unsigned long)freq / 1000, (unsigned long)freq % 1000); + } else { =20 - return; + /* Make sure we're within 1% */ + if (abs(tsc_khz - freq) > tsc_khz/100) + goto out; } =20 - /* Make sure we're within 1% */ - if (abs(tsc_khz - freq) > tsc_khz/100) - goto out; - tsc_khz =3D freq; pr_info("Refined TSC clocksource calibration: %lu.%03lu MHz\n", (unsigned long)tsc_khz / 1000, @@ -1475,18 +1474,19 @@ static int __init init_tsc_clocksource(void) if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3)) clocksource_tsc.flags |=3D CLOCK_SOURCE_SUSPEND_NONSTOP; =20 - /* - * When TSC frequency is known (retrieved via MSR or CPUID), we skip - * the refined calibration and directly register it as a clocksource. - */ if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) { if (boot_cpu_has(X86_FEATURE_ART)) art_related_clocksource =3D &clocksource_tsc; - clocksource_register_khz(&clocksource_tsc, tsc_khz); - clocksource_unregister(&clocksource_tsc_early); =20 - if (!tsc_force_recalibrate) - return 0; + /* + * When TSC frequency is known (retrieved via MSR or CPUID), we + * skip the refined calibration and directly register it as a + * clocksource. + */ + if (!tsc_force_recalibrate) { + clocksource_register_khz(&clocksource_tsc, tsc_khz); + clocksource_unregister(&clocksource_tsc_early); + } } =20 schedule_delayed_work(&tsc_irqwork, 0);