diff options
author | kib <kib@FreeBSD.org> | 2016-06-28 16:42:40 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2016-06-28 16:42:40 +0000 |
commit | 8543a46c508fbf946ee8bf0b83a54ca61e03b257 (patch) | |
tree | 7d5e3aa0ee656d6dd61d8cf6637216816bb15a34 /sys/kern | |
parent | fb3ea99e649137928787bf59dba50efdce32c30b (diff) | |
download | FreeBSD-src-8543a46c508fbf946ee8bf0b83a54ca61e03b257.zip FreeBSD-src-8543a46c508fbf946ee8bf0b83a54ca61e03b257.tar.gz |
Do not use Giant to prevent parallel calls to CLOCK_SETTIME(). Use
private mtx in resettodr(), no implementation of CLOCK_SETTIME() is
allowed to sleep.
Reviewed by: imp, jhb
Sponsored by: The FreeBSD Foundation
Approved by: re (gjb)
X-Differential revision: https://reviews.freebsd.org/D6825
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/subr_clock.c | 4 | ||||
-rw-r--r-- | sys/kern/subr_rtc.c | 9 |
2 files changed, 10 insertions, 3 deletions
diff --git a/sys/kern/subr_clock.c b/sys/kern/subr_clock.c index 05de5b9..0b2a084 100644 --- a/sys/kern/subr_clock.c +++ b/sys/kern/subr_clock.c @@ -67,8 +67,8 @@ sysctl_machdep_adjkerntz(SYSCTL_HANDLER_ARGS) resettodr(); return (error); } -SYSCTL_PROC(_machdep, OID_AUTO, adjkerntz, CTLTYPE_INT|CTLFLAG_RW, - &adjkerntz, 0, sysctl_machdep_adjkerntz, "I", +SYSCTL_PROC(_machdep, OID_AUTO, adjkerntz, CTLTYPE_INT | CTLFLAG_RW | + CTLFLAG_MPSAFE, &adjkerntz, 0, sysctl_machdep_adjkerntz, "I", "Local offset from UTC in seconds"); static int ct_debug; diff --git a/sys/kern/subr_rtc.c b/sys/kern/subr_rtc.c index 5d4167d..dbad36d 100644 --- a/sys/kern/subr_rtc.c +++ b/sys/kern/subr_rtc.c @@ -62,6 +62,8 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/bus.h> #include <sys/clock.h> +#include <sys/lock.h> +#include <sys/mutex.h> #include <sys/sysctl.h> #ifdef FFCLOCK #include <sys/timeffc.h> @@ -73,6 +75,8 @@ __FBSDID("$FreeBSD$"); static device_t clock_dev = NULL; static long clock_res; static struct timespec clock_adj; +static struct mtx resettodr_lock; +MTX_SYSINIT(resettodr_init, &resettodr_lock, "tod2rl", MTX_DEF); /* XXX: should be kern. now, it's no longer machdep. */ static int disable_rtc_set; @@ -168,11 +172,14 @@ resettodr(void) if (disable_rtc_set || clock_dev == NULL) return; + mtx_lock(&resettodr_lock); getnanotime(&ts); timespecadd(&ts, &clock_adj); ts.tv_sec -= utc_offset(); /* XXX: We should really set all registered RTCs */ - if ((error = CLOCK_SETTIME(clock_dev, &ts)) != 0) + error = CLOCK_SETTIME(clock_dev, &ts); + mtx_unlock(&resettodr_lock); + if (error != 0) printf("warning: clock_settime failed (%d), time-of-day clock " "not adjusted to system time\n", error); } |