linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch 0/2] x86/tsc: Cure fallout from the TSC ADJUST series
@ 2017-02-09 15:08 Thomas Gleixner
  2017-02-09 15:08 ` [patch 1/2] x86/tsc: Avoid the large time jump when sanitizing TSC ADJUST Thomas Gleixner
  2017-02-09 15:08 ` [patch 2/2] x86/tsc: Make the TSC ADJUST sanitizing work for tsc_reliable Thomas Gleixner
  0 siblings, 2 replies; 5+ messages in thread
From: Thomas Gleixner @ 2017-02-09 15:08 UTC (permalink / raw)
  To: LKML; +Cc: x86, Peter Zijlstra, Olof Johansson

The following patches address the fallout of the TSC ADJUST changes in
Linus tree.

      - Forward jump of dmesg timestamps
      - Make it work when TSC is marked reliable

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [patch 1/2] x86/tsc: Avoid the large time jump when sanitizing TSC ADJUST
  2017-02-09 15:08 [patch 0/2] x86/tsc: Cure fallout from the TSC ADJUST series Thomas Gleixner
@ 2017-02-09 15:08 ` Thomas Gleixner
  2017-02-10  8:48   ` [tip:x86/urgent] " tip-bot for Thomas Gleixner
  2017-02-09 15:08 ` [patch 2/2] x86/tsc: Make the TSC ADJUST sanitizing work for tsc_reliable Thomas Gleixner
  1 sibling, 1 reply; 5+ messages in thread
From: Thomas Gleixner @ 2017-02-09 15:08 UTC (permalink / raw)
  To: LKML; +Cc: x86, Peter Zijlstra, Olof Johansson

[-- Attachment #1: x86-tsc--Avoid-the-large-time-jump-when-sanitizing-TSC-ADJUST.patch --]
[-- Type: text/plain, Size: 2510 bytes --]

Olof reported that on a machine which has a BIOS wreckaged TSC the
timestamps in dmesg are making a large jump because the TSC value is
jumping forward after resetting the TSC ADJUST register to a sane value.

This can be avoided by calling the TSC ADJUST saniziting function before
initializing the per cpu sched clock machinery. That takes the offset into
account and avoid the time jump.

What cannot be avoided is that the 'Firmware Bug' warnings on the secondary
CPUs are printed with the large time offsets because it would be too much
effort and ugly hackery to print those warnings into a buffer and emit them
after the adjustemt on the starting CPUs. It's a firmware bug and should be
fixed in firmware. The weird timestamps are collateral damage and just
illustrate the sillyness of the BIOS folks:

[    0.397445] smp: Bringing up secondary CPUs ...
[    0.402100] x86: Booting SMP configuration:
[    0.406343] .... node  #0, CPUs:      #1
[1265776479.930667] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2978888639075328 CPU1: -2978888639183101
[1265776479.944664] TSC ADJUST synchronize: Reference CPU0: 0 CPU1: -2978888639183101
[    0.508119]  #2
[1265776480.032346] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2978888639075328 CPU2: -2978888639183677
[1265776480.044192] TSC ADJUST synchronize: Reference CPU0: 0 CPU2: -2978888639183677
[    0.607643]  #3
[1265776480.131874] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2978888639075328 CPU3: -2978888639184530
[1265776480.143720] TSC ADJUST synchronize: Reference CPU0: 0 CPU3: -2978888639184530
[    0.707108] smp: Brought up 1 node, 4 CPUs
[    0.711271] smpboot: Total of 4 processors activated (21698.88 BogoMIPS)


Reported-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/tsc.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1356,6 +1356,9 @@ void __init tsc_init(void)
 		(unsigned long)cpu_khz / 1000,
 		(unsigned long)cpu_khz % 1000);
 
+	/* Sanitize TSC ADJUST before cyc2ns gets initialized */
+	tsc_store_and_check_tsc_adjust(true);
+
 	/*
 	 * Secondary CPUs do not run through tsc_init(), so set up
 	 * all the scale factors for all CPUs, assuming the same
@@ -1386,8 +1389,6 @@ void __init tsc_init(void)
 
 	if (unsynchronized_tsc())
 		mark_tsc_unstable("TSCs unsynchronized");
-	else
-		tsc_store_and_check_tsc_adjust(true);
 
 	check_system_tsc_reliable();
 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [patch 2/2] x86/tsc: Make the TSC ADJUST sanitizing work for tsc_reliable
  2017-02-09 15:08 [patch 0/2] x86/tsc: Cure fallout from the TSC ADJUST series Thomas Gleixner
  2017-02-09 15:08 ` [patch 1/2] x86/tsc: Avoid the large time jump when sanitizing TSC ADJUST Thomas Gleixner
