summaryrefslogtreecommitdiff
path: root/sys/kern/kern_tc.c
diff options
context:
space:
mode:
authorcheloha <cheloha@cvs.openbsd.org>2019-03-09 23:04:57 +0000
committercheloha <cheloha@cvs.openbsd.org>2019-03-09 23:04:57 +0000
commitf0a09737c9214a057bef51b20677739d4e73be30 (patch)
treef8148967c4076ee2ff334a0b4f8d93c90473e4ca /sys/kern/kern_tc.c
parentebbf205bcd31aba3faedbbe1828081771d17b24e (diff)
tc_windup: read active timecounter once at function start.
tc_windup() is not necessarily called with KERNEL_LOCK, so it is possible for the timecounter pointer to change in the midst of the call via the kern.timecounter.hardware sysctl(2). Reading it once and using that local copy ensures we're referring to the same timecounter consistently. Apparently the compiler can optimize this out... somehow... so there may be room for improvement. Idea from visa@. With input from visa@, mpi@, cjeker@, and guenther@. ok visa@ mpi@
Diffstat (limited to 'sys/kern/kern_tc.c')
-rw-r--r--sys/kern/kern_tc.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index 607d06fbeee..eccf869c19c 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_tc.c,v 1.37 2019/01/31 05:00:18 cheloha Exp $ */
+/* $OpenBSD: kern_tc.c,v 1.38 2019/03/09 23:04:56 cheloha Exp $ */
/*
* Copyright (c) 2000 Poul-Henning Kamp <phk@FreeBSD.org>
@@ -447,6 +447,7 @@ void
tc_windup(void)
{
struct bintime bt;
+ struct timecounter *active_tc;
struct timehands *th, *tho;
u_int64_t scale;
u_int delta, ncount, ogen;
@@ -454,6 +455,8 @@ tc_windup(void)
MUTEX_ASSERT_LOCKED(&timecounter_mtx);
+ active_tc = timecounter;
+
/*
* Make the next timehands a copy of the current one, but do not
* overwrite the generation or next pointer. While we update
@@ -472,8 +475,8 @@ tc_windup(void)
* Update the offset fields accordingly.
*/
delta = tc_delta(th);
- if (th->th_counter != timecounter)
- ncount = timecounter->tc_get_timecount(timecounter);
+ if (th->th_counter != active_tc)
+ ncount = active_tc->tc_get_timecount(active_tc);
else
ncount = 0;
th->th_offset_count += delta;
@@ -516,8 +519,8 @@ tc_windup(void)
bintime2timespec(&bt, &th->th_nanotime);
/* Now is a good time to change timecounters. */
- if (th->th_counter != timecounter) {
- th->th_counter = timecounter;
+ if (th->th_counter != active_tc) {
+ th->th_counter = active_tc;
th->th_offset_count = ncount;
}