summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-06-28 16:42:40 +0000
committerkib <kib@FreeBSD.org>2016-06-28 16:42:40 +0000
commit8543a46c508fbf946ee8bf0b83a54ca61e03b257 (patch)
tree7d5e3aa0ee656d6dd61d8cf6637216816bb15a34 /sys/kern
parentfb3ea99e649137928787bf59dba50efdce32c30b (diff)
downloadFreeBSD-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.c4
-rw-r--r--sys/kern/subr_rtc.c9
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);
}
OpenPOWER on IntegriCloud