mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: <mike.travis@hpe.com>
To: Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
	Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Bin Gao <bin.gao@linux.intel.com>,
	Prarit Bhargava <prarit@redhat.com>,
	Dimitri Sivanich <dimitri.sivanich@hpe.com>,
	Andrew Banman <andrew.banman@hpe.com>,
	Russ Anderson <russ.anderson@hpe.com>,
	linux-kernel@vger.kernel.org, x86@kernel.org
Subject: [PATCH 1/3] x86/kernel: Add option that TSC on Socket 0 being non-null is valid
Date: Thu, 21 Sep 2017 15:12:22 -0500	[thread overview]
Message-ID: <20170921201222.033552716@stormcage.americas.sgi.com> (raw)
In-Reply-To: <20170921201221.869441567@stormcage.americas.sgi.com>

[-- Attachment #1: add-base-nonzero --]
[-- Type: text/plain, Size: 4194 bytes --]

Add a flag to indicate that a TSC ADJUST value of non-zero is valid
on Socket 0.  This is required on multiple chassis systems for which
the Time Stamp Counter on all the chassis are started asynchronously.
The UV architecture is an example of this.

In this scenario the UV system BIOS will adjust all the TSC ADJUST values
forward so there are no negative ADJUST values.  This may cause the TSC
ADJUST value on socket 0 to not necessarily be zero.

This procedure results TSC skew rates that are far less than the values
as set by the current kernel TSC adjustment functions which force the
TSC ADJUST to be zero on Socket 0.  Note also that an assumption of
zero for TSC ADJUST was also made by not initializing the adjust values.

Signed-off-by: Mike Travis <mike.travis@hpe.com>
Reviewed-by: Dimitri Sivanich <dimitri.sivanich@hpe.com>
Reviewed-by: Russ Anderson <russ.anderson@hpe.com>
Reviewed-by: Andrew Banman <andrew.abanman@hpe.com>
---
 arch/x86/include/asm/tsc.h |    2 ++
 arch/x86/kernel/tsc.c      |   19 +++++++++++++++++++
 arch/x86/kernel/tsc_sync.c |   25 +++++++++++++++++++++----
 3 files changed, 42 insertions(+), 4 deletions(-)

--- linux.orig/arch/x86/include/asm/tsc.h
+++ linux/arch/x86/include/asm/tsc.h
@@ -35,6 +35,8 @@ extern void tsc_init(void);
 extern void mark_tsc_unstable(char *reason);
 extern int unsynchronized_tsc(void);
 extern int check_tsc_unstable(void);
+extern int check_tsc_socket0_nonzero(void);
+extern void mark_tsc_socket0_nonzero(char *reason);
 extern unsigned long native_calibrate_cpu(void);
 extern unsigned long native_calibrate_tsc(void);
 extern unsigned long long native_sched_clock_from_tsc(u64 tsc);
--- linux.orig/arch/x86/kernel/tsc.c
+++ linux/arch/x86/kernel/tsc.c
@@ -37,6 +37,11 @@ EXPORT_SYMBOL(tsc_khz);
  */
 static int __read_mostly tsc_unstable;
 
+/*
+ * TSC on socket 0 being non-zero may be correct as set by BIOS
+ */
+static int __read_mostly tsc_socket0_nonzero;
+
 /* native_sched_clock() is called before tsc_init(), so
    we must start with the TSC soft disabled to prevent
    erroneous rdtsc usage on !boot_cpu_has(X86_FEATURE_TSC) processors */
@@ -244,6 +249,20 @@ int check_tsc_unstable(void)
 }
 EXPORT_SYMBOL_GPL(check_tsc_unstable);
 
+void mark_tsc_socket0_nonzero(char *reason)
+{
+	tsc_socket0_nonzero = 1;
+	pr_info("Marking TSC non-zero value valid for socket 0 due to %s\n",
+		reason);
+}
+EXPORT_SYMBOL_GPL(mark_tsc_socket0_nonzero);
+
+int check_tsc_socket0_nonzero(void)
+{
+	return tsc_socket0_nonzero;
+}
+EXPORT_SYMBOL_GPL(check_tsc_socket0_nonzero);
+
 #ifdef CONFIG_X86_TSC
 int __init notsc_setup(char *str)
 {
--- linux.orig/arch/x86/kernel/tsc_sync.c
+++ linux/arch/x86/kernel/tsc_sync.c
@@ -71,12 +71,22 @@ static void tsc_sanitize_first_cpu(struc
 	 * non zero. We don't do that on non boot cpus because physical
 	 * hotplug should have set the ADJUST register to a value > 0 so
 	 * the TSC is in sync with the already running cpus.
+	 *
+	 * Also don't force the ADJUST value from non-zero to zero if that
+	 * is a valid value for socket 0 as determined by the system BIOS.
+	 * This is required where multiple chassis are started asynchronously
+	 * with each other and socket 0 may not have an TSC ADJUST value of 0.
 	 */
 	if (bootcpu && bootval != 0) {
-		pr_warn(FW_BUG "TSC ADJUST: CPU%u: %lld force to 0\n", cpu,
-			bootval);
-		wrmsrl(MSR_IA32_TSC_ADJUST, 0);
-		bootval = 0;
+		if (!check_tsc_socket0_nonzero()) {
+			pr_warn(FW_BUG "TSC ADJUST: CPU%u: %lld force to 0\n",
+				cpu, bootval);
+			wrmsrl(MSR_IA32_TSC_ADJUST, 0);
+			bootval = 0;
+		} else {
+			pr_info("TSC ADJUST: CPU%u: %lld NOT forced to 0\n",
+				cpu, bootval);
+		}
 	}
 	cur->adjusted = bootval;
 }
@@ -118,6 +128,13 @@ bool tsc_store_and_check_tsc_adjust(bool
 	cur->warned = false;
 
 	/*
+	 * If a non-zero TSC value for socket 0 is valid then the default
+	 * adjusted value cannot assumed to be zero.
+	 */
+	if (check_tsc_socket0_nonzero())
+		cur->adjusted = bootval;
+
+	/*
 	 * Check whether this CPU is the first in a package to come up. In
 	 * this case do not check the boot value against another package
 	 * because the new package might have been physically hotplugged,

-- 

  reply	other threads:[~2017-09-21 20:22 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-21 20:12 [PATCH 0/3] x86/platform/UV: Update TSC support mike.travis
2017-09-21 20:12 ` mike.travis [this message]
2017-09-25 15:30   ` [PATCH 1/3] x86/kernel: Add option that TSC on Socket 0 being non-null is valid Thomas Gleixner
2017-09-25 16:47     ` Mike Travis
2017-09-25 18:10       ` Thomas Gleixner
2017-09-26  0:13         ` Mike Travis
2017-09-26  7:28           ` Thomas Gleixner
2017-09-21 20:12 ` [PATCH 2/3] x86/kernel: Skip TSC test and error messages if already unstable mike.travis
2017-09-21 20:12 ` [PATCH 3/3] x86/platform/UV: Add check of TSC state set by UV BIOS mike.travis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170921201222.033552716@stormcage.americas.sgi.com \
    --to=mike.travis@hpe.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=andrew.banman@hpe.com \
    --cc=bin.gao@linux.intel.com \
    --cc=dimitri.sivanich@hpe.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=prarit@redhat.com \
    --cc=russ.anderson@hpe.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®