timecounter: Load the currently selected tc once in tc_windup()

Reported by:	Sebastian Huber <sebastian.huber@embedded-brains.de>
Reviewed by:	kib
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D32729
This commit is contained in:
Mark Johnston
2021-10-29 14:29:22 -04:00
committed by Moyano, Gabriel
parent 4f130929b8
commit 1640657022

View File

@@ -110,6 +110,13 @@ atomic_store_rel_int(Atomic_Uint *i, u_int val)
_Atomic_Store_uint(i, val, ATOMIC_ORDER_RELEASE); _Atomic_Store_uint(i, val, ATOMIC_ORDER_RELEASE);
} }
static inline void *
atomic_load_ptr(void *ptr)
{
return ((void *)_Atomic_Load_uintptr(ptr, ATOMIC_ORDER_RELAXED));
}
#endif /* __rtems__ */ #endif /* __rtems__ */
/* /*
@@ -1559,6 +1566,7 @@ _Timecounter_Windup(struct bintime *new_boottimebin,
#endif /* __rtems__ */ #endif /* __rtems__ */
{ {
struct bintime bt; struct bintime bt;
struct timecounter *tc;
struct timehands *th, *tho; struct timehands *th, *tho;
uint32_t delta, ncount, ogen; uint32_t delta, ncount, ogen;
int i; int i;
@@ -1593,9 +1601,10 @@ _Timecounter_Windup(struct bintime *new_boottimebin,
* changing timecounters, a counter value from the new timecounter. * changing timecounters, a counter value from the new timecounter.
* Update the offset fields accordingly. * Update the offset fields accordingly.
*/ */
tc = atomic_load_ptr(&timecounter);
delta = tc_delta(th); delta = tc_delta(th);
if (th->th_counter != timecounter) if (th->th_counter != tc)
ncount = timecounter->tc_get_timecount(timecounter); ncount = tc->tc_get_timecount(tc);
else else
ncount = 0; ncount = 0;
#ifdef FFCLOCK #ifdef FFCLOCK
@@ -1661,20 +1670,20 @@ _Timecounter_Windup(struct bintime *new_boottimebin,
bintime2timespec(&bt, &th->th_nanotime); bintime2timespec(&bt, &th->th_nanotime);
/* Now is a good time to change timecounters. */ /* Now is a good time to change timecounters. */
if (th->th_counter != timecounter) { if (th->th_counter != tc) {
#ifndef __rtems__ #ifndef __rtems__
#ifndef __arm__ #ifndef __arm__
if ((timecounter->tc_flags & TC_FLAGS_C2STOP) != 0) if ((tc->tc_flags & TC_FLAGS_C2STOP) != 0)
cpu_disable_c2_sleep++; cpu_disable_c2_sleep++;
if ((th->th_counter->tc_flags & TC_FLAGS_C2STOP) != 0) if ((th->th_counter->tc_flags & TC_FLAGS_C2STOP) != 0)
cpu_disable_c2_sleep--; cpu_disable_c2_sleep--;
#endif #endif
#endif /* __rtems__ */ #endif /* __rtems__ */
th->th_counter = timecounter; th->th_counter = tc;
th->th_offset_count = ncount; th->th_offset_count = ncount;
#ifndef __rtems__ #ifndef __rtems__
tc_min_ticktock_freq = max(1, timecounter->tc_frequency / tc_min_ticktock_freq = max(1, tc->tc_frequency /
(((uint64_t)timecounter->tc_counter_mask + 1) / 3)); (((uint64_t)tc->tc_counter_mask + 1) / 3));
#endif /* __rtems__ */ #endif /* __rtems__ */
recalculate_scaling_factor_and_large_delta(th); recalculate_scaling_factor_and_large_delta(th);
#ifdef FFCLOCK #ifdef FFCLOCK