From 8d5fc57e655494778bc372ee7d12b519d536bd51 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 8 Mar 2021 01:50:12 +0200 Subject: Make kern.timecounter.hardware tunable Noted and reviewed by: kevans MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D29122 --- cpukit/score/src/kern_tc.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 51ef27744e..2e9de6e463 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -290,6 +290,7 @@ SYSCTL_PROC(_kern_timecounter, OID_AUTO, alloweddeviation, volatile int rtc_generation = 1; static int tc_chosen; /* Non-zero if a specific tc was chosen via sysctl. */ +static char tc_from_tunable[16]; #endif /* __rtems__ */ static void tc_windup(struct bintime *new_boottimebin); @@ -1400,17 +1401,26 @@ tc_init(struct timecounter *tc) return; if (tc->tc_quality < 0) return; -#endif /* __rtems__ */ + if (tc_from_tunable[0] != '\0' && + strcmp(tc->tc_name, tc_from_tunable) == 0) { + tc_chosen = 1; + tc_from_tunable[0] = '\0'; + } else { + if (tc->tc_quality < timecounter->tc_quality) + return; + if (tc->tc_quality == timecounter->tc_quality && + tc->tc_frequency < timecounter->tc_frequency) + return; + } + (void)tc->tc_get_timecount(tc); + timecounter = tc; +#else /* __rtems__ */ if (tc->tc_quality < timecounter->tc_quality) return; if (tc->tc_quality == timecounter->tc_quality && tc->tc_frequency < timecounter->tc_frequency) return; -#ifndef __rtems__ - (void)tc->tc_get_timecount(tc); -#endif /* __rtems__ */ timecounter = tc; -#ifdef __rtems__ tc_windup(NULL); #endif /* __rtems__ */ } @@ -2241,6 +2251,9 @@ inittimehands(void *dummy) for (i = 1, thp = &ths[0]; i < timehands_count; thp = &ths[i++]) thp->th_next = &ths[i]; thp->th_next = &ths[0]; + + TUNABLE_STR_FETCH("kern.timecounter.hardware", tc_from_tunable, + sizeof(tc_from_tunable)); } SYSINIT(timehands, SI_SUB_TUNABLES, SI_ORDER_ANY, inittimehands, NULL); -- cgit v1.2.3