CVSROOT:        /cvs
Module name:    src
Changes by:     chel...@cvs.openbsd.org 2019/03/25 17:32:00

Modified files:
        sys/kern       : kern_tc.c kern_time.c 
        sys/sys        : timetc.h 

Log message:
MP-safe timecounting: new rwlock: tc_lock

tc_lock allows adjfreq(2) and the kern.timecounter.hardware sysctl(2)
to read/write the active timecounter pointer and the .tc_adj_freq
member of the active timecounter safely.  This eliminates any possibility
of a torn read/write for the .tc_adj_freq member when we drop the
KERNEL_LOCK from the timecounting layer.  It also ensures the active
timecounter does not change in the midst of an adjfreq(2) call.

Because these are not high-traffic paths, we can get away with using
tc_lock in write-mode to ensure combination read/write adjtime(2) calls
are relatively atomic (a) to other writer adjtime(2) calls, and (b) to
settimeofday(2)/clock_settime(2) calls, which cancel ongoing adjtime(2)
adjustment.

When the KERNEL_LOCK is dropped, an unprivileged user will be able to
create some tc_lock contention via adjfreq(2); it is very unlikely to
ever be a problem.  If it ever is actually a problem a lockless read
could be added to address it.

While here, reorganize sys_adjfreq()/sys_adjtime() to minimize code
under the lock.  Also while here, make tc_adjfreq() void, as it cannot
fail under any circumstance.  Also also while here, annotate various
globals/struct members with lock ordering details.

With lots of input from mpi@ and visa@.

ok visa@

Reply via email to