Index: sys/compat/linprocfs/linprocfs.c =================================================================== --- sys/compat/linprocfs/linprocfs.c +++ sys/compat/linprocfs/linprocfs.c @@ -447,9 +447,11 @@ struct pcpu *pcpu; long cp_time[CPUSTATES]; long *cp; + struct timeval boottime; int i; read_cpu_time(cp_time); + getboottime(&boottime); sbuf_printf(sb, "cpu %ld %ld %ld %ld\n", T2J(cp_time[CP_USER]), T2J(cp_time[CP_NICE]), @@ -624,10 +626,12 @@ linprocfs_doprocstat(PFS_FILL_ARGS) { struct kinfo_proc kp; + struct timeval boottime; char state; static int ratelimit = 0; vm_offset_t startcode, startdata; + getboottime(&boottime); sx_slock(&proctree_lock); PROC_LOCK(p); fill_kinfo_proc(p, &kp); Index: sys/fs/devfs/devfs_vnops.c =================================================================== --- sys/fs/devfs/devfs_vnops.c +++ sys/fs/devfs/devfs_vnops.c @@ -707,10 +707,11 @@ { struct vnode *vp = ap->a_vp; struct vattr *vap = ap->a_vap; - int error; struct devfs_dirent *de; struct devfs_mount *dmp; struct cdev *dev; + struct timeval boottime; + int error; error = devfs_populate_vp(vp); if (error != 0) @@ -740,6 +741,7 @@ vap->va_blocksize = DEV_BSIZE; vap->va_type = vp->v_type; + getboottime(&boottime); #define fix(aa) \ do { \ if ((aa).tv_sec <= 3600) { \ Index: sys/fs/fdescfs/fdesc_vnops.c =================================================================== --- sys/fs/fdescfs/fdesc_vnops.c +++ sys/fs/fdescfs/fdesc_vnops.c @@ -394,7 +394,9 @@ { struct vnode *vp = ap->a_vp; struct vattr *vap = ap->a_vap; + struct timeval boottime; + getboottime(&boottime); vap->va_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; vap->va_fileid = VTOFDESC(vp)->fd_ix; vap->va_uid = 0; Index: sys/fs/nfs/nfsport.h =================================================================== --- sys/fs/nfs/nfsport.h +++ sys/fs/nfs/nfsport.h @@ -872,7 +872,7 @@ /* * Set boottime. */ -#define NFSSETBOOTTIME(b) ((b) = boottime) +#define NFSSETBOOTTIME(b) (getboottime(&b)) /* * The size of directory blocks in the buffer cache. Index: sys/fs/procfs/procfs_status.c =================================================================== --- sys/fs/procfs/procfs_status.c +++ sys/fs/procfs/procfs_status.c @@ -70,6 +70,7 @@ const char *wmesg; char *pc; char *sep; + struct timeval boottime; int pid, ppid, pgid, sid; int i; @@ -129,6 +130,7 @@ calcru(p, &ut, &st); PROC_STATUNLOCK(p); start = p->p_stats->p_start; + getboottime(&boottime); timevaladd(&start, &boottime); sbuf_printf(sb, " %jd,%ld %jd,%ld %jd,%ld", (intmax_t)start.tv_sec, start.tv_usec, Index: sys/kern/kern_acct.c =================================================================== --- sys/kern/kern_acct.c +++ sys/kern/kern_acct.c @@ -389,7 +389,7 @@ acct.ac_stime = encode_timeval(st); /* (4) The elapsed time the command ran (and its starting time) */ - tmp = boottime; + getboottime(&tmp); timevaladd(&tmp, &p->p_stats->p_start); acct.ac_btime = tmp.tv_sec; microuptime(&tmp); Index: sys/kern/kern_clock.c =================================================================== --- sys/kern/kern_clock.c +++ sys/kern/kern_clock.c @@ -381,7 +381,9 @@ int psratio; static DPCPU_DEFINE(int, pcputicks); /* Per-CPU version of ticks. */ -static int global_hardclock_run = 0; +#ifdef DEVICE_POLLING +static int devpoll_run = 0; +#endif /* * Initialize clock frequencies and start both clocks running. @@ -584,15 +586,15 @@ #endif /* We are in charge to handle this tick duty. */ if (newticks > 0) { - /* Dangerous and no need to call these things concurrently. */ - if (atomic_cmpset_acq_int(&global_hardclock_run, 0, 1)) { - tc_ticktock(newticks); + tc_ticktock(newticks); #ifdef DEVICE_POLLING + /* Dangerous and no need to call these things concurrently. */ + if (atomic_cmpset_acq_int(&devpoll_run, 0, 1)) { /* This is very short and quick. */ hardclock_device_poll(); -#endif /* DEVICE_POLLING */ - atomic_store_rel_int(&global_hardclock_run, 0); + atomic_store_rel_int(&devpoll_run, 0); } +#endif /* DEVICE_POLLING */ #ifdef SW_WATCHDOG if (watchdog_enabled > 0) { i = atomic_fetchadd_int(&watchdog_ticks, -newticks); Index: sys/kern/kern_ntptime.c =================================================================== --- sys/kern/kern_ntptime.c +++ sys/kern/kern_ntptime.c @@ -162,29 +162,12 @@ static int64_t time_adjtime; /* correction from adjtime(2) (usec) */ -static struct mtx ntpadj_lock; -MTX_SYSINIT(ntpadj, &ntpadj_lock, "ntpadj", -#ifdef PPS_SYNC - MTX_SPIN -#else - MTX_DEF -#endif -); +static struct mtx ntp_lock; +MTX_SYSINIT(ntp, &ntp_lock, "ntp", MTX_SPIN); -/* - * When PPS_SYNC is defined, hardpps() function is provided which can - * be legitimately called from interrupt filters. Due to this, use - * spinlock for ntptime state protection, otherwise sleepable mutex is - * adequate. - */ -#ifdef PPS_SYNC -#define NTPADJ_LOCK() mtx_lock_spin(&ntpadj_lock) -#define NTPADJ_UNLOCK() mtx_unlock_spin(&ntpadj_lock) -#else -#define NTPADJ_LOCK() mtx_lock(&ntpadj_lock) -#define NTPADJ_UNLOCK() mtx_unlock(&ntpadj_lock) -#endif -#define NTPADJ_ASSERT_LOCKED() mtx_assert(&ntpadj_lock, MA_OWNED) +#define NTP_LOCK() mtx_lock_spin(&ntp_lock) +#define NTP_UNLOCK() mtx_unlock_spin(&ntp_lock) +#define NTP_ASSERT_LOCKED() mtx_assert(&ntp_lock, MA_OWNED) #ifdef PPS_SYNC /* @@ -271,7 +254,7 @@ { struct timespec atv; /* nanosecond time */ - NTPADJ_ASSERT_LOCKED(); + NTP_ASSERT_LOCKED(); nanotime(&atv); ntvp->time.tv_sec = atv.tv_sec; @@ -302,9 +285,9 @@ { struct ntptimeval ntv; - NTPADJ_LOCK(); + NTP_LOCK(); ntp_gettime1(&ntv); - NTPADJ_UNLOCK(); + NTP_UNLOCK(); td->td_retval[0] = ntv.time_state; return (copyout(&ntv, uap->ntvp, sizeof(ntv))); @@ -315,9 +298,9 @@ { struct ntptimeval ntv; /* temporary structure */ - NTPADJ_LOCK(); + NTP_LOCK(); ntp_gettime1(&ntv); - NTPADJ_UNLOCK(); + NTP_UNLOCK(); return (sysctl_handle_opaque(oidp, &ntv, sizeof(ntv), req)); } @@ -382,7 +365,7 @@ error = priv_check(td, PRIV_NTP_ADJTIME); if (error != 0) return (error); - NTPADJ_LOCK(); + NTP_LOCK(); if (modes & MOD_MAXERROR) time_maxerror = ntv.maxerror; if (modes & MOD_ESTERROR) @@ -484,7 +467,7 @@ ntv.stbcnt = pps_stbcnt; #endif /* PPS_SYNC */ retval = ntp_is_time_error(time_status) ? TIME_ERROR : time_state; - NTPADJ_UNLOCK(); + NTP_UNLOCK(); error = copyout((caddr_t)&ntv, (caddr_t)uap->tp, sizeof(ntv)); if (error == 0) @@ -506,6 +489,8 @@ int tickrate; l_fp ftemp; /* 32/64-bit temporary */ + NTP_LOCK(); + /* * On rollover of the second both the nanosecond and microsecond * clocks are updated and the state machine cranked as @@ -627,6 +612,8 @@ else time_status &= ~STA_PPSSIGNAL; #endif /* PPS_SYNC */ + + NTP_UNLOCK(); } /* @@ -690,7 +677,7 @@ long mtemp; l_fp ftemp; - NTPADJ_ASSERT_LOCKED(); + NTP_ASSERT_LOCKED(); /* * Select how the phase is to be controlled and from which @@ -772,7 +759,7 @@ long u_sec, u_nsec, v_nsec; /* temps */ l_fp ftemp; - NTPADJ_LOCK(); + NTP_LOCK(); /* * The signal is first processed by a range gate and frequency @@ -956,7 +943,7 @@ time_freq = pps_freq; out: - NTPADJ_UNLOCK(); + NTP_UNLOCK(); } #endif /* PPS_SYNC */ @@ -999,11 +986,11 @@ return (error); ltw = (int64_t)delta->tv_sec * 1000000 + delta->tv_usec; } - NTPADJ_LOCK(); + NTP_LOCK(); ltr = time_adjtime; if (delta != NULL) time_adjtime = ltw; - NTPADJ_UNLOCK(); + NTP_UNLOCK(); if (olddelta != NULL) { atv.tv_sec = ltr / 1000000; atv.tv_usec = ltr % 1000000; Index: sys/kern/kern_proc.c =================================================================== --- sys/kern/kern_proc.c +++ sys/kern/kern_proc.c @@ -872,6 +872,7 @@ struct session *sp; struct ucred *cred; struct sigacts *ps; + struct timeval boottime; /* For proc_realparent. */ sx_assert(&proctree_lock, SX_LOCKED); @@ -953,6 +954,7 @@ kp->ki_nice = p->p_nice; kp->ki_fibnum = p->p_fibnum; kp->ki_start = p->p_stats->p_start; + getboottime(&boottime); timevaladd(&kp->ki_start, &boottime); PROC_STATLOCK(p); rufetch(p, &kp->ki_rusage); Index: sys/kern/kern_tc.c =================================================================== --- sys/kern/kern_tc.c +++ sys/kern/kern_tc.c @@ -70,31 +70,22 @@ struct bintime th_offset; struct timeval th_microtime; struct timespec th_nanotime; + struct bintime th_boottime; /* Fields not to be copied in tc_windup start with th_generation. */ u_int th_generation; struct timehands *th_next; }; static struct timehands th0; -static struct timehands th9 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th0}; -static struct timehands th8 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th9}; -static struct timehands th7 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th8}; -static struct timehands th6 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th7}; -static struct timehands th5 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th6}; -static struct timehands th4 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th5}; -static struct timehands th3 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th4}; -static struct timehands th2 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th3}; -static struct timehands th1 = { NULL, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, 0, &th2}; +static struct timehands th1 = { + .th_next = &th0 +}; static struct timehands th0 = { - &dummy_timecounter, - 0, - (uint64_t)-1 / 1000000, - 0, - {1, 0}, - {0, 0}, - {0, 0}, - 1, - &th1 + .th_counter = &dummy_timecounter, + .th_scale = (uint64_t)-1 / 1000000, + .th_offset = { .sec = 1 }, + .th_generation = 1, + .th_next = &th1 }; static struct timehands *volatile timehands = &th0; @@ -106,8 +97,6 @@ volatile time_t time_second = 1; volatile time_t time_uptime = 1; -struct bintime boottimebin; -struct timeval boottime; static int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS); SYSCTL_PROC(_kern, KERN_BOOTTIME, boottime, CTLTYPE_STRUCT|CTLFLAG_RD, NULL, 0, sysctl_kern_boottime, "S,timeval", "System boottime"); @@ -135,7 +124,7 @@ static int tc_chosen; /* Non-zero if a specific tc was chosen via sysctl. */ -static void tc_windup(void); +static void tc_windup(struct bintime *new_boottimebin); static void cpu_tick_calibrate(int); void dtrace_getnanotime(struct timespec *tsp); @@ -143,6 +132,10 @@ static int sysctl_kern_boottime(SYSCTL_HANDLER_ARGS) { + struct timeval boottime; + + getboottime(&boottime); + #ifndef __mips__ #ifdef SCTL_MASK32 int tv[2]; @@ -150,11 +143,11 @@ if (req->flags & SCTL_MASK32) { tv[0] = boottime.tv_sec; tv[1] = boottime.tv_usec; - return SYSCTL_OUT(req, tv, sizeof(tv)); - } else + return (SYSCTL_OUT(req, tv, sizeof(tv))); + } #endif #endif - return SYSCTL_OUT(req, &boottime, sizeof(boottime)); + return (SYSCTL_OUT(req, &boottime, sizeof(boottime))); } static int @@ -164,7 +157,7 @@ struct timecounter *tc = arg1; ncount = tc->tc_get_timecount(tc); - return sysctl_handle_int(oidp, &ncount, 0, req); + return (sysctl_handle_int(oidp, &ncount, 0, req)); } static int @@ -174,7 +167,7 @@ struct timecounter *tc = arg1; freq = tc->tc_frequency; - return sysctl_handle_64(oidp, &freq, 0, req); + return (sysctl_handle_64(oidp, &freq, 0, req)); } /* @@ -234,9 +227,17 @@ void fbclock_bintime(struct bintime *bt) { + struct timehands *th; + unsigned int gen; - fbclock_binuptime(bt); - bintime_add(bt, &boottimebin); + do { + th = timehands; + gen = atomic_load_acq_int(&th->th_generation); + *bt = th->th_offset; + bintime_addx(bt, th->th_scale * tc_delta(th)); + bintime_add(bt, &th->th_boottime); + atomic_thread_fence_acq(); + } while (gen == 0 || gen != th->th_generation); } void @@ -309,9 +310,9 @@ th = timehands; gen = atomic_load_acq_int(&th->th_generation); *bt = th->th_offset; + bintime_add(bt, &th->th_boottime); atomic_thread_fence_acq(); } while (gen == 0 || gen != th->th_generation); - bintime_add(bt, &boottimebin); } void @@ -378,9 +379,17 @@ void bintime(struct bintime *bt) { + struct timehands *th; + u_int gen; - binuptime(bt); - bintime_add(bt, &boottimebin); + do { + th = timehands; + gen = atomic_load_acq_int(&th->th_generation); + *bt = th->th_offset; + bintime_addx(bt, th->th_scale * tc_delta(th)); + bintime_add(bt, &th->th_boottime); + atomic_thread_fence_acq(); + } while (gen == 0 || gen != th->th_generation); } void @@ -453,9 +462,9 @@ th = timehands; gen = atomic_load_acq_int(&th->th_generation); *bt = th->th_offset; + bintime_add(bt, &th->th_boottime); atomic_thread_fence_acq(); } while (gen == 0 || gen != th->th_generation); - bintime_add(bt, &boottimebin); } void @@ -487,6 +496,29 @@ } #endif /* FFCLOCK */ +void +getboottime(struct timeval *boottime) +{ + struct bintime boottimebin; + + getboottimebin(&boottimebin); + bintime2timeval(&boottimebin, boottime); +} + +void +getboottimebin(struct bintime *boottimebin) +{ + struct timehands *th; + u_int gen; + + do { + th = timehands; + gen = atomic_load_acq_int(&th->th_generation); + *boottimebin = th->th_boottime; + atomic_thread_fence_acq(); + } while (gen == 0 || gen != th->th_generation); +} + #ifdef FFCLOCK /* * Support for feed-forward synchronization algorithms. This is heavily inspired @@ -1103,6 +1135,7 @@ sysclock_snap2bintime(struct sysclock_snap *cs, struct bintime *bt, int whichclock, uint32_t flags) { + struct bintime boottimebin; #ifdef FFCLOCK struct bintime bt2; uint64_t period; @@ -1116,8 +1149,10 @@ if (cs->delta > 0) bintime_addx(bt, cs->fb_info.th_scale * cs->delta); - if ((flags & FBCLOCK_UPTIME) == 0) + if ((flags & FBCLOCK_UPTIME) == 0) { + getboottimebin(&boottimebin); bintime_add(bt, &boottimebin); + } break; #ifdef FFCLOCK case SYSCLOCK_FFWD: @@ -1226,10 +1261,12 @@ return (timehands->th_counter->tc_frequency); } +static struct mtx tc_setclock_mtx; +MTX_SYSINIT(tc_setclock_init, &tc_setclock_mtx, "tcsetc", MTX_SPIN); + /* * Step our concept of UTC. This is done by modifying our estimate of * when we booted. - * XXX: not locked. */ void tc_setclock(struct timespec *ts) @@ -1237,26 +1274,24 @@ struct timespec tbef, taft; struct bintime bt, bt2; - cpu_tick_calibrate(1); - nanotime(&tbef); timespec2bintime(ts, &bt); + nanotime(&tbef); + mtx_lock_spin(&tc_setclock_mtx); + cpu_tick_calibrate(1); binuptime(&bt2); bintime_sub(&bt, &bt2); - bintime_add(&bt2, &boottimebin); - boottimebin = bt; - bintime2timeval(&bt, &boottime); /* XXX fiddle all the little crinkly bits around the fiords... */ - tc_windup(); - nanotime(&taft); + tc_windup(&bt); + mtx_unlock_spin(&tc_setclock_mtx); if (timestepwarnings) { + nanotime(&taft); log(LOG_INFO, "Time stepped from %jd.%09ld to %jd.%09ld (%jd.%09ld)\n", (intmax_t)tbef.tv_sec, tbef.tv_nsec, (intmax_t)taft.tv_sec, taft.tv_nsec, (intmax_t)ts->tv_sec, ts->tv_nsec); } - cpu_tick_calibrate(1); } /* @@ -1265,7 +1300,7 @@ * timecounter and/or do seconds processing in NTP. Slightly magic. */ static void -tc_windup(void) +tc_windup(struct bintime *new_boottimebin) { struct bintime bt; struct timehands *th, *tho; @@ -1289,6 +1324,8 @@ th->th_generation = 0; atomic_thread_fence_rel(); bcopy(tho, th, offsetof(struct timehands, th_generation)); + if (new_boottimebin != NULL) + th->th_boottime = *new_boottimebin; /* * Capture a timecounter delta on the current timecounter and if @@ -1338,7 +1375,7 @@ * case we missed a leap second. */ bt = th->th_offset; - bintime_add(&bt, &boottimebin); + bintime_add(&bt, &th->th_boottime); i = bt.sec - tho->th_microtime.tv_sec; if (i > LARGE_STEP) i = 2; @@ -1346,7 +1383,7 @@ t = bt.sec; ntp_update_second(&th->th_adjustment, &bt.sec); if (bt.sec != t) - boottimebin.sec += bt.sec - t; + th->th_boottime.sec += bt.sec - t; } /* Update the UTC timestamps used by the get*() functions. */ /* XXX shouldn't do this here. Should force non-`get' versions. */ @@ -1769,7 +1806,7 @@ tcount &= pps->capth->th_counter->tc_counter_mask; bt = pps->capth->th_offset; bintime_addx(&bt, pps->capth->th_scale * tcount); - bintime_add(&bt, &boottimebin); + bintime_add(&bt, &pps->capth->th_boottime); bintime2timespec(&bt, &ts); /* If the timecounter was wound up underneath us, bail out. */ @@ -1842,11 +1879,14 @@ { static int count; - count += cnt; - if (count < tc_tick) - return; - count = 0; - tc_windup(); + if (mtx_trylock_spin(&tc_setclock_mtx)) { + count += cnt; + if (count >= tc_tick) { + count = 0; + tc_windup(NULL); + } + mtx_unlock_spin(&tc_setclock_mtx); + } } static void __inline @@ -1921,7 +1961,9 @@ /* warm up new timecounter (again) and get rolling. */ (void)timecounter->tc_get_timecount(timecounter); (void)timecounter->tc_get_timecount(timecounter); - tc_windup(); + mtx_lock_spin(&tc_setclock_mtx); + tc_windup(NULL); + mtx_unlock_spin(&tc_setclock_mtx); } SYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_SECOND, inittimecounter, NULL); @@ -2095,7 +2137,7 @@ vdso_th->th_offset_count = th->th_offset_count; vdso_th->th_counter_mask = th->th_counter->tc_counter_mask; vdso_th->th_offset = th->th_offset; - vdso_th->th_boottime = boottimebin; + vdso_th->th_boottime = th->th_boottime; enabled = cpu_fill_vdso_timehands(vdso_th, th->th_counter); if (!vdso_th_enable) enabled = 0; @@ -2116,8 +2158,8 @@ vdso_th32->th_counter_mask = th->th_counter->tc_counter_mask; vdso_th32->th_offset.sec = th->th_offset.sec; *(uint64_t *)&vdso_th32->th_offset.frac[0] = th->th_offset.frac; - vdso_th32->th_boottime.sec = boottimebin.sec; - *(uint64_t *)&vdso_th32->th_boottime.frac[0] = boottimebin.frac; + vdso_th32->th_boottime.sec = th->th_boottime.sec; + *(uint64_t *)&vdso_th32->th_boottime.frac[0] = th->th_boottime.frac; enabled = cpu_fill_vdso_timehands32(vdso_th32, th->th_counter); if (!vdso_th_enable) enabled = 0; Index: sys/kern/kern_time.c =================================================================== --- sys/kern/kern_time.c +++ sys/kern/kern_time.c @@ -120,9 +120,7 @@ struct timeval delta, tv1, tv2; static struct timeval maxtime, laststep; struct timespec ts; - int s; - s = splclock(); microtime(&tv1); delta = *tv; timevalsub(&delta, &tv1); @@ -152,10 +150,8 @@ printf("Time adjustment clamped to -1 second\n"); } } else { - if (tv1.tv_sec == laststep.tv_sec) { - splx(s); + if (tv1.tv_sec == laststep.tv_sec) return (EPERM); - } if (delta.tv_sec > 1) { tv->tv_sec = tv1.tv_sec + 1; printf("Time adjustment clamped to +1 second\n"); @@ -166,10 +162,8 @@ ts.tv_sec = tv->tv_sec; ts.tv_nsec = tv->tv_usec * 1000; - mtx_lock(&Giant); tc_setclock(&ts); resettodr(); - mtx_unlock(&Giant); return (0); } Index: sys/kern/subr_rtc.c =================================================================== --- sys/kern/subr_rtc.c +++ sys/kern/subr_rtc.c @@ -172,11 +172,11 @@ 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 */ + mtx_lock(&resettodr_lock); error = CLOCK_SETTIME(clock_dev, &ts); mtx_unlock(&resettodr_lock); if (error != 0) Index: sys/kern/sys_procdesc.c =================================================================== --- sys/kern/sys_procdesc.c +++ sys/kern/sys_procdesc.c @@ -523,7 +523,7 @@ struct thread *td) { struct procdesc *pd; - struct timeval pstart; + struct timeval pstart, boottime; /* * XXXRW: Perhaps we should cache some more information from the @@ -539,6 +539,7 @@ /* Set birth and [acm] times to process start time. */ pstart = pd->pd_proc->p_stats->p_start; + getboottime(&boottime); timevaladd(&pstart, &boottime); TIMEVAL_TO_TIMESPEC(&pstart, &sb->st_birthtim); sb->st_atim = sb->st_birthtim; Index: sys/net/altq/altq_subr.c =================================================================== --- sys/net/altq/altq_subr.c +++ sys/net/altq/altq_subr.c @@ -1027,9 +1027,10 @@ panic("read_machclk"); #endif } else { - struct timeval tv; + struct timeval tv, boottime; microtime(&tv); + getboottime(&boottime); val = (((u_int64_t)(tv.tv_sec - boottime.tv_sec) * 1000000 + tv.tv_usec) << MACHCLK_SHIFT); } Index: sys/net/bpf.c =================================================================== --- sys/net/bpf.c +++ sys/net/bpf.c @@ -2328,12 +2328,13 @@ static void bpf_bintime2ts(struct bintime *bt, struct bpf_ts *ts, int tstype) { - struct bintime bt2; + struct bintime bt2, boottimebin; struct timeval tsm; struct timespec tsn; if ((tstype & BPF_T_MONOTONIC) == 0) { bt2 = *bt; + getboottimebin(&boottimebin); bintime_add(&bt2, &boottimebin); bt = &bt2; } Index: sys/netpfil/ipfw/ip_fw_sockopt.c =================================================================== --- sys/netpfil/ipfw/ip_fw_sockopt.c +++ sys/netpfil/ipfw/ip_fw_sockopt.c @@ -395,6 +395,7 @@ static void export_cntr1_base(struct ip_fw *krule, struct ip_fw_bcounter *cntr) { + struct timeval boottime; cntr->size = sizeof(*cntr); @@ -403,21 +404,26 @@ cntr->bcnt = counter_u64_fetch(krule->cntr + 1); cntr->timestamp = krule->timestamp; } - if (cntr->timestamp > 0) + if (cntr->timestamp > 0) { + getboottime(&boottime); cntr->timestamp += boottime.tv_sec; + } } static void export_cntr0_base(struct ip_fw *krule, struct ip_fw_bcounter0 *cntr) { + struct timeval boottime; if (krule->cntr != NULL) { cntr->pcnt = counter_u64_fetch(krule->cntr); cntr->bcnt = counter_u64_fetch(krule->cntr + 1); cntr->timestamp = krule->timestamp; } - if (cntr->timestamp > 0) + if (cntr->timestamp > 0) { + getboottime(&boottime); cntr->timestamp += boottime.tv_sec; + } } /* @@ -2055,11 +2061,13 @@ char *ep = bp + space; struct ip_fw *rule; struct ip_fw_rule0 *dst; + struct timeval boottime; int error, i, l, warnflag; time_t boot_seconds; warnflag = 0; + getboottime(&boottime); boot_seconds = boottime.tv_sec; for (i = 0; i < chain->n_rules; i++) { rule = chain->map[i]; Index: sys/nfs/nfs_lock.c =================================================================== --- sys/nfs/nfs_lock.c +++ sys/nfs/nfs_lock.c @@ -241,6 +241,7 @@ struct flock *fl; struct proc *p; struct nfsmount *nmp; + struct timeval boottime; td = curthread; p = td->td_proc; @@ -284,6 +285,7 @@ p->p_nlminfo = malloc(sizeof(struct nlminfo), M_NLMINFO, M_WAITOK | M_ZERO); p->p_nlminfo->pid_start = p->p_stats->p_start; + getboottime(&boottime); timevaladd(&p->p_nlminfo->pid_start, &boottime); } msg.lm_msg_ident.pid_start = p->p_nlminfo->pid_start; Index: sys/rpc/rpcsec_gss/svc_rpcsec_gss.c =================================================================== --- sys/rpc/rpcsec_gss/svc_rpcsec_gss.c +++ sys/rpc/rpcsec_gss/svc_rpcsec_gss.c @@ -504,11 +504,13 @@ { struct svc_rpc_gss_client *client; struct svc_rpc_gss_client_list *list; + struct timeval boottime; unsigned long hostid; rpc_gss_log_debug("in svc_rpc_gss_find_client(%d)", id->ci_id); getcredhostid(curthread->td_ucred, &hostid); + getboottime(&boottime); if (id->ci_hostid != hostid || id->ci_boottime != boottime.tv_sec) return (NULL); @@ -537,6 +539,7 @@ { struct svc_rpc_gss_client *client; struct svc_rpc_gss_client_list *list; + struct timeval boottime; unsigned long hostid; rpc_gss_log_debug("in svc_rpc_gss_create_client()"); @@ -547,6 +550,7 @@ sx_init(&client->cl_lock, "GSS-client"); getcredhostid(curthread->td_ucred, &hostid); client->cl_id.ci_hostid = hostid; + getboottime(&boottime); client->cl_id.ci_boottime = boottime.tv_sec; client->cl_id.ci_id = svc_rpc_gss_next_clientid++; list = &svc_rpc_gss_client_hash[client->cl_id.ci_id % CLIENT_HASH_SIZE]; Index: sys/sys/time.h =================================================================== --- sys/sys/time.h +++ sys/sys/time.h @@ -372,8 +372,6 @@ extern volatile time_t time_second; extern volatile time_t time_uptime; -extern struct bintime boottimebin; -extern struct timeval boottime; extern struct bintime tc_tick_bt; extern sbintime_t tc_tick_sbt; extern struct bintime tick_bt; @@ -440,6 +438,9 @@ void getnanotime(struct timespec *tsp); void getmicrotime(struct timeval *tvp); +void getboottime(struct timeval *boottime); +void getboottimebin(struct bintime *boottimebin); + /* Other functions */ int itimerdecr(struct itimerval *itp, int usec); int itimerfix(struct timeval *tv);