diff options
author | ian <ian@FreeBSD.org> | 2015-08-23 18:03:43 +0000 |
---|---|---|
committer | ian <ian@FreeBSD.org> | 2015-08-23 18:03:43 +0000 |
commit | 8cf9fedbf651f151cb25af637e612be5b827d962 (patch) | |
tree | cf04455142daaa6e263a9eaff0f3bba9977cd3da /sys/kern/kern_tc.c | |
parent | 9fbd70f0796a6feeb989a8f1443fefd3d29409c0 (diff) | |
download | FreeBSD-src-8cf9fedbf651f151cb25af637e612be5b827d962.zip FreeBSD-src-8cf9fedbf651f151cb25af637e612be5b827d962.tar.gz |
MFC r286701:
If a specific timecounter has been chosen via sysctl, and a new
timecounter with higher quality registers (presumably in a module that has
just been loaded), do not undo the user's choice by switching to the new
timecounter.
Document that behavior, and also the fact that there is no way to
unregister a timecounter (and thus no way to unload a module containing
one).
Diffstat (limited to 'sys/kern/kern_tc.c')
-rw-r--r-- | sys/kern/kern_tc.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index 0d4ffa2..08b4f66 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -133,6 +133,8 @@ SYSCTL_PROC(_kern_timecounter, OID_AUTO, alloweddeviation, sysctl_kern_timecounter_adjprecision, "I", "Allowed time interval deviation in percents"); +static int tc_chosen; /* Non-zero if a specific tc was chosen via sysctl. */ + static void tc_windup(void); static void cpu_tick_calibrate(int); @@ -1180,10 +1182,13 @@ tc_init(struct timecounter *tc) "quality", CTLFLAG_RD, &(tc->tc_quality), 0, "goodness of time counter"); /* - * Never automatically use a timecounter with negative quality. + * Do not automatically switch if the current tc was specifically + * chosen. Never automatically use a timecounter with negative quality. * Even though we run on the dummy counter, switching here may be - * worse since this timecounter may not be monotonous. + * worse since this timecounter may not be monotonic. */ + if (tc_chosen) + return; if (tc->tc_quality < 0) return; if (tc->tc_quality < timecounter->tc_quality) @@ -1411,9 +1416,12 @@ sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS) strlcpy(newname, tc->tc_name, sizeof(newname)); error = sysctl_handle_string(oidp, &newname[0], sizeof(newname), req); - if (error != 0 || req->newptr == NULL || - strcmp(newname, tc->tc_name) == 0) + if (error != 0 || req->newptr == NULL) return (error); + /* Record that the tc in use now was specifically chosen. */ + tc_chosen = 1; + if (strcmp(newname, tc->tc_name) == 0) + return (0); for (newtc = timecounters; newtc != NULL; newtc = newtc->tc_next) { if (strcmp(newname, newtc->tc_name) != 0) continue; @@ -1434,7 +1442,7 @@ SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW, "Timecounter hardware selected"); -/* Report or change the active timecounter hardware. */ +/* Report the available timecounter hardware. */ static int sysctl_kern_timecounter_choice(SYSCTL_HANDLER_ARGS) { |