diff options
author | cheloha <cheloha@cvs.openbsd.org> | 2019-03-09 23:04:57 +0000 |
---|---|---|
committer | cheloha <cheloha@cvs.openbsd.org> | 2019-03-09 23:04:57 +0000 |
commit | f0a09737c9214a057bef51b20677739d4e73be30 (patch) | |
tree | f8148967c4076ee2ff334a0b4f8d93c90473e4ca /sys/kern/kern_tc.c | |
parent | ebbf205bcd31aba3faedbbe1828081771d17b24e (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.c | 13 |
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; } |