Received: by 2002:a05:6358:e9c4:b0:b2:91dc:71ab with SMTP id hc4csp4632922rwb; Mon, 8 Aug 2022 04:44:26 -0700 (PDT) X-Google-Smtp-Source: AA6agR7DpIaz3NAR1vPDMo7q8w5aZg/1ooDOgIrdom+AR06Wz8S6cjM3og90Fe34HSSezeVaXmZF X-Received: by 2002:a17:902:7247:b0:16f:8361:ba26 with SMTP id c7-20020a170902724700b0016f8361ba26mr17973137pll.83.1659959066619; Mon, 08 Aug 2022 04:44:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659959066; cv=none; d=google.com; s=arc-20160816; b=YSkDPe4hyXCDGoxRIa7lT/feDvdAKhsa2/jFHZef9Z+XWz+BVbh2sg3BRHZeaEagLM aLkbOI8iCvlyg+RKBs3V910ikKwd7oeff1JV3Gdg7t4NghJXFjCoSk9LSW1mavqOTJse xC1OA1S/AuRNrT5zNCg7PoPg1n6E8auWkfGVvBnUj/Jd5JwQlqgmFs67ydlKnxw8SaYz AegGsF6ogYO9Xoh48B4bx9yZtt5JiyES1iO9nBYqbXpxQl0uoS44+bbKgLY8UNTV9GfK Z0j9io6tmv779J/coIuJPhO78Yc7MBD1GJAG1uvP45QBBmBiKLniwzw0s1snNoFyE3n0 yVkg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=1Zzce1F5iUjHe9wnkMen9Xw820p2wnL2nIyEab1zJ/I=; b=wMxL6jua1tZWAaj+sCdbHs050uSpNoOA718YoALGmnCKN2Oyf8PLu/o0SICVOAUXI5 hhfSKAK6KlZYEOeSpOepvdknuZRRo1fbwkd0jbeZiY/vu9zHEhKDneAaHvc5s1D5Z/iw 2ZHjlgGn+cl/hqBpVuUIqYPhLNDQIn1NxsLq5QNYtdLyiNe1biKzUqlnx6Qz57DefOmB efIP8ztIcCIrik0HQPZpDDQcP32SOG7gxugWSaO8ud+QJVjiu/ASSljGhEc2V7csLiDC Jhb0LdnSWDpxLWRHnHqhYVZazW8TsbgCCs/TsdceuNoALRVAe/Dm+IQVGBjtqr1F3as/ 8S7Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b=fYNy0f8F; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y73-20020a638a4c000000b0041cf945a2efsi10468093pgd.333.2022.08.08.04.44.11; Mon, 08 Aug 2022 04:44:26 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b=fYNy0f8F; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242910AbiHHLk1 (ORCPT + 99 others); Mon, 8 Aug 2022 07:40:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44746 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242699AbiHHLkW (ORCPT ); Mon, 8 Aug 2022 07:40:22 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [46.235.227.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21DD32BDA; Mon, 8 Aug 2022 04:40:21 -0700 (PDT) Received: from localhost.localdomain (unknown [39.46.64.186]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: usama.anjum) by madras.collabora.co.uk (Postfix) with ESMTPSA id 97B426601C27; Mon, 8 Aug 2022 12:40:16 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1659958819; bh=NABXr45P299DN/2txxUii3Yn/eCVqoWtHDq/GPwndk8=; h=From:To:Cc:Subject:Date:From; b=fYNy0f8FvAj4A8hmcHbVxS54ZMzVune13gUjXYchzLFDeM8J1DXiX0lDjZRk+Mrmy IQhdd8/szZQuCC5liBCRMmfbLoe7BPmUeS09pzNgfrG6AKJCjL9yfVhRltH9jFjiPo zNe2bCa8SKNzq0tBbNQRQdKJLCYjgX8p579I/aIDGQ7Z65mbfk+oEcSdvvI2GH+wkz 7YfcT4TX+q0ZCOwV6THhCc6kBfeA9frLz0P5BWfGCsCtIphk04eAmkE655EwazKCfA WnvyqcZ36bYDKRWjuy2wxaAlymAss+apyuseoJky4x3WpbkUlJnmhoqXUtFHt4jD5G juicVl5T6jUhQ== From: Muhammad Usama Anjum To: Jonathan Corbet , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org (maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)), "H. Peter Anvin" , linux-doc@vger.kernel.org (open list:DOCUMENTATION), linux-kernel@vger.kernel.org (open list) Cc: Steven Noonan , usama.anjum@collabora.com, kernel@collabora.com Subject: [PATCH 1/3] x86/tsc: implement tsc=directsync for systems without IA32_TSC_ADJUST Date: Mon, 8 Aug 2022 16:39:52 +0500 Message-Id: <20220808113954.345579-1-usama.anjum@collabora.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Steven Noonan AMD processors don't implement any mechanism like Intel's IA32_TSC_ADJUST MSR to sync the TSC. Instead of just relying on the BIOS, TSC can be synced by calculating the difference and directly writing it to the TSC MSR. Add directsync flag to turn on the TSC sync when IA32_TSC_MSR isn't available. Attempt 1000 times or for 30 seconds before giving up. Signed-off-by: Steven Noonan Signed-off-by: Muhammad Usama Anjum --- .../admin-guide/kernel-parameters.txt | 4 +- arch/x86/include/asm/tsc.h | 1 + arch/x86/kernel/tsc.c | 3 ++ arch/x86/kernel/tsc_sync.c | 46 +++++++++++++++---- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index db5de5f0b9d3..f0e6ea580e68 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -6271,7 +6271,7 @@ If not specified, "default" is used. In this case, the RNG's choice is left to each individual trust source. - tsc= Disable clocksource stability checks for TSC. + tsc= Disable clocksource stability checks for TSC or sync the TSC. Format: [x86] reliable: mark tsc clocksource as reliable, this disables clocksource verification at runtime, as well @@ -6289,6 +6289,8 @@ in situations with strict latency requirements (where interruptions from clocksource watchdog are not acceptable). + [x86] directsync: attempt to sync the tsc via direct + writes if MSR_IA32_TSC_ADJUST isn't available tsc_early_khz= [X86] Skip early TSC calibration and use the given value instead. Useful when the early TSC frequency discovery diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index fbdc3d951494..dc70909119e8 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h @@ -42,6 +42,7 @@ extern unsigned long native_calibrate_tsc(void); extern unsigned long long native_sched_clock_from_tsc(u64 tsc); extern int tsc_clocksource_reliable; +extern int tsc_allow_direct_sync; #ifdef CONFIG_X86_TSC extern bool tsc_async_resets; #else diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index cafacb2e58cc..6345af65a549 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -47,6 +47,7 @@ static unsigned int __initdata tsc_early_khz; static DEFINE_STATIC_KEY_FALSE(__use_tsc); int tsc_clocksource_reliable; +int tsc_allow_direct_sync; static u32 art_to_tsc_numerator; static u32 art_to_tsc_denominator; @@ -303,6 +304,8 @@ static int __init tsc_setup(char *str) mark_tsc_unstable("boot parameter"); if (!strcmp(str, "nowatchdog")) no_tsc_watchdog = 1; + if (!strcmp(str, "directsync")) + tsc_allow_direct_sync = 1; return 1; } diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c index 9452dc9664b5..2a855991f982 100644 --- a/arch/x86/kernel/tsc_sync.c +++ b/arch/x86/kernel/tsc_sync.c @@ -340,6 +340,8 @@ static cycles_t check_tsc_warp(unsigned int timeout) */ static inline unsigned int loop_timeout(int cpu) { + if (!boot_cpu_has(X86_FEATURE_TSC_ADJUST)) + return 30; return (cpumask_weight(topology_core_cpumask(cpu)) > 1) ? 2 : 20; } @@ -360,13 +362,16 @@ void check_tsc_sync_source(int cpu) /* * Set the maximum number of test runs to - * 1 if the CPU does not provide the TSC_ADJUST MSR - * 3 if the MSR is available, so the target can try to adjust + * 3 if TSC_ADJUST MSR is available, so the target can try to adjust + * 1000 if TSC MSR can be written to compensate + * 1 if MSRs cannot be written */ - if (!boot_cpu_has(X86_FEATURE_TSC_ADJUST)) - atomic_set(&test_runs, 1); - else + if (boot_cpu_has(X86_FEATURE_TSC_ADJUST)) atomic_set(&test_runs, 3); + else if (tsc_allow_direct_sync) + atomic_set(&test_runs, 1000); + else + atomic_set(&test_runs, 1); retry: /* * Wait for the target to start or to skip the test: @@ -434,6 +439,21 @@ void check_tsc_sync_source(int cpu) goto retry; } +static inline cycles_t write_tsc_adjustment(cycles_t adjustment) +{ + cycles_t adjval, nextval; + + rdmsrl(MSR_IA32_TSC, adjval); + adjval += adjustment; + wrmsrl(MSR_IA32_TSC, adjval); + rdmsrl(MSR_IA32_TSC, nextval); + + /* + * Estimated clock cycle overhead for wrmsr + rdmsr + */ + return nextval - adjval; +} + /* * Freshly booted CPUs call into this: */ @@ -441,7 +461,7 @@ void check_tsc_sync_target(void) { struct tsc_adjust *cur = this_cpu_ptr(&tsc_adjust); unsigned int cpu = smp_processor_id(); - cycles_t cur_max_warp, gbl_max_warp; + cycles_t cur_max_warp, gbl_max_warp, est_overhead = 0; int cpus = 2; /* Also aborts if there is no TSC. */ @@ -521,12 +541,18 @@ void check_tsc_sync_target(void) * value is used. In the worst case the adjustment needs to go * through a 3rd run for fine tuning. */ - cur->adjusted += cur_max_warp; + if (boot_cpu_has(X86_FEATURE_TSC_ADJUST)) { + cur->adjusted += cur_max_warp; - pr_warn("TSC ADJUST compensate: CPU%u observed %lld warp. Adjust: %lld\n", - cpu, cur_max_warp, cur->adjusted); + pr_warn("TSC ADJUST compensate: CPU%u observed %lld warp. Adjust: %lld\n", + cpu, cur_max_warp, cur->adjusted); - wrmsrl(MSR_IA32_TSC_ADJUST, cur->adjusted); + wrmsrl(MSR_IA32_TSC_ADJUST, cur->adjusted); + } else { + pr_debug("TSC direct sync: CPU%u observed %lld warp. Overhead: %lld\n", + cpu, cur_max_warp, est_overhead); + est_overhead = write_tsc_adjustment(cur_max_warp + est_overhead); + } goto retry; } -- 2.30.2