Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp2212225imm; Thu, 19 Jul 2018 15:32:16 -0700 (PDT) X-Google-Smtp-Source: AAOMgpcvFM7Ms11qw9UFX/26KGP7mCyZn6pA3nAIFO9mcb7jli+q54vSuDwzuOt4HLzAHt2Hbl3F X-Received: by 2002:a65:5106:: with SMTP id f6-v6mr11448672pgq.72.1532039536227; Thu, 19 Jul 2018 15:32:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532039536; cv=none; d=google.com; s=arc-20160816; b=dt6bB4QHrByFl9ieBDXqfThQUOuT7fme9b1r7crfCoUvFqXCNTr+8y7F/2uxp1l48D 3O7jNNAi5E9zQOnvTIfdhhl0I7GiIcP3a7EmGjmp7KQ4XfLlIGjMHnSWsWN4HdsV3js7 BgNRIdSnB5pY0Ng3YI3qTptblqp2704XIoOSKJri7/kUn1I2XdA2jRMDNnW8mJt3tPDh 67d2wWlMBDzljJegKQt4IhyNK7/3RWlqA/45rETlDJOs0lx2krV9sEp9t71dQ08cFf+T +xDzsQI+7VV/0hQ4iuHiXk3CewwBtUdrRQxBXOzR91QQ/OUZT55yhmO1F4PlaJo3Ddw0 wLgg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-disposition :content-transfer-encoding:mime-version:robot-unsubscribe:robot-id :git-commit-id:subject:to:references:in-reply-to:reply-to:cc :message-id:from:date:arc-authentication-results; bh=1baun4BXrQ9PluUvbEMnNznbKUE7QevYcs3H9hrEViY=; b=Xdq8OeBiwQ6TeJSbBOoIml/rnkjMEK1Z6NTNVERbuawhTp01S94W6YiEaPm2dQEb7k +FmPuwnNsRc9zxAvxTNAKTRw8dgMoUHD2GjG4fiRwQWadYpIOGmAUIvIGKzQYk+r+kwQ bokH3f2b43osaEIT/UaHv/NRecUmsr+tuhTa3mGlXgkoWm1FnpKFZWMwl/1M2ty/twny EEvG0R5t5weqEK50Zirk7stfaUPzA/naKomUdC31ox1sSxKnkTH24dq0phoWqtubKgpF DXSEy5761YYvZVDglpRbPZnzF44+N3T5/3+G5qhrT7YF+tKPzdYoi0TPR51ga4EtwKP8 mDtA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a7-v6si236636plz.510.2018.07.19.15.32.01; Thu, 19 Jul 2018 15:32:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731282AbeGSXQd (ORCPT + 99 others); Thu, 19 Jul 2018 19:16:33 -0400 Received: from terminus.zytor.com ([198.137.202.136]:57239 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730315AbeGSXQd (ORCPT ); Thu, 19 Jul 2018 19:16:33 -0400 Received: from terminus.zytor.com (localhost [127.0.0.1]) by terminus.zytor.com (8.15.2/8.15.2) with ESMTPS id w6JMVHrT2439532 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 19 Jul 2018 15:31:17 -0700 Received: (from tipbot@localhost) by terminus.zytor.com (8.15.2/8.15.2/Submit) id w6JMVHlx2439529; Thu, 19 Jul 2018 15:31:17 -0700 Date: Thu, 19 Jul 2018 15:31:17 -0700 X-Authentication-Warning: terminus.zytor.com: tipbot set sender to tipbot@zytor.com using -f From: tip-bot for Pavel Tatashin Message-ID: Cc: pasha.tatashin@oracle.com, linux-kernel@vger.kernel.org, tglx@linutronix.de, hpa@zytor.com, mingo@kernel.org Reply-To: pasha.tatashin@oracle.com, mingo@kernel.org, hpa@zytor.com, tglx@linutronix.de, linux-kernel@vger.kernel.org In-Reply-To: <20180719205545.16512-20-pasha.tatashin@oracle.com> References: <20180719205545.16512-20-pasha.tatashin@oracle.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:x86/timers] x86/tsc: Calibrate tsc only once Git-Commit-ID: cf7a63ef4e0203f6f33284c69e8188d91422de83 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, DATE_IN_FUTURE_96_Q autolearn=ham autolearn_force=no version=3.4.1 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on terminus.zytor.com Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: cf7a63ef4e0203f6f33284c69e8188d91422de83 Gitweb: https://git.kernel.org/tip/cf7a63ef4e0203f6f33284c69e8188d91422de83 Author: Pavel Tatashin AuthorDate: Thu, 19 Jul 2018 16:55:38 -0400 Committer: Thomas Gleixner CommitDate: Fri, 20 Jul 2018 00:02:42 +0200 x86/tsc: Calibrate tsc only once During boot tsc is calibrated twice: once in tsc_early_delay_calibrate(), and the second time in tsc_init(). Rename tsc_early_delay_calibrate() to tsc_early_init(), and rework it so the calibration is done only early, and make tsc_init() to use the values already determined in tsc_early_init(). Sometimes it is not possible to determine tsc early, as the subsystem that is required is not yet initialized, in such case try again later in tsc_init(). Suggested-by: Thomas Gleixner Signed-off-by: Pavel Tatashin Signed-off-by: Thomas Gleixner Cc: steven.sistare@oracle.com Cc: daniel.m.jordan@oracle.com Cc: linux@armlinux.org.uk Cc: schwidefsky@de.ibm.com Cc: heiko.carstens@de.ibm.com Cc: john.stultz@linaro.org Cc: sboyd@codeaurora.org Cc: hpa@zytor.com Cc: douly.fnst@cn.fujitsu.com Cc: peterz@infradead.org Cc: prarit@redhat.com Cc: feng.tang@intel.com Cc: pmladek@suse.com Cc: gnomes@lxorguk.ukuu.org.uk Cc: linux-s390@vger.kernel.org Cc: boris.ostrovsky@oracle.com Cc: jgross@suse.com Cc: pbonzini@redhat.com Link: https://lkml.kernel.org/r/20180719205545.16512-20-pasha.tatashin@oracle.com --- arch/x86/include/asm/tsc.h | 2 +- arch/x86/kernel/setup.c | 2 +- arch/x86/kernel/tsc.c | 87 +++++++++++++++++++++++++--------------------- 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index 2701d221583a..c4368ff73652 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h @@ -33,7 +33,7 @@ static inline cycles_t get_cycles(void) extern struct system_counterval_t convert_art_to_tsc(u64 art); extern struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns); -extern void tsc_early_delay_calibrate(void); +extern void tsc_early_init(void); extern void tsc_init(void); extern void mark_tsc_unstable(char *reason); extern int unsynchronized_tsc(void); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 7490de925a81..5d32c55aeb8b 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1014,6 +1014,7 @@ void __init setup_arch(char **cmdline_p) */ init_hypervisor_platform(); + tsc_early_init(); x86_init.resources.probe_roms(); /* after parse_early_param, so could debug it */ @@ -1199,7 +1200,6 @@ void __init setup_arch(char **cmdline_p) memblock_find_dma_reserve(); - tsc_early_delay_calibrate(); if (!early_xdbc_setup_hardware()) early_xdbc_register_console(); diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 186395041725..4cab2236169e 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -33,6 +33,8 @@ EXPORT_SYMBOL(cpu_khz); unsigned int __read_mostly tsc_khz; EXPORT_SYMBOL(tsc_khz); +#define KHZ 1000 + /* * TSC can be unstable due to cpufreq or due to unsynced TSCs */ @@ -1335,34 +1337,10 @@ unreg: */ device_initcall(init_tsc_clocksource); -void __init tsc_early_delay_calibrate(void) -{ - unsigned long lpj; - - if (!boot_cpu_has(X86_FEATURE_TSC)) - return; - - cpu_khz = x86_platform.calibrate_cpu(); - tsc_khz = x86_platform.calibrate_tsc(); - - tsc_khz = tsc_khz ? : cpu_khz; - if (!tsc_khz) - return; - - lpj = tsc_khz * 1000; - do_div(lpj, HZ); - loops_per_jiffy = lpj; -} - -void __init tsc_init(void) +static bool __init determine_cpu_tsc_frequencies(void) { - u64 lpj, cyc; - int cpu; - - if (!boot_cpu_has(X86_FEATURE_TSC)) { - setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER); - return; - } + /* Make sure that cpu and tsc are not already calibrated */ + WARN_ON(cpu_khz || tsc_khz); cpu_khz = x86_platform.calibrate_cpu(); tsc_khz = x86_platform.calibrate_tsc(); @@ -1377,20 +1355,52 @@ void __init tsc_init(void) else if (abs(cpu_khz - tsc_khz) * 10 > tsc_khz) cpu_khz = tsc_khz; - if (!tsc_khz) { - mark_tsc_unstable("could not calculate TSC khz"); - setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER); - return; - } + if (tsc_khz == 0) + return false; pr_info("Detected %lu.%03lu MHz processor\n", - (unsigned long)cpu_khz / 1000, - (unsigned long)cpu_khz % 1000); + (unsigned long)cpu_khz / KHZ, + (unsigned long)cpu_khz % KHZ); if (cpu_khz != tsc_khz) { pr_info("Detected %lu.%03lu MHz TSC", - (unsigned long)tsc_khz / 1000, - (unsigned long)tsc_khz % 1000); + (unsigned long)tsc_khz / KHZ, + (unsigned long)tsc_khz % KHZ); + } + return true; +} + +static unsigned long __init get_loops_per_jiffy(void) +{ + unsigned long lpj = tsc_khz * KHZ; + + do_div(lpj, HZ); + return lpj; +} + +void __init tsc_early_init(void) +{ + if (!boot_cpu_has(X86_FEATURE_TSC)) + return; + if (!determine_cpu_tsc_frequencies()) + return; + loops_per_jiffy = get_loops_per_jiffy(); +} + +void __init tsc_init(void) +{ + if (!boot_cpu_has(X86_FEATURE_TSC)) { + setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER); + return; + } + + if (!tsc_khz) { + /* We failed to determine frequencies earlier, try again */ + if (!determine_cpu_tsc_frequencies()) { + mark_tsc_unstable("could not calculate TSC khz"); + setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER); + return; + } } /* Sanitize TSC ADJUST before cyc2ns gets initialized */ @@ -1413,10 +1423,7 @@ void __init tsc_init(void) if (!no_sched_irq_time) enable_sched_clock_irqtime(); - lpj = ((u64)tsc_khz * 1000); - do_div(lpj, HZ); - lpj_fine = lpj; - + lpj_fine = get_loops_per_jiffy(); use_tsc_delay(); check_system_tsc_reliable();