Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Print a rate limited warning if the TSC timecounter...
details: https://anonhg.NetBSD.org/src/rev/d5ee00b84d7a
branches: trunk
changeset: 972935:d5ee00b84d7a
user: ad <ad%NetBSD.org@localhost>
date: Sat Jun 13 23:58:51 2020 +0000
description:
Print a rate limited warning if the TSC timecounter goes backwards from the
viewpoint of any single LWP.
diffstat:
sys/arch/amd64/amd64/cpufunc.S | 9 +++++----
sys/arch/amd64/include/proc.h | 3 ++-
sys/arch/i386/i386/cpufunc.S | 11 +++++------
sys/arch/i386/include/proc.h | 3 ++-
sys/arch/x86/x86/tsc.c | 40 +++++++++++++++++++++++++++++++++++++---
5 files changed, 51 insertions(+), 15 deletions(-)
diffs (176 lines):
diff -r bd25dec90681 -r d5ee00b84d7a sys/arch/amd64/amd64/cpufunc.S
--- a/sys/arch/amd64/amd64/cpufunc.S Sat Jun 13 22:35:23 2020 +0000
+++ b/sys/arch/amd64/amd64/cpufunc.S Sat Jun 13 23:58:51 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc.S,v 1.59 2020/06/01 22:58:06 ad Exp $ */
+/* $NetBSD: cpufunc.S,v 1.60 2020/06/13 23:58:51 ad Exp $ */
/*
* Copyright (c) 1998, 2007, 2008, 2020 The NetBSD Foundation, Inc.
@@ -206,8 +206,10 @@
END(x86_hotpatch)
#endif /* !XENPV */
-/* Could be exact same as cpu_counter, but KMSAN needs to have the correct
- * size of the return value. */
+/*
+ * Could be exact same as cpu_counter, but KMSAN needs to have the correct
+ * size of the return value.
+ */
ENTRY(cpu_counter32)
movq CPUVAR(CURLWP), %rcx
1:
@@ -221,7 +223,6 @@
2:
jmp 1b
END(cpu_counter32)
-STRONG_ALIAS(tsc_get_timecount, cpu_counter32)
ENTRY(cpu_counter)
movq CPUVAR(CURLWP), %rcx
diff -r bd25dec90681 -r d5ee00b84d7a sys/arch/amd64/include/proc.h
--- a/sys/arch/amd64/include/proc.h Sat Jun 13 22:35:23 2020 +0000
+++ b/sys/arch/amd64/include/proc.h Sat Jun 13 23:58:51 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: proc.h,v 1.24 2020/01/13 00:26:52 ad Exp $ */
+/* $NetBSD: proc.h,v 1.25 2020/06/13 23:58:51 ad Exp $ */
/*
* Copyright (c) 1991 Regents of the University of California.
@@ -46,6 +46,7 @@
struct vm_page;
struct mdlwp {
+ volatile uint64_t md_tsc; /* last TSC reading */
struct trapframe *md_regs; /* registers on current frame */
int md_flags; /* machine-dependent flags */
volatile int md_astpending;
diff -r bd25dec90681 -r d5ee00b84d7a sys/arch/i386/i386/cpufunc.S
--- a/sys/arch/i386/i386/cpufunc.S Sat Jun 13 22:35:23 2020 +0000
+++ b/sys/arch/i386/i386/cpufunc.S Sat Jun 13 23:58:51 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc.S,v 1.45 2020/05/28 20:03:19 ad Exp $ */
+/* $NetBSD: cpufunc.S,v 1.46 2020/06/13 23:58:52 ad Exp $ */
/*-
* Copyright (c) 1998, 2007, 2020 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
#include <sys/errno.h>
#include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: cpufunc.S,v 1.45 2020/05/28 20:03:19 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpufunc.S,v 1.46 2020/06/13 23:58:52 ad Exp $");
#include "opt_xen.h"
@@ -163,7 +163,7 @@
ret
END(msr_onfault)
-ENTRY(tsc_get_timecount)
+ENTRY(cpu_counter)
pushl %ebx
movl CPUVAR(CURLWP), %ecx
1:
@@ -177,10 +177,9 @@
ret
2:
jmp 1b
-END(tsc_get_timecount)
+END(cpu_counter)
-STRONG_ALIAS(cpu_counter, tsc_get_timecount)
-STRONG_ALIAS(cpu_counter32, tsc_get_timecount)
+STRONG_ALIAS(cpu_counter32, cpu_counter)
ENTRY(breakpoint)
pushl %ebp
diff -r bd25dec90681 -r d5ee00b84d7a sys/arch/i386/include/proc.h
--- a/sys/arch/i386/include/proc.h Sat Jun 13 22:35:23 2020 +0000
+++ b/sys/arch/i386/include/proc.h Sat Jun 13 23:58:51 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: proc.h,v 1.47 2020/01/13 00:26:52 ad Exp $ */
+/* $NetBSD: proc.h,v 1.48 2020/06/13 23:58:52 ad Exp $ */
/*
* Copyright (c) 1991 Regents of the University of California.
@@ -46,6 +46,7 @@
#define MDL_FPU_IN_CPU 0x0020 /* the FPU state is in the CPU */
struct mdlwp {
+ volatile uint64_t md_tsc; /* last TSC reading */
struct trapframe *md_regs; /* registers on current frame */
int md_flags; /* machine-dependent flags */
volatile int md_astpending; /* AST pending for this process */
diff -r bd25dec90681 -r d5ee00b84d7a sys/arch/x86/x86/tsc.c
--- a/sys/arch/x86/x86/tsc.c Sat Jun 13 22:35:23 2020 +0000
+++ b/sys/arch/x86/x86/tsc.c Sat Jun 13 23:58:51 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tsc.c,v 1.48 2020/05/27 18:46:15 ad Exp $ */
+/* $NetBSD: tsc.c,v 1.49 2020/06/13 23:58:52 ad Exp $ */
/*-
* Copyright (c) 2008, 2020 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.48 2020/05/27 18:46:15 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tsc.c,v 1.49 2020/06/13 23:58:52 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -38,6 +38,7 @@
#include <sys/kernel.h>
#include <sys/cpu.h>
#include <sys/xcall.h>
+#include <sys/lock.h>
#include <machine/cpu_counter.h>
#include <machine/cpuvar.h>
@@ -50,7 +51,7 @@
#define TSC_SYNC_ROUNDS 1000
#define ABS(a) ((a) >= 0 ? (a) : -(a))
-u_int tsc_get_timecount(struct timecounter *);
+static u_int tsc_get_timecount(struct timecounter *);
static void tsc_delay(unsigned int);
@@ -352,3 +353,36 @@
x86_pause();
}
}
+
+static u_int
+tsc_get_timecount(struct timecounter *tc)
+{
+ static __cpu_simple_lock_t lock = __SIMPLELOCK_UNLOCKED;
+ static int lastwarn;
+ uint64_t cur, prev;
+ lwp_t *l = curlwp;
+ int ticks;
+
+ /*
+ * Previous value must be read before the counter and stored to
+ * after, because this routine can be called from interrupt context
+ * and may run over the top of an existing invocation. Ordering is
+ * guaranteed by "volatile" on md_tsc.
+ */
+ prev = l->l_md.md_tsc;
+ cur = cpu_counter();
+ if (__predict_false(cur < prev)) {
+ if ((cur >> 63) == (prev >> 63) &&
+ __cpu_simple_lock_try(&lock)) {
+ ticks = getticks();
+ if (ticks - lastwarn >= hz) {
+ printf("WARNING: TSC time went backwards "
+ " by %u\n", (unsigned)(prev - cur));
+ lastwarn = ticks;
+ }
+ __cpu_simple_unlock(&lock);
+ }
+ }
+ l->l_md.md_tsc = cur;
+ return (uint32_t)cur;
+}
Home |
Main Index |
Thread Index |
Old Index