diff options
| author | ad <ad@NetBSD.org> | 2008-04-21 12:56:30 +0000 |
|---|---|---|
| committer | ad <ad@NetBSD.org> | 2008-04-21 12:56:30 +0000 |
| commit | a2249ef75cbe2acbcf5e0d0a53dcbfc6ebe40783 (patch) | |
| tree | 6a5a7871a7ca8808cd6013a6b8082dffd5db0da2 /sys | |
| parent | 45e89afb6fdd63c527033ba5c11249e873d549f1 (diff) | |
Make ntp, pmc, reboot, sysarch, time syscalls MPSAFE.
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/arch/evbarm/dev/plcom.c | 20 | ||||
| -rw-r--r-- | sys/arch/x86/x86/sys_machdep.c | 14 | ||||
| -rw-r--r-- | sys/dev/ic/com.c | 12 | ||||
| -rw-r--r-- | sys/dev/ic/z8530tty.c | 12 | ||||
| -rw-r--r-- | sys/dev/ppbus/pps_ppbus.c | 21 | ||||
| -rw-r--r-- | sys/kern/kern_ntptime.c | 70 | ||||
| -rw-r--r-- | sys/kern/kern_tc.c | 70 | ||||
| -rw-r--r-- | sys/kern/kern_time.c | 17 | ||||
| -rw-r--r-- | sys/kern/kern_xxx.c | 6 | ||||
| -rw-r--r-- | sys/kern/sys_pmc.c | 31 | ||||
| -rw-r--r-- | sys/kern/syscalls.master | 20 | ||||
| -rw-r--r-- | sys/sys/timepps.h | 6 | ||||
| -rw-r--r-- | sys/sys/timex.h | 19 |
13 files changed, 229 insertions, 89 deletions
diff --git a/sys/arch/evbarm/dev/plcom.c b/sys/arch/evbarm/dev/plcom.c index c7cf0e90ed0..4e8eec99e15 100644 --- a/sys/arch/evbarm/dev/plcom.c +++ b/sys/arch/evbarm/dev/plcom.c @@ -1,4 +1,4 @@ -/* $NetBSD: plcom.c,v 1.25 2008/01/05 12:40:34 ad Exp $ */ +/* $NetBSD: plcom.c,v 1.26 2008/04/21 12:56:30 ad Exp $ */ /*- * Copyright (c) 2001 ARM Ltd @@ -101,7 +101,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.25 2008/01/05 12:40:34 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.26 2008/04/21 12:56:30 ad Exp $"); #include "opt_plcom.h" #include "opt_ddb.h" @@ -557,8 +557,10 @@ plcom_shutdown(struct plcom_softc *sc) plcom_break(sc, 0); /* Turn off PPS capture on last close. */ + mutex_spin_enter(&timecounter_lock); sc->sc_ppsmask = 0; sc->ppsparam.mode = 0; + mutex_spin_exit(&timecounter_lock); /* * Hang up if necessary. Wait a bit, so the other side has time to @@ -659,8 +661,11 @@ plcomopen(dev_t dev, int flag, int mode, struct lwp *l) sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, plcom_fr); /* Clear PPS capture state on first open. */ + + mutex_spin_enter(&timecounter_lock); sc->sc_ppsmask = 0; sc->ppsparam.mode = 0; + mutex_spin_exit(&timecounter_lock); PLCOM_UNLOCK(sc); splx(s2); @@ -889,7 +894,9 @@ plcomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) case PPS_IOC_GETPARAMS: { pps_params_t *pp; pp = (pps_params_t *)data; + mutex_spin_enter(&timecounter_lock); *pp = sc->ppsparam; + mutex_spin_exit(&timecounter_lock); break; } @@ -897,8 +904,10 @@ plcomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) pps_params_t *pp; int mode; pp = (pps_params_t *)data; + mutex_spin_enter(&timecounter_lock); if (pp->mode & ~ppscap) { error = EINVAL; + mutex_spin_exit(&timecounter_lock); break; } sc->ppsparam = *pp; @@ -943,6 +952,7 @@ plcomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) error = EINVAL; break; } + mutex_spin_exit(&timecounter_lock); break; } @@ -953,7 +963,9 @@ plcomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) case PPS_IOC_FETCH: { pps_info_t *pi; pi = (pps_info_t *)data; + mutex_spin_enter(&timecounter_lock); *pi = sc->ppsinfo; + mutex_spin_exit(&timecounter_lock); break; } @@ -963,6 +975,7 @@ plcomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) * rising edge as the on-the-second signal. * The old API has no way to specify PPS polarity. */ + mutex_spin_enter(&timecounter_lock); sc->sc_ppsmask = MSR_DCD; #ifndef PPS_TRAILING_EDGE sc->sc_ppsassert = MSR_DCD; @@ -975,6 +988,7 @@ plcomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) TIMESPEC_TO_TIMEVAL((struct timeval *)data, &sc->ppsinfo.clear_timestamp); #endif + mutex_spin_exit(&timecounter_lock); break; default: @@ -1813,6 +1827,7 @@ plcomintr(void *arg) */ if (delta & sc->sc_ppsmask) { struct timeval tv; + mutex_spin_enter(&timecounter_lock); if ((msr & sc->sc_ppsmask) == sc->sc_ppsassert) { /* XXX nanotime() */ microtime(&tv); @@ -1849,6 +1864,7 @@ plcomintr(void *arg) sc->ppsinfo.clear_sequence++; sc->ppsinfo.current_mode = sc->ppsparam.mode; } + mutex_spin_exit(&timecounter_lock); } /* diff --git a/sys/arch/x86/x86/sys_machdep.c b/sys/arch/x86/x86/sys_machdep.c index a13602d3cec..b45adec1bda 100644 --- a/sys/arch/x86/x86/sys_machdep.c +++ b/sys/arch/x86/x86/sys_machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: sys_machdep.c,v 1.11 2008/01/28 19:57:43 ad Exp $ */ +/* $NetBSD: sys_machdep.c,v 1.12 2008/04/21 12:56:31 ad Exp $ */ /*- * Copyright (c) 1998, 2007 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.11 2008/01/28 19:57:43 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.12 2008/04/21 12:56:31 ad Exp $"); #include "opt_compat_netbsd.h" #include "opt_mtrr.h" @@ -585,7 +585,9 @@ x86_get_mtrr(struct lwp *l, void *args, register_t *retval) if (error != 0) return error; + KERNEL_LOCK(1, NULL); error = mtrr_get(ua.mtrrp, &n, l->l_proc, MTRR_GETSET_USER); + KERNEL_UNLOCK_ONE(NULL); copyout(&n, ua.n, sizeof (int)); @@ -618,9 +620,11 @@ x86_set_mtrr(struct lwp *l, void *args, register_t *retval) if (error != 0) return error; + KERNEL_LOCK(1, NULL); error = mtrr_set(ua.mtrrp, &n, l->l_proc, MTRR_GETSET_USER); if (n != 0) mtrr_commit(); + KERNEL_UNLOCK_ONE(NULL); copyout(&n, ua.n, sizeof n); @@ -744,15 +748,21 @@ sys_sysarch(struct lwp *l, const struct sys_sysarch_args *uap, register_t *retva #ifdef PERFCTRS case X86_PMC_INFO: + KERNEL_LOCK(1, NULL); error = pmc_info(l, SCARG(uap, parms), retval); + KERNEL_UNLOCK_ONE(NULL); break; case X86_PMC_STARTSTOP: + KERNEL_LOCK(1, NULL); error = pmc_startstop(l, SCARG(uap, parms), retval); + KERNEL_UNLOCK_ONE(NULL); break; case X86_PMC_READ: + KERNEL_LOCK(1, NULL); error = pmc_read(l, SCARG(uap, parms), retval); + KERNEL_UNLOCK_ONE(NULL); break; #endif diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c index b3bbf8fca91..bdf4b69f6bb 100644 --- a/sys/dev/ic/com.c +++ b/sys/dev/ic/com.c @@ -1,4 +1,4 @@ -/* $NetBSD: com.c,v 1.278 2008/04/11 12:45:08 tsutsui Exp $ */ +/* $NetBSD: com.c,v 1.279 2008/04/21 12:56:31 ad Exp $ */ /*- * Copyright (c) 1998, 1999, 2004, 2008 The NetBSD Foundation, Inc. @@ -73,7 +73,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.278 2008/04/11 12:45:08 tsutsui Exp $"); +__KERNEL_RCSID(0, "$NetBSD: com.c,v 1.279 2008/04/21 12:56:31 ad Exp $"); #include "opt_com.h" #include "opt_ddb.h" @@ -788,9 +788,11 @@ comopen(dev_t dev, int flag, int mode, struct lwp *l) sc->sc_msr = CSR_READ_1(&sc->sc_regs, COM_REG_MSR); /* Clear PPS capture state on first open. */ + mutex_spin_enter(&timecounter_lock); memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state)); sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; pps_init(&sc->sc_pps_state); + mutex_spin_exit(&timecounter_lock); mutex_spin_exit(&sc->sc_lock); @@ -1032,10 +1034,13 @@ comioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) #ifdef PPS_SYNC case PPS_IOC_KCBIND: #endif + mutex_spin_enter(&timecounter_lock); error = pps_ioctl(cmd, data, &sc->sc_pps_state); + mutex_spin_exit(&timecounter_lock); break; case TIOCDCDTIMESTAMP: /* XXX old, overloaded API used by xntpd v3 */ + mutex_spin_enter(&timecounter_lock); #ifndef PPS_TRAILING_EDGE TIMESPEC_TO_TIMEVAL((struct timeval *)data, &sc->sc_pps_state.ppsinfo.assert_timestamp); @@ -1043,6 +1048,7 @@ comioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) TIMESPEC_TO_TIMEVAL((struct timeval *)data, &sc->sc_pps_state.ppsinfo.clear_timestamp); #endif + mutex_spin_exit(&timecounter_lock); break; default: @@ -1908,11 +1914,13 @@ again: do { sc->sc_msr = msr; if ((sc->sc_pps_state.ppsparam.mode & PPS_CAPTUREBOTH) && (delta & MSR_DCD)) { + mutex_spin_enter(&timecounter_lock); pps_capture(&sc->sc_pps_state); pps_event(&sc->sc_pps_state, (msr & MSR_DCD) ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR); + mutex_spin_exit(&timecounter_lock); } /* diff --git a/sys/dev/ic/z8530tty.c b/sys/dev/ic/z8530tty.c index a5e8457dbe9..eb97c987624 100644 --- a/sys/dev/ic/z8530tty.c +++ b/sys/dev/ic/z8530tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: z8530tty.c,v 1.122 2008/03/29 19:15:36 tsutsui Exp $ */ +/* $NetBSD: z8530tty.c,v 1.123 2008/04/21 12:56:31 ad Exp $ */ /*- * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999 @@ -137,7 +137,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: z8530tty.c,v 1.122 2008/03/29 19:15:36 tsutsui Exp $"); +__KERNEL_RCSID(0, "$NetBSD: z8530tty.c,v 1.123 2008/04/21 12:56:31 ad Exp $"); #include "opt_kgdb.h" #include "opt_ntp.h" @@ -600,11 +600,13 @@ zsopen(dev_t dev, int flags, int mode, struct lwp *l) SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE); /* Clear PPS capture state on first open. */ + mutex_spin_enter(&timecounter_lock); zst->zst_ppsmask = 0; memset(&zst->zst_pps_state, 0, sizeof(zst->zst_pps_state)); zst->zst_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; pps_init(&zst->zst_pps_state); + mutex_spin_exit(&timecounter_lock); mutex_spin_exit(&cs->cs_lock); @@ -821,11 +823,13 @@ zsioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) #ifdef PPS_SYNC case PPS_IOC_KCBIND: #endif + mutex_spin_enter(&timecounter_lock); error = pps_ioctl(cmd, data, &zst->zst_pps_state); if (zst->zst_pps_state.ppsparam.mode & PPS_CAPTUREBOTH) zst->zst_ppsmask = ZSRR0_DCD; else zst->zst_ppsmask = 0; + mutex_spin_exit(&timecounter_lock); break; case TIOCDCDTIMESTAMP: /* XXX old, overloaded API used by xntpd v3 */ @@ -833,6 +837,7 @@ zsioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) error = EINVAL; break; } + mutex_spin_enter(&timecounter_lock); #ifndef PPS_TRAILING_EDGE TIMESPEC_TO_TIMEVAL((struct timeval *)data, &zst->zst_pps_state.ppsinfo.assert_timestamp); @@ -840,6 +845,7 @@ zsioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) TIMESPEC_TO_TIMEVAL((struct timeval *)data, &zst->zst_pps_state.ppsinfo.clear_timestamp); #endif + mutex_spin_exit(&timecounter_lock); /* * Now update interrupts. */ @@ -1484,11 +1490,13 @@ zstty_stint(struct zs_chanstate *cs, int force) if (ISSET(delta, zst->zst_ppsmask)) { if (zst->zst_pps_state.ppsparam.mode & PPS_CAPTUREBOTH) { + mutex_spin_enter(&timecounter_lock); pps_capture(&zst->zst_pps_state); pps_event(&zst->zst_pps_state, (ISSET(cs->cs_rr0, zst->zst_ppsmask)) ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR); + mutex_spin_exit(&timecounter_lock); } } diff --git a/sys/dev/ppbus/pps_ppbus.c b/sys/dev/ppbus/pps_ppbus.c index 7a45f03e0dd..26b28cbfce0 100644 --- a/sys/dev/ppbus/pps_ppbus.c +++ b/sys/dev/ppbus/pps_ppbus.c @@ -1,4 +1,4 @@ -/* $NetBSD: pps_ppbus.c,v 1.12 2008/04/16 09:39:01 cegger Exp $ */ +/* $NetBSD: pps_ppbus.c,v 1.13 2008/04/21 12:56:31 ad Exp $ */ /* * ported to timecounters by Frank Kardel 2006 @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pps_ppbus.c,v 1.12 2008/04/16 09:39:01 cegger Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pps_ppbus.c,v 1.13 2008/04/21 12:56:31 ad Exp $"); #include "opt_ntp.h" @@ -122,11 +122,14 @@ ppsopen(dev_t dev, int flags, int fmt, struct lwp *l) ppbus_set_mode(sc->ppbus, PPBUS_PS2, 0); ppbus_wctr(sc->ppbus, IRQENABLE | PCD | nINIT | SELECTIN); + mutex_spin_enter(&timecounter_lock); memset((void *)&sc->pps_state, 0, sizeof(sc->pps_state)); sc->pps_state.ppscap = PPS_CAPTUREASSERT; pps_init(&sc->pps_state); + mutex_spin_exit(&timecounter_lock); sc->busy = 1; + return (0); } @@ -137,7 +140,9 @@ ppsclose(dev_t dev, int flags, int fmt, struct lwp *l) device_t ppbus = sc->ppbus; sc->busy = 0; + mutex_spin_enter(&timecounter_lock); sc->pps_state.ppsparam.mode = 0; + mutex_spin_exit(&timecounter_lock); ppbus_wdtr(ppbus, 0); ppbus_wctr(ppbus, 0); @@ -154,18 +159,18 @@ ppsintr(void *arg) struct pps_softc *sc = arg; device_t ppbus = sc->ppbus; + mutex_spin_enter(&timecounter_lock); pps_capture(&sc->pps_state); - - if (!(ppbus_rstr(ppbus) & nACK)) + if (!(ppbus_rstr(ppbus) & nACK)) { + mutex_spin_exit(&timecounter_lock); return; - + } if (sc->pps_state.ppsparam.mode & PPS_ECHOASSERT) ppbus_wctr(ppbus, IRQENABLE | AUTOFEED); - pps_event(&sc->pps_state, PPS_CAPTUREASSERT); - if (sc->pps_state.ppsparam.mode & PPS_ECHOASSERT) ppbus_wctr(ppbus, IRQENABLE); + mutex_spin_exit(&timecounter_lock); } static int @@ -184,7 +189,9 @@ ppsioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) #ifdef PPS_SYNC case PPS_IOC_KCBIND: #endif + mutex_spin_enter(&timecounter_lock); error = pps_ioctl(cmd, data, &sc->pps_state); + mutex_spin_exit(&timecounter_lock); break; default: diff --git a/sys/kern/kern_ntptime.c b/sys/kern/kern_ntptime.c index 4fcfd626f57..3518ea6e8d1 100644 --- a/sys/kern/kern_ntptime.c +++ b/sys/kern/kern_ntptime.c @@ -1,4 +1,37 @@ -/* $NetBSD: kern_ntptime.c,v 1.47 2008/02/27 19:55:59 matt Exp $ */ +/* $NetBSD: kern_ntptime.c,v 1.48 2008/04/21 12:56:31 ad Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ /*- *********************************************************************** @@ -34,7 +67,7 @@ #include <sys/cdefs.h> /* __FBSDID("$FreeBSD: src/sys/kern/kern_ntptime.c,v 1.59 2005/05/28 14:34:41 rwatson Exp $"); */ -__KERNEL_RCSID(0, "$NetBSD: kern_ntptime.c,v 1.47 2008/02/27 19:55:59 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_ntptime.c,v 1.48 2008/04/21 12:56:31 ad Exp $"); #include "opt_ntp.h" #include "opt_compat_netbsd.h" @@ -46,17 +79,16 @@ __KERNEL_RCSID(0, "$NetBSD: kern_ntptime.c,v 1.47 2008/02/27 19:55:59 matt Exp $ #include <sys/proc.h> #include <sys/sysctl.h> #include <sys/timex.h> -#ifdef COMPAT_30 -#include <compat/sys/timex.h> -#endif #include <sys/vnode.h> #include <sys/kauth.h> - #include <sys/mount.h> #include <sys/syscallargs.h> - #include <sys/cpu.h> +#ifdef COMPAT_30 +#include <compat/sys/timex.h> +#endif + /* * Single-precision macros for 64-bit machines */ @@ -215,11 +247,14 @@ static void hardupdate(long offset); void ntp_gettime(struct ntptimeval *ntv) { + + mutex_spin_enter(&timecounter_lock); nanotime(&ntv->time); ntv->maxerror = time_maxerror; ntv->esterror = time_esterror; ntv->tai = time_tai; ntv->time_state = time_state; + mutex_spin_exit(&timecounter_lock); } /* ARGSUSED */ @@ -258,7 +293,6 @@ ntp_adjtime1(struct timex *ntv) { long freq; int modes; - int s; /* * Update selected clock variables - only the superuser can @@ -269,11 +303,11 @@ ntp_adjtime1(struct timex *ntv) * the STA_PLL bit in the status word is cleared, the state and * status words are reset to the initial values at boot. */ + mutex_spin_enter(&timecounter_lock); modes = ntv->modes; if (modes != 0) /* We need to save the system time during shutdown */ time_adjusted |= 2; - s = splclock(); if (modes & MOD_MAXERROR) time_maxerror = ntv->maxerror; if (modes & MOD_ESTERROR) @@ -374,7 +408,7 @@ ntp_adjtime1(struct timex *ntv) ntv->jitcnt = pps_jitcnt; ntv->stbcnt = pps_stbcnt; #endif /* PPS_SYNC */ - splx(s); + mutex_spin_exit(&timecounter_lock); } #endif /* NTP */ @@ -392,6 +426,8 @@ ntp_update_second(int64_t *adjustment, time_t *newsec) int tickrate; l_fp ftemp; /* 32/64-bit temporary */ + KASSERT(mutex_owned(&timecounter_lock)); + #ifdef NTP /* @@ -584,6 +620,8 @@ hardupdate(long offset) long mtemp; l_fp ftemp; + KASSERT(mutex_owned(&timecounter_lock)); + /* * Select how the phase is to be controlled and from which * source. If the PPS signal is present and enabled to @@ -666,6 +704,8 @@ hardpps(struct timespec *tsp, /* time at PPS */ long u_sec, u_nsec, v_nsec; /* temps */ l_fp ftemp; + KASSERT(mutex_owned(&timecounter_lock)); + /* * The signal is first processed by a range gate and frequency * discriminator. The range gate rejects noise spikes outside @@ -849,6 +889,8 @@ hardpps(struct timespec *tsp, /* time at PPS */ int ntp_timestatus(void) { + int rv; + /* * Status word error decode. If any of these conditions * occur, an error is returned, instead of the status @@ -858,6 +900,7 @@ ntp_timestatus(void) * * Hardware or software error */ + mutex_spin_enter(&timecounter_lock); if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) || /* @@ -880,9 +923,12 @@ ntp_timestatus(void) */ (time_status & STA_PPSFREQ && time_status & (STA_PPSWANDER | STA_PPSERROR))) - return (TIME_ERROR); + rv = TIME_ERROR; else - return (time_state); + rv = time_state; + mutex_spin_exit(&timecounter_lock); + + return rv; } /*ARGSUSED*/ diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index 25847ce0522..80ee2625ad0 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -1,4 +1,37 @@ -/* $NetBSD: kern_tc.c,v 1.32 2008/02/10 13:56:17 ad Exp $ */ +/* $NetBSD: kern_tc.c,v 1.33 2008/04/21 12:56:31 ad Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ /*- * ---------------------------------------------------------------------------- @@ -11,7 +44,7 @@ #include <sys/cdefs.h> /* __FBSDID("$FreeBSD: src/sys/kern/kern_tc.c,v 1.166 2005/09/19 22:16:31 andre Exp $"); */ -__KERNEL_RCSID(0, "$NetBSD: kern_tc.c,v 1.32 2008/02/10 13:56:17 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_tc.c,v 1.33 2008/04/21 12:56:31 ad Exp $"); #include "opt_ntp.h" @@ -99,7 +132,7 @@ static struct bintime timebasebin; static int timestepwarnings; extern kmutex_t time_lock; -static kmutex_t tc_windup_lock; +kmutex_t timecounter_lock; #ifdef __FreeBSD__ SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW, @@ -448,7 +481,7 @@ tc_init(struct timecounter *tc) } mutex_enter(&time_lock); - mutex_spin_enter(&tc_windup_lock); + mutex_spin_enter(&timecounter_lock); tc->tc_next = timecounters; timecounters = tc; /* @@ -464,7 +497,7 @@ tc_init(struct timecounter *tc) timecounter = tc; tc_windup(); } - mutex_spin_exit(&tc_windup_lock); + mutex_spin_exit(&timecounter_lock); mutex_exit(&time_lock); } @@ -502,12 +535,12 @@ tc_detach(struct timecounter *target) else if (tc->tc_frequency > best->tc_frequency) best = tc; } - mutex_spin_enter(&tc_windup_lock); + mutex_spin_enter(&timecounter_lock); (void)best->tc_get_timecount(best); (void)best->tc_get_timecount(best); timecounter = best; tc_windup(); - mutex_spin_exit(&tc_windup_lock); + mutex_spin_exit(&timecounter_lock); out: mutex_exit(&time_lock); return rc; @@ -531,7 +564,7 @@ tc_setclock(struct timespec *ts) struct timespec ts2; struct bintime bt, bt2; - mutex_spin_enter(&tc_windup_lock); + mutex_spin_enter(&timecounter_lock); TC_COUNT(nsetclock); binuptime(&bt2); timespec2bintime(ts, &bt); @@ -539,7 +572,7 @@ tc_setclock(struct timespec *ts) bintime_add(&bt2, &timebasebin); timebasebin = bt; tc_windup(); - mutex_spin_exit(&tc_windup_lock); + mutex_spin_exit(&timecounter_lock); if (timestepwarnings) { bintime2timespec(&bt2, &ts2); @@ -564,7 +597,7 @@ tc_windup(void) int i, s_update; time_t t; - KASSERT(mutex_owned(&tc_windup_lock)); + KASSERT(mutex_owned(&timecounter_lock)); s_update = 0; @@ -714,6 +747,8 @@ pps_ioctl(u_long cmd, void *data, struct pps_state *pps) int *epi; #endif + KASSERT(mutex_owned(&timecounter_lock)); + KASSERT(pps != NULL); /* XXX ("NULL pps pointer in pps_ioctl") */ switch (cmd) { case PPS_IOC_CREATE: @@ -758,6 +793,9 @@ pps_ioctl(u_long cmd, void *data, struct pps_state *pps) void pps_init(struct pps_state *pps) { + + KASSERT(mutex_owned(&timecounter_lock)); + pps->ppscap |= PPS_TSFMT_TSPEC; if (pps->ppscap & PPS_CAPTUREASSERT) pps->ppscap |= PPS_OFFSETASSERT; @@ -770,7 +808,9 @@ pps_capture(struct pps_state *pps) { struct timehands *th; - KASSERT(pps != NULL); /* XXX ("NULL pps pointer in pps_capture") */ + KASSERT(mutex_owned(&timecounter_lock)); + KASSERT(pps != NULL); + th = timehands; pps->capgen = th->th_generation; pps->capth = th; @@ -788,6 +828,8 @@ pps_event(struct pps_state *pps, int event) int foff, fhard; pps_seq_t *pseq; + KASSERT(mutex_owned(&timecounter_lock)); + KASSERT(pps != NULL); /* XXX ("NULL pps pointer in pps_event") */ /* If the timecounter was wound up underneath us, bail out. */ if (pps->capgen == 0 || pps->capgen != pps->capth->th_generation) @@ -885,9 +927,9 @@ tc_ticktock(void) if (++count < tc_tick) return; count = 0; - mutex_spin_enter(&tc_windup_lock); + mutex_spin_enter(&timecounter_lock); tc_windup(); - mutex_spin_exit(&tc_windup_lock); + mutex_spin_exit(&timecounter_lock); } void @@ -895,7 +937,7 @@ inittimecounter(void) { u_int p; - mutex_init(&tc_windup_lock, MUTEX_DEFAULT, IPL_SCHED); + mutex_init(&timecounter_lock, MUTEX_DEFAULT, IPL_SCHED); /* * Set the initial timeout to diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 3c7f0c3847e..3e988bfab4d 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_time.c,v 1.142 2008/04/21 00:13:46 ad Exp $ */ +/* $NetBSD: kern_time.c,v 1.143 2008/04/21 12:56:31 ad Exp $ */ /*- * Copyright (c) 2000, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.142 2008/04/21 00:13:46 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.143 2008/04/21 12:56:31 ad Exp $"); #include <sys/param.h> #include <sys/resourcevar.h> @@ -79,15 +79,14 @@ __KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.142 2008/04/21 00:13:46 ad Exp $"); #include <sys/signalvar.h> #include <sys/syslog.h> #include <sys/timetc.h> +#include <sys/timex.h> #include <sys/kauth.h> - #include <sys/mount.h> #include <sys/syscallargs.h> +#include <sys/cpu.h> #include <uvm/uvm_extern.h> -#include <sys/cpu.h> - static void timer_intr(void *); static void itimerfire(struct ptimer *); static void itimerfree(struct ptimers *, int); @@ -464,8 +463,10 @@ adjtime1(const struct timeval *delta, struct timeval *olddelta, struct proc *p) extern int64_t time_adjtime; /* in kern_ntptime.c */ if (olddelta) { + mutex_spin_enter(&timecounter_lock); atv.tv_sec = time_adjtime / 1000000; atv.tv_usec = time_adjtime % 1000000; + mutex_spin_exit(&timecounter_lock); if (atv.tv_usec < 0) { atv.tv_usec += 1000000; atv.tv_sec--; @@ -480,12 +481,14 @@ adjtime1(const struct timeval *delta, struct timeval *olddelta, struct proc *p) if (error) return (error); + mutex_spin_enter(&timecounter_lock); time_adjtime = (int64_t)atv.tv_sec * 1000000 + atv.tv_usec; - - if (time_adjtime) + if (time_adjtime) { /* We need to save the system time during shutdown */ time_adjusted |= 1; + } + mutex_spin_exit(&timecounter_lock); } return error; diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c index bade39a0473..3f4c0c60d8f 100644 --- a/sys/kern/kern_xxx.c +++ b/sys/kern/kern_xxx.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_xxx.c,v 1.68 2008/01/05 12:30:47 dsl Exp $ */ +/* $NetBSD: kern_xxx.c,v 1.69 2008/04/21 12:56:31 ad Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_xxx.c,v 1.68 2008/01/05 12:30:47 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_xxx.c,v 1.69 2008/04/21 12:56:31 ad Exp $"); #include "opt_syscall_debug.h" @@ -74,7 +74,9 @@ sys_reboot(struct lwp *l, const struct sys_reboot_args *uap, register_t *retval) /* * Not all ports use the bootstr currently. */ + KERNEL_LOCK(1, NULL); cpu_reboot(SCARG(uap, opt), bootstr); + KERNEL_UNLOCK_ONE(NULL); return (0); } diff --git a/sys/kern/sys_pmc.c b/sys/kern/sys_pmc.c index ffdad2ea259..0099c5c5e9e 100644 --- a/sys/kern/sys_pmc.c +++ b/sys/kern/sys_pmc.c @@ -1,4 +1,4 @@ -/* $NetBSD: sys_pmc.c,v 1.9 2007/12/20 23:03:11 dsl Exp $ */ +/* $NetBSD: sys_pmc.c,v 1.10 2008/04/21 12:56:31 ad Exp $ */ /* * Copyright (c) 2002 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sys_pmc.c,v 1.9 2007/12/20 23:03:11 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_pmc.c,v 1.10 2008/04/21 12:56:31 ad Exp $"); #include "opt_perfctrs.h" @@ -73,25 +73,23 @@ sys_pmc_control(struct lwp *l, const struct sys_pmc_control_args *uap, register_ ctr = SCARG(uap, ctr); operation = SCARG(uap, op); + KERNEL_LOCK(1, NULL); switch (operation) { case PMC_OP_START: if (!pmc_counter_isconfigured(l->l_proc, ctr)) { - return ENXIO; + error = ENXIO; + } else if (pmc_counter_isrunning(l->l_proc, ctr)) { + error = EINPROGRESS; + } else { + pmc_enable_counter(l->l_proc, ctr); } - if (pmc_counter_isrunning(l->l_proc, ctr)) { - return EINPROGRESS; - } - pmc_enable_counter(l->l_proc, ctr); break; case PMC_OP_STOP: if (!pmc_counter_isconfigured(l->l_proc, ctr)) { - return ENXIO; - } - if (!pmc_counter_isrunning(l->l_proc, ctr)) { - /* Nothing to do */ - return 0; + error = ENXIO; + } else if (pmc_counter_isrunning(l->l_proc, ctr)) { + pmc_disable_counter(l->l_proc, ctr); } - pmc_disable_counter(l->l_proc, ctr); break; case PMC_OP_CONFIGURE: args = SCARG(uap, args); @@ -119,6 +117,7 @@ sys_pmc_control(struct lwp *l, const struct sys_pmc_control_args *uap, register_ error = EINVAL; break; } + KERNEL_UNLOCK_ONE(NULL); return error; #endif } @@ -142,8 +141,8 @@ sys_pmc_get_info(struct lwp *l, const struct sys_pmc_get_info_args *uap, registe request = SCARG(uap, op); args = SCARG(uap, args); + KERNEL_LOCK(1, NULL); nctrs = pmc_get_num_counters(); - switch (request) { case PMC_INFO_NCOUNTERS: /* args should be (int *) */ error = copyout(&nctrs, args, sizeof(int)); @@ -159,7 +158,8 @@ sys_pmc_get_info(struct lwp *l, const struct sys_pmc_get_info_args *uap, registe /*FALLTHROUGH*/ case PMC_INFO_COUNTER_VALUE: if (ctr < 0 || ctr >= nctrs) { - return EINVAL; + error = EINVAL; + break; } error = pmc_get_counter_value(l->l_proc, ctr, flags, &val); if (error == 0) { @@ -170,6 +170,7 @@ sys_pmc_get_info(struct lwp *l, const struct sys_pmc_get_info_args *uap, registe error = EINVAL; break; } + KERNEL_UNLOCK_ONE(NULL); return error; #endif } diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 43d162a8b0c..c4cb9315f00 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.198 2008/04/21 11:45:34 ad Exp $ + $NetBSD: syscalls.master,v 1.199 2008/04/21 12:56:31 ad Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -158,7 +158,7 @@ struct sigaltstack13 *oss); } sigaltstack13 54 STD MPSAFE { int sys_ioctl(int fd, \ u_long com, ... void *data); } -55 COMPAT_12 { int sys_reboot(int opt); } oreboot +55 COMPAT_12 MPSAFE { int sys_reboot(int opt); } oreboot 56 STD MPSAFE { int sys_revoke(const char *path); } 57 STD MPSAFE RUMP { int sys_symlink(const char *path, \ const char *link); } @@ -283,7 +283,7 @@ 138 STD MPSAFE { int sys_utimes(const char *path, \ const struct timeval *tptr); } 139 OBSOL 4.2 sigreturn -140 STD { int sys_adjtime(const struct timeval *delta, \ +140 STD MPSAFE { int sys_adjtime(const struct timeval *delta, \ struct timeval *olddelta); } 141 COMPAT_43 { int sys_getpeername(int fdes, void *asa, \ int *alen); } ogetpeername @@ -328,7 +328,7 @@ 163 COMPAT_09 MPSAFE { int sys_setdomainname(char *domainname, int len); } \ osetdomainname 164 COMPAT_09 MPSAFE { int sys_uname(struct outsname *name); } ouname -165 STD { int sys_sysarch(int op, void *parms); } +165 STD MPSAFE { int sys_sysarch(int op, void *parms); } 166 UNIMPL 167 UNIMPL 168 UNIMPL @@ -359,9 +359,9 @@ 174 STD MPSAFE { ssize_t sys_pwrite(int fd, const void *buf, \ size_t nbyte, int pad, off_t offset); } ; For some reason, ntp_gettime doesn't want to raise SIGSYS when it's excluded. -175 COMPAT_30 { int sys_ntp_gettime(struct ntptimeval30 *ntvp); } +175 COMPAT_30 MPSAFE { int sys_ntp_gettime(struct ntptimeval30 *ntvp); } #if defined(NTP) || !defined(_KERNEL) -176 STD { int sys_ntp_adjtime(struct timex *tp); } +176 STD MPSAFE { int sys_ntp_adjtime(struct timex *tp); } #else 176 EXCL ntp_adjtime #endif @@ -420,7 +420,7 @@ 206 STD MPSAFE { int sys_futimes(int fd, \ const struct timeval *tptr); } 207 STD MPSAFE { pid_t sys_getpgid(pid_t pid); } -208 STD { int sys_reboot(int opt, char *bootstr); } +208 STD MPSAFE { int sys_reboot(int opt, char *bootstr); } 209 STD MPSAFE { int sys_poll(struct pollfd *fds, u_int nfds, \ int timeout); } ; @@ -688,8 +688,8 @@ const struct sigaction *nsa, \ struct sigaction *osa, \ const void *tramp, int vers); } -341 STD { int sys_pmc_get_info(int ctr, int op, void *args); } -342 STD { int sys_pmc_control(int ctr, int op, void *args); } +341 STD MPSAFE { int sys_pmc_get_info(int ctr, int op, void *args); } +342 STD MPSAFE { int sys_pmc_control(int ctr, int op, void *args); } 343 STD MPSAFE { int sys_rasctl(void *addr, size_t len, int op); } 344 STD MPSAFE { int sys_kqueue(void); } 345 STD MPSAFE { int sys_kevent(int fd, \ @@ -794,7 +794,7 @@ 391 IGNORED old posix_fadvise 392 COMPAT_30 MPSAFE { int sys___fhstat30(const struct compat_30_fhandle \ *fhp, struct stat *sb); } -393 STD { int sys___ntp_gettime30(struct ntptimeval *ntvp); } +393 STD MPSAFE { int sys___ntp_gettime30(struct ntptimeval *ntvp); } 394 STD { int sys___socket30(int domain, int type, int protocol); } 395 STD MPSAFE { int sys___getfh30(const char *fname, void *fhp, \ size_t *fh_size); } diff --git a/sys/sys/timepps.h b/sys/sys/timepps.h index ce4c2c2347c..cd56827b1a1 100644 --- a/sys/sys/timepps.h +++ b/sys/sys/timepps.h @@ -1,4 +1,4 @@ -/* $NetBSD: timepps.h,v 1.17 2008/01/20 18:09:13 joerg Exp $ */ +/* $NetBSD: timepps.h,v 1.18 2008/04/21 12:56:31 ad Exp $ */ /* * Copyright (c) 1998 Jonathan Stone @@ -131,6 +131,10 @@ typedef struct { #ifdef _KERNEL +#include <sys/mutex.h> + +extern kmutex_t timecounter_lock; + struct pps_state { /* Capture information. */ struct timehands *capth; diff --git a/sys/sys/timex.h b/sys/sys/timex.h index 3d2bf641937..724afb993c4 100644 --- a/sys/sys/timex.h +++ b/sys/sys/timex.h @@ -1,4 +1,4 @@ -/* $NetBSD: timex.h,v 1.13 2008/01/20 18:09:13 joerg Exp $ */ +/* $NetBSD: timex.h,v 1.14 2008/04/21 12:56:31 ad Exp $ */ /*- *********************************************************************** @@ -95,13 +95,12 @@ * STA_NANO bit in the status word. See the description below for * further information. */ + #ifndef _SYS_TIMEX_H_ #define _SYS_TIMEX_H_ 1 #define NTP_API 4 /* NTP API version */ -#ifndef MSDOS /* Microsoft specific */ #include <sys/syscall.h> -#endif /* MSDOS */ /* * The following defines establish the performance envelope of the @@ -220,30 +219,24 @@ struct timex { long stbcnt; /* stability limit exceeded (ro) */ }; -#if defined(__FreeBSD__) || defined(__NetBSD__) - #ifdef _KERNEL +#include <sys/mutex.h> + void ntp_update_second(int64_t *adjustment, time_t *newsec); -#ifdef __NetBSD__ void ntp_adjtime1(struct timex *); void ntp_gettime(struct ntptimeval *); int ntp_timestatus(void); -#endif /* __NetBSD__ */ + +extern kmutex_t timecounter_lock; #else /* !_KERNEL */ #include <sys/cdefs.h> __BEGIN_DECLS -#ifdef __NetBSD__ #ifndef __LIBC12_SOURCE__ int ntp_gettime(struct ntptimeval *) __RENAME(__ntp_gettime30); #endif -#else -int ntp_gettime(struct ntptimeval *); -#endif int ntp_adjtime(struct timex *); __END_DECLS #endif /* _KERNEL */ -#endif /* __FreeBSD__ || __NetBSD__ */ - #endif /* _SYS_TIMEX_H_ */ |