@ 2017-02-09 15:08 ` Thomas Gleixner
  2017-02-10  8:49   ` [tip:x86/urgent] " tip-bot for Thomas Gleixner
  1 sibling, 1 reply; 5+ messages in thread
From: Thomas Gleixner @ 2017-02-09 15:08 UTC (permalink / raw)
  To: LKML; +Cc: x86, Peter Zijlstra, Olof Johansson

[-- Attachment #1: x86-tsc--Make-the-TSC-ADJUST-sanitizing-work-for-tsc_reliable.patch --]
[-- Type: text/plain, Size: 1708 bytes --]

When the TSC is marked reliable then the synchronization check is skipped,
but that also skips the TSC ADJUST sanitizing code. So on a machine with a
wreckaged BIOS the TSC deviation between CPUs might go unnoticed.

Let the TSC adjust sanitizing code run unconditionally and just skip the
expensive synchronization checks when TSC is marked reliable.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/kernel/tsc_sync.c |   16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -286,13 +286,6 @@ void check_tsc_sync_source(int cpu)
 	if (unsynchronized_tsc())
 		return;
 
-	if (tsc_clocksource_reliable) {
-		if (cpu == (nr_cpu_ids-1) || system_state != SYSTEM_BOOTING)
-			pr_info(
-			"Skipped synchronization checks as TSC is reliable.\n");
-		return;
-	}
-
 	/*
 	 * Set the maximum number of test runs to
 	 *  1 if the CPU does not provide the TSC_ADJUST MSR
@@ -380,14 +373,19 @@ void check_tsc_sync_target(void)
 	int cpus = 2;
 
 	/* Also aborts if there is no TSC. */
-	if (unsynchronized_tsc() || tsc_clocksource_reliable)
+	if (unsynchronized_tsc())
 		return;
 
 	/*
 	 * Store, verify and sanitize the TSC adjust register. If
 	 * successful skip the test.
+	 *
+	 * The test is also skipped when the TSC is marked reliable. This
+	 * is true for SoCs which have no fallback clocksource. On these
+	 * SoCs the TSC is frequency synchronized, but still the TSC ADJUST
+	 * register might have been wreckaged by the BIOS..
 	 */
-	if (tsc_store_and_check_tsc_adjust(false)) {
+	if (tsc_store_and_check_tsc_adjust(false) || tsc_clocksource_reliable) {
 		atomic_inc(&skip_test);
 		return;
 	}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [tip:x86/urgent] x86/tsc: Avoid the large time jump when sanitizing TSC ADJUST
  2017-02-09 15:08 ` [patch 1/2] x86/tsc: Avoid the large time jump when sanitizing TSC ADJUST Thomas Gleixner
@ 2017-02-10  8:48   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 5+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-02-10  8:48 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: hpa, peterz, olof, tglx, linux-kernel, mingo

Commit-ID:  f2e04214ef7f7e49d1e06109ad1b2718155dab25
Gitweb:     http://git.kernel.org/tip/f2e04214ef7f7e49d1e06109ad1b2718155dab25
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Thu, 9 Feb 2017 16:08:41 +0100
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Fri, 10 Feb 2017 09:47:16 +0100

x86/tsc: Avoid the large time jump when sanitizing TSC ADJUST

Olof reported that on a machine which has a BIOS wreckaged TSC the
timestamps in dmesg are making a large jump because the TSC value is
jumping forward after resetting the TSC ADJUST register to a sane value.

This can be avoided by calling the TSC ADJUST saniziting function before
initializing the per cpu sched clock machinery. That takes the offset into
account and avoid the time jump.

What cannot be avoided is that the 'Firmware Bug' warnings on the secondary
CPUs are printed with the large time offsets because it would be too much
effort and ugly hackery to print those warnings into a buffer and emit them
after the adjustemt on the starting CPUs. It's a firmware bug and should be
fixed in firmware. The weird timestamps are collateral damage and just
illustrate the sillyness of the BIOS folks:

[    0.397445] smp: Bringing up secondary CPUs ...
[    0.402100] x86: Booting SMP configuration:
[    0.406343] .... node  #0, CPUs:      #1
[1265776479.930667] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2978888639075328 CPU1: -2978888639183101
[1265776479.944664] TSC ADJUST synchronize: Reference CPU0: 0 CPU1: -2978888639183101
[    0.508119]  #2
[1265776480.032346] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2978888639075328 CPU2: -2978888639183677
[1265776480.044192] TSC ADJUST synchronize: Reference CPU0: 0 CPU2: -2978888639183677
[    0.607643]  #3
[1265776480.131874] [Firmware Bug]: TSC ADJUST differs: Reference CPU0: -2978888639075328 CPU3: -2978888639184530
[1265776480.143720] TSC ADJUST synchronize: Reference CPU0: 0 CPU3: -2978888639184530
[    0.707108] smp: Brought up 1 node, 4 CPUs
[    0.711271] smpboot: Total of 4 processors activated (21698.88 BogoMIPS)

Reported-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20170209151231.411460506@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

---
 arch/x86/kernel/tsc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index e41af59..37e7cf5 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1356,6 +1356,9 @@ void __init tsc_init(void)
 		(unsigned long)cpu_khz / 1000,
 		(unsigned long)cpu_khz % 1000);
 
+	/* Sanitize TSC ADJUST before cyc2ns gets initialized */
+	tsc_store_and_check_tsc_adjust(true);
+
 	/*
 	 * Secondary CPUs do not run through tsc_init(), so set up
 	 * all the scale factors for all CPUs, assuming the same
@@ -1386,8 +1389,6 @@ void __init tsc_init(void)
 
 	if (unsynchronized_tsc())
 		mark_tsc_unstable("TSCs unsynchronized");
-	else
-		tsc_store_and_check_tsc_adjust(true);
 
 	check_system_tsc_reliable();
 

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [tip:x86/urgent] x86/tsc: Make the TSC ADJUST sanitizing work for tsc_reliable
  2017-02-09 15:08 ` [patch 2/2] x86/tsc: Make the TSC ADJUST sanitizing work for tsc_reliable Thomas Gleixner
@ 2017-02-10  8:49   ` tip-bot for Thomas Gleixner
  0 siblings, 0 replies; 5+ messages in thread
From: tip-bot for Thomas Gleixner @ 2017-02-10  8:49 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: peterz, linux-kernel, olof, hpa, tglx, mingo

Commit-ID:  5f2e71e71410ecb858cfec184ba092adaca61626
Gitweb:     http://git.kernel.org/tip/5f2e71e71410ecb858cfec184ba092adaca61626
Author:     Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Thu, 9 Feb 2017 16:08:42 +0100
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Fri, 10 Feb 2017 09:47:17 +0100

x86/tsc: Make the TSC ADJUST sanitizing work for tsc_reliable

When the TSC is marked reliable then the synchronization check is skipped,
but that also skips the TSC ADJUST sanitizing code. So on a machine with a
wreckaged BIOS the TSC deviation between CPUs might go unnoticed.

Let the TSC adjust sanitizing code run unconditionally and just skip the
expensive synchronization checks when TSC is marked reliable.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Olof Johansson <olof@lixom.net>
Link: http://lkml.kernel.org/r/20170209151231.491189912@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

---
 arch/x86/kernel/tsc_sync.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index d0db011..728f753 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -286,13 +286,6 @@ void check_tsc_sync_source(int cpu)
 	if (unsynchronized_tsc())
 		return;
 
-	if (tsc_clocksource_reliable) {
-		if (cpu == (nr_cpu_ids-1) || system_state != SYSTEM_BOOTING)
-			pr_info(
-			"Skipped synchronization checks as TSC is reliable.\n");
-		return;
-	}
-
 	/*
 	 * Set the maximum number of test runs to
 	 *  1 if the CPU does not provide the TSC_ADJUST MSR
@@ -380,14 +373,19 @@ void check_tsc_sync_target(void)
 	int cpus = 2;
 
 	/* Also aborts if there is no TSC. */
-	if (unsynchronized_tsc() || tsc_clocksource_reliable)
+	if (unsynchronized_tsc())
 		return;
 
 	/*
 	 * Store, verify and sanitize the TSC adjust register. If
 	 * successful skip the test.
+	 *
+	 * The test is also skipped when the TSC is marked reliable. This
+	 * is true for SoCs which have no fallback clocksource. On these
+	 * SoCs the TSC is frequency synchronized, but still the TSC ADJUST
+	 * register might have been wreckaged by the BIOS..
 	 */
-	if (tsc_store_and_check_tsc_adjust(false)) {
+	if (tsc_store_and_check_tsc_adjust(false) || tsc_clocksource_reliable) {
 		atomic_inc(&skip_test);
 		return;
 	}

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2017-02-10  9:44 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-09 15:08 [patch 0/2] x86/tsc: Cure fallout from the TSC ADJUST series Thomas Gleixner
2017-02-09 15:08 ` [patch 1/2] x86/tsc: Avoid the large time jump when sanitizing TSC ADJUST Thomas Gleixner
2017-02-10  8:48   ` [tip:x86/urgent] " tip-bot for Thomas Gleixner
2017-02-09 15:08 ` [patch 2/2] x86/tsc: Make the TSC ADJUST sanitizing work for tsc_reliable Thomas Gleixner
2017-02-10  8:49   ` [tip:x86/urgent] " tip-bot for Thomas Gleixner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).