Index: sbin/savecore/savecore.c =================================================================== RCS file: /cvsroot/src/sbin/savecore/savecore.c,v retrieving revision 1.65 diff -d -p -u -r1.65 savecore.c --- sbin/savecore/savecore.c 16 Oct 2004 03:48:15 -0000 1.65 +++ sbin/savecore/savecore.c 22 Nov 2005 13:39:07 -0000 @@ -75,8 +75,12 @@ struct nlist current_nl[] = { /* Namelis { "_dumpdev" }, #define X_DUMPLO 1 { "_dumplo" }, -#define X_TIME 2 - { "_time" }, +#define X_TIME_SECOND 2 +#ifdef __HAVE_TIMECOUNTER + { "_time_second" }, +#else + { "_time" }, /* XXX uses same array slot as "X_TIME_SECOND" */ +#endif #define X_DUMPSIZE 3 { "_dumpsize" }, #define X_VERSION 4 @@ -94,12 +98,17 @@ struct nlist current_nl[] = { /* Namelis { NULL }, }; int cursyms[] = { X_DUMPDEV, X_DUMPLO, X_VERSION, X_DUMPMAG, -1 }; -int dumpsyms[] = { X_TIME, X_DUMPSIZE, X_VERSION, X_PANICSTR, X_DUMPMAG, -1 }; +int dumpsyms[] = { X_TIME_SECOND, X_DUMPSIZE, X_VERSION, X_PANICSTR, X_DUMPMAG, + -1 }; struct nlist dump_nl[] = { /* Name list for dumped system. */ { "_dumpdev" }, /* Entries MUST be the same as */ { "_dumplo" }, /* those in current_nl[]. */ - { "_time" }, +#ifdef __HAVE_TIMECOUNTER + { "_time_second" }, +#else + { "_time" }, /* XXX uses same array slot as "X_TIME_SECOND" */ +#endif { "_dumpsize" }, { "_version" }, { "_dumpmag" }, @@ -678,15 +687,25 @@ rawname(char *s) int get_crashtime(void) { - struct timeval dtime; time_t dumptime; /* Time the dump was taken. */ +#ifndef __HAVE_TIMECOUNTER + struct timeval dtime; +#endif - if (KREAD(kd_dump, dump_nl[X_TIME].n_value, &dtime) != 0) { +#ifdef __HAVE_TIMECOUNTER + if (KREAD(kd_dump, dump_nl[X_TIME_SECOND].n_value, &dumptime) != 0) { + if (verbose) + syslog(LOG_WARNING, "kvm_read: %s", kvm_geterr(kd_dump)); + return (0); + } +#else + if (KREAD(kd_dump, dump_nl[X_TIME_SECOND].n_value, &dtime) != 0) { if (verbose) syslog(LOG_WARNING, "kvm_read: %s", kvm_geterr(kd_dump)); return (0); } dumptime = dtime.tv_sec; +#endif if (dumptime == 0) { if (verbose) syslog(LOG_ERR, "dump time is zero"); Index: sys/arch/i386/acpi/acpi_wakeup.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/acpi/acpi_wakeup.c,v retrieving revision 1.16 diff -d -p -u -r1.16 acpi_wakeup.c --- sys/arch/i386/acpi/acpi_wakeup.c 2 May 2005 14:54:46 -0000 1.16 +++ sys/arch/i386/acpi/acpi_wakeup.c 22 Nov 2005 13:39:32 -0000 @@ -430,7 +430,7 @@ acpi_md_sleep(int state) */ initrtclock(); - inittodr(time.tv_sec); + inittodr(time_second); #ifdef ACPI_PRINT_REG acpi_savecpu(); Index: sys/arch/i386/conf/Makefile.i386 =================================================================== RCS file: /cvsroot/src/sys/arch/i386/conf/Makefile.i386,v retrieving revision 1.141 diff -d -p -u -r1.141 Makefile.i386 --- sys/arch/i386/conf/Makefile.i386 7 Nov 2005 11:42:34 -0000 1.141 +++ sys/arch/i386/conf/Makefile.i386 22 Nov 2005 13:39:32 -0000 @@ -46,10 +46,10 @@ KERN_AS= library ## ## (4) local objects, compile rules, and dependencies ## -MD_OBJS= locore.o copy.o spl.o vector.o microtime.o +MD_OBJS= locore.o copy.o spl.o vector.o MD_CFILES= MD_SFILES= ${I386}/i386/locore.S ${I386}/i386/copy.S ${I386}/i386/spl.S \ - ${I386}/i386/vector.S ${I386}/i386/microtime.S + ${I386}/i386/vector.S locore.o: ${I386}/i386/locore.S assym.h ${NORMAL_S} @@ -63,9 +63,6 @@ spl.o: ${I386}/i386/spl.S assym.h vector.o: ${I386}/i386/vector.S assym.h ${NORMAL_S} -microtime.o: ${I386}/i386/microtime.S assym.h - ${NORMAL_S} - ## ## (5) link settings ## Index: sys/arch/i386/conf/files.i386 =================================================================== RCS file: /cvsroot/src/sys/arch/i386/conf/files.i386,v retrieving revision 1.273 diff -d -p -u -r1.273 files.i386 --- sys/arch/i386/conf/files.i386 7 Nov 2005 11:42:34 -0000 1.273 +++ sys/arch/i386/conf/files.i386 22 Nov 2005 13:39:32 -0000 @@ -79,7 +79,6 @@ file arch/i386/i386/machdep.c file arch/i386/i386/identcpu.c file arch/i386/i386/math_emulate.c math_emulate file arch/i386/i386/mem.c -file kern/kern_microtime.c i586_cpu | i686_cpu file arch/i386/i386/mtrr_k6.c mtrr file netns/ns_cksum.c ns file arch/i386/i386/pmap.c @@ -88,6 +87,7 @@ file arch/i386/i386/procfs_machdep.c pro file arch/i386/i386/sys_machdep.c file arch/i386/i386/syscall.c file arch/i386/i386/trap.c +file arch/i386/i386/tsc.c # XXX just i586_cpu | i686_cpu ? file arch/i386/i386/vm_machdep.c file dev/cons.c @@ -191,6 +191,13 @@ device geodewdog: sysmon_wdog attach geodewdog at pci file arch/i386/pci/geode.c geodewdog +# AMD Geode SC1100 high resolution counter implementation. +# The TSC and ISA hardware counter implementations are horribly broken +# for time keeping because of power saving features +device geodecntr +attach geodecntr at pci +file arch/i386/pci/geodecntr.c geodecntr + # PCI-EISA bridges device pceb: eisabus, isabus attach pceb at pci Index: sys/arch/i386/i386/apm.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/apm.c,v retrieving revision 1.87 diff -d -p -u -r1.87 apm.c --- sys/arch/i386/i386/apm.c 1 Jun 2005 16:49:14 -0000 1.87 +++ sys/arch/i386/i386/apm.c 22 Nov 2005 13:39:36 -0000 @@ -349,13 +349,13 @@ apmcall_debug(func, regs, line) inf = aci[func].inflag; outf = aci[func].outflag; } - inittodr(time.tv_sec); /* update timestamp */ + inittodr(time_second); /* update timestamp */ if (name) printf("apmcall@%03ld: %s/%#x (line=%d) ", - time.tv_sec % 1000, name, func, line); + time_second % 1000, name, func, line); else printf("apmcall@%03ld: %#x (line=%d) ", - time.tv_sec % 1000, func, line); + time_second % 1000, func, line); acallpr(inf, "in:", regs); } rv = apmcall(func, regs); @@ -588,7 +588,7 @@ apm_resume(sc, regs) */ initrtclock(); - inittodr(time.tv_sec); + inittodr(time_second); dopowerhooks(PWR_RESUME); splx(apm_spl); Index: sys/arch/i386/i386/cpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/cpu.c,v retrieving revision 1.24 diff -d -p -u -r1.24 cpu.c --- sys/arch/i386/i386/cpu.c 7 Jul 2005 13:20:53 -0000 1.24 +++ sys/arch/i386/i386/cpu.c 22 Nov 2005 13:39:37 -0000 @@ -409,19 +409,7 @@ cpu_init(ci) if (ci->ci_cpu_class >= CPUCLASS_486) lcr0(rcr0() | CR0_WP); #endif -#if defined(I586_CPU) || defined(I686_CPU) -#ifndef NO_TSC_TIME - /* - * On systems with a cycle counter, use that for - * interval timing inbetween hz ticks in microtime(9) - * N.B. this is not a good idea on processors whose - * frequency varies a lot over time (e.g. modern laptops) - */ - if (cpu_feature & CPUID_TSC) { - microtime_func = cc_microtime; - } -#endif -#endif + #if defined(I686_CPU) /* * On a P6 or above, enable global TLB caching if the @@ -624,10 +612,8 @@ cpu_hatch(void *v) enable_intr(); printf("%s: CPU %ld running\n",ci->ci_dev->dv_xname, ci->ci_cpuid); -#if defined(I586_CPU) || defined(I686_CPU) - if (ci->ci_feature_flags & CPUID_TSC) - cc_microset(ci); -#endif + + /* XXX old cc_microset() type work needed with MP timecounters? */ microtime(&ci->ci_schedstate.spc_runtime); splx(s); } Index: sys/arch/i386/i386/ipifuncs.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/ipifuncs.c,v retrieving revision 1.10 diff -d -p -u -r1.10 ipifuncs.c --- sys/arch/i386/i386/ipifuncs.c 14 Jul 2003 22:13:10 -0000 1.10 +++ sys/arch/i386/i386/ipifuncs.c 22 Nov 2005 13:39:37 -0000 @@ -86,11 +86,7 @@ void i386_reload_mtrr(struct cpu_info *) void (*ipifunc[X86_NIPI])(struct cpu_info *) = { i386_ipi_halt, -#if defined(I586_CPU) || defined(I686_CPU) - cc_microset, -#else - 0, -#endif + 0, /* cc_microset - not used with timecounters */ i386_ipi_flush_fpu, i386_ipi_synch_fpu, pmap_do_tlb_shootdown, Index: sys/arch/i386/i386/machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/machdep.c,v retrieving revision 1.565 diff -d -p -u -r1.565 machdep.c --- sys/arch/i386/i386/machdep.c 22 Sep 2005 07:13:27 -0000 1.565 +++ sys/arch/i386/i386/machdep.c 22 Nov 2005 13:39:44 -0000 @@ -112,7 +112,6 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v #include #include #include -#include #include #include #include @@ -133,10 +132,12 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v #include +#include #include #include #include #include +#include #include #include #include @@ -255,8 +256,7 @@ struct vm_map *phys_map = NULL; extern paddr_t avail_start, avail_end; void (*delay_func)(int) = i8254_delay; -void (*microtime_func)(struct timeval *) = i8254_microtime; -void (*initclock_func)(void) = i8254_initclocks; +void (*initclock_func)(void) = i8254_initclocks; /* XXXX deal with this in a cleaner way too? */ /* * Size of memory segments, before any memory is stolen. @@ -2284,7 +2284,9 @@ cpu_setmcontext(struct lwp *l, const mco void cpu_initclocks() { + (*initclock_func)(); + init_TSC_tc(); } #ifdef MULTIPROCESSOR Index: sys/arch/i386/i386/microtime.S =================================================================== RCS file: sys/arch/i386/i386/microtime.S diff -N sys/arch/i386/i386/microtime.S --- sys/arch/i386/i386/microtime.S 7 Aug 2003 16:27:55 -0000 1.3 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,118 +0,0 @@ -/* $NetBSD: microtime.S,v 1.3 2003/08/07 16:27:55 agc Exp $ */ - -/*- - * Copyright (c) 1993 The Regents of the University of California. - * 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. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#include -#include -#include - -#include "assym.h" - -/* LINTSTUB: include */ - -#define IRQ_BIT(irq_num) (1 << ((irq_num) % 8)) -#define IRQ_BYTE(irq_num) ((irq_num) >> 3) - -/* LINTSTUB: Func: void i8254_microtime(struct timeval *tv) */ -ENTRY(i8254_microtime) - # clear registers and do whatever we can up front - pushl %edi - pushl %ebx - xorl %edx,%edx - movl $(TIMER_SEL0|TIMER_LATCH),%eax - - cli # disable interrupts - - # select timer 0 and latch its counter - outb %al,$IO_TIMER1+TIMER_MODE - inb $IO_ICU1,%al # as close to timer latch as possible - movb %al,%ch # %ch is current ICU mask - - # Read counter value into [%al %dl], LSB first - inb $IO_TIMER1+TIMER_CNTR0,%al - movb %al,%dl # %dl has LSB - inb $IO_TIMER1+TIMER_CNTR0,%al # %al has MSB - - /* - * XXX this assumes that irq 0 is slot 0 on the primary CPU. - * Currently always true, and not likely to change, but - * still not a beauty. - */ - # save state of IIR in ICU, and of ipending, for later perusal - movb CPUVAR(IPENDING) + IRQ_BYTE(0),%cl # %cl is interrupt pending - - # save the current value of _time - movl _C_LABEL(time),%edi # get time.tv_sec - movl _C_LABEL(time)+4,%ebx # and time.tv_usec - - sti # enable interrupts, we're done - - # At this point we've collected all the state we need to - # compute the time. First figure out if we've got a pending - # interrupt. If the IRQ0 bit is set in ipending we've taken - # a clock interrupt without incrementing time, so we bump - # time.tv_usec by a tick. Otherwise if the ICU shows a pending - # interrupt for IRQ0 we (or the caller) may have blocked an interrupt - # with the cli. If the counter is not a very small value (3 as - # a heuristic), i.e. in pre-interrupt state, we add a tick to - # time.tv_usec - - testb $IRQ_BIT(0),%cl # pending interrupt? - jnz 1f # yes, increment count - - testb $IRQ_BIT(0),%ch # hardware interrupt pending? - jz 2f # no, continue - testb %al,%al # MSB zero? - jnz 1f # no, add a tick - cmpb $3,%dl # is this small number? - jbe 2f # yes, continue -1: addl _C_LABEL(isa_timer_tick),%ebx # add a tick - - # We've corrected for pending interrupts. Now do a table lookup - # based on each of the high and low order counter bytes to increment - # time.tv_usec -2: movw _C_LABEL(isa_timer_msb_table)(,%eax,2),%ax - subw _C_LABEL(isa_timer_lsb_table)(,%edx,2),%ax - addl %eax,%ebx # add msb increment - - # Normalize the struct timeval. We know the previous increments - # will be less than a second, so we'll only need to adjust accordingly - cmpl $1000000,%ebx # carry in timeval? - jb 3f - subl $1000000,%ebx # adjust usec - incl %edi # bump sec - -3: movl 12(%esp),%ecx # load timeval pointer arg - movl %edi,(%ecx) # tvp->tv_sec = sec - movl %ebx,4(%ecx) # tvp->tv_usec = usec - - popl %ebx - popl %edi - ret Index: sys/arch/i386/i386/svr4_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/svr4_machdep.c,v retrieving revision 1.75 diff -d -p -u -r1.75 svr4_machdep.c --- sys/arch/i386/i386/svr4_machdep.c 12 Mar 2005 16:33:45 -0000 1.75 +++ sys/arch/i386/i386/svr4_machdep.c 22 Nov 2005 13:39:46 -0000 @@ -530,8 +530,8 @@ svr4_fasttrap(frame) struct proc *p = l->l_proc; struct schedstate_percpu *spc; struct timeval tv; + struct timespec ts; uint64_t tm; - int s; l->l_md.md_regs = &frame; @@ -550,14 +550,11 @@ svr4_fasttrap(frame) * This is like gethrtime(3), returning the time expressed * in nanoseconds since an arbitrary time in the past and * guaranteed to be monotonically increasing, which we - * obtain from mono_time(9). + * obtain from nanouptime(9). */ - s = splclock(); - tv = mono_time; - splx(s); + nanouptime(&ts); - tm = tv.tv_usec * 1000u; - tm += tv.tv_sec * (uint64_t)1000000000u; + tm = ts.tv_nsec + ts.tv_sec * (uint64_t)1000000000u; /* XXX: dsl - I would have expected the msb in %edx */ frame.tf_edx = tm & 0xffffffffu; frame.tf_eax = (tm >> 32); @@ -591,10 +588,10 @@ svr4_fasttrap(frame) * proc's wall time. Seconds are returned in %eax, nanoseconds * in %edx. */ - microtime(&tv); + nanotime(&ts); - frame.tf_eax = (u_int32_t) tv.tv_sec; - frame.tf_edx = (u_int32_t) tv.tv_usec * 1000; + frame.tf_eax = (u_int32_t) ts.tv_sec; + frame.tf_edx = (u_int32_t) ts.tv_nsec; break; default: Index: sys/arch/i386/i386/tsc.c =================================================================== RCS file: sys/arch/i386/i386/tsc.c diff -N sys/arch/i386/i386/tsc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/i386/i386/tsc.c 22 Nov 2005 13:39:46 -0000 @@ -0,0 +1,173 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 1998-2003 Poul-Henning Kamp + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include +/* __FBSDID("$FreeBSD: src/sys/i386/i386/tsc.c,v 1.204 2003/10/21 18:28:34 silby Exp $"); */ +__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.94 2005/10/02 17:51:27 chs Exp $"); + +#include "opt_multiprocessor.h" + +#include +#include +#include +#include +#include +#include +#include +#include /* XXX for bootverbose */ +#include +#include + +uint64_t tsc_freq; +u_int tsc_present; +int tsc_is_broken = 0; + +static unsigned tsc_get_timecount(struct timecounter *tc); + +static struct timecounter tsc_timecounter = { + tsc_get_timecount, /* get_timecount */ + 0, /* no poll_pps */ + ~0u, /* counter_mask */ + 0, /* frequency */ + "TSC", /* name */ + 800, /* quality (adjusted in code) */ +}; + +void +init_TSC(void) +{ + u_int64_t tscval[2]; + + if (cpu_feature & CPUID_TSC) + tsc_present = 1; + else + tsc_present = 0; + + if (!tsc_present) + return; + + if (bootverbose) + printf("Calibrating TSC clock ... "); + + tscval[0] = rdtsc(); + DELAY(1000000); + tscval[1] = rdtsc(); + + tsc_freq = tscval[1] - tscval[0]; + if (bootverbose) + printf("TSC clock: %ju Hz\n", (intmax_t)tsc_freq); +} + +#if 0 /* XXX kardel XXX */ +#ifdef MULTIPROCESSOR +static int mp_tsc_ok = 0; + +SYSCTL_SETUP(sysctl_timecounter_setup, "sysctl timecounter setup") +{ + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, "tsc_ok", + "Indicates whether the TSC is safe to use in SMP mode", + NULL, 0, &mp_tsc_ok, 0, CTL_KERN, KERN_TIMECOUNTER, + CTL_CREATE, CTL_EOL); +} +#endif /* MULTIPROCESSOR */ +#endif /* XXX kardel XXX */ + +void +init_TSC_tc(void) +{ + +#if 0 /* XXXX check apm */ + /* + * We can not use the TSC if we support APM. Precise timekeeping + * on an APM'ed machine is at best a fools pursuit, since + * any and all of the time spent in various SMM code can't + * be reliably accounted for. Reading the RTC is your only + * source of reliable time info. The i8254 looses too of course + * but we need to have some kind of time... + * We don't know at this point whether APM is going to be used + * or not, nor when it might be activated. Play it safe. + */ + if (power_pm_get_type() == POWER_PM_TYPE_APM) { + tsc_timecounter.tc_quality = -1000; + if (bootverbose) + printf("TSC timecounter disabled: APM enabled.\n"); + } +#endif /* XXXX check apm */ + +#ifdef MULTIPROCESSOR +/* XXX timecounter - doesn't current netbsd code handle TSC on multiple CPUs? */ + /* + * We can not use the TSC in SMP mode unless the TSCs on all CPUs + * are somehow synchronized. Some hardware configurations do + * this, but we have no way of determining whether this is the + * case, so we do not use the TSC in multi-processor systems + * unless the user indicated (by setting kern.timecounter.smp_tsc + * to 1) that he believes that his TSCs are synchronized. + */ +#if 0 /* XXX timecounter XXX */ + if (mp_ncpus > 1 && !smp_tsc) +#endif /* XXX timecounter XXX */ + tsc_timecounter.tc_quality = -100; +#endif /* MULTIPROCESSOR */ + + if (tsc_present && tsc_freq != 0 && !tsc_is_broken) { + tsc_timecounter.tc_frequency = tsc_freq; + tc_init(&tsc_timecounter); + } +} + +#ifdef __FreeBSD__ /* XXXX */ +static int +sysctl_machdep_tsc_freq(SYSCTL_HANDLER_ARGS) +{ + int error; + uint64_t freq; + + if (tsc_timecounter.tc_frequency == 0) + return (EOPNOTSUPP); + freq = tsc_freq; + error = sysctl_handle_int(oidp, &freq, sizeof(freq), req); + if (error == 0 && req->newptr != NULL) { + tsc_freq = freq; + tsc_timecounter.tc_frequency = tsc_freq; + } + return (error); +} + +SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_QUAD | CTLFLAG_RW, + 0, sizeof(u_int), sysctl_machdep_tsc_freq, "IU", ""); +#endif /* __FreeBSD__ */ + +static u_int +tsc_get_timecount(struct timecounter *tc) +{ + + return (rdtsc()); +} Index: sys/arch/i386/include/clock.h =================================================================== RCS file: sys/arch/i386/include/clock.h diff -N sys/arch/i386/include/clock.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/i386/include/clock.h 22 Nov 2005 13:39:46 -0000 @@ -0,0 +1,6 @@ +/* $NetBSD$ */ + +/* XXX copyright */ + +void init_TSC(void); +void init_TSC_tc(void); Index: sys/arch/i386/include/cpu.h =================================================================== RCS file: /cvsroot/src/sys/arch/i386/include/cpu.h,v retrieving revision 1.118 diff -d -p -u -r1.118 cpu.h --- sys/arch/i386/include/cpu.h 11 Aug 2005 20:32:55 -0000 1.118 +++ sys/arch/i386/include/cpu.h 22 Nov 2005 13:39:47 -0000 @@ -296,11 +296,9 @@ struct clockframe { */ extern void (*delay_func)(int); struct timeval; -extern void (*microtime_func)(struct timeval *); #define DELAY(x) (*delay_func)(x) #define delay(x) (*delay_func)(x) -#define microtime(tv) (*microtime_func)(tv) /* * pull in #defines for kinds of processors Index: sys/arch/i386/include/types.h =================================================================== RCS file: /cvsroot/src/sys/arch/i386/include/types.h,v retrieving revision 1.45 diff -d -p -u -r1.45 types.h --- sys/arch/i386/include/types.h 18 Jan 2004 18:23:19 -0000 1.45 +++ sys/arch/i386/include/types.h 22 Nov 2005 13:39:47 -0000 @@ -72,6 +72,7 @@ typedef __volatile int __cpu_simple_loc #define __HAVE_OLD_DISKLABEL #define __HAVE_GENERIC_SOFT_INTERRUPTS #define __HAVE_CPU_MAXPROC +#define __HAVE_TIMECOUNTER #if defined(_KERNEL) #define __HAVE_RAS Index: sys/arch/i386/isa/clock.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/isa/clock.c,v retrieving revision 1.87 diff -d -p -u -r1.87 clock.c --- sys/arch/i386/isa/clock.c 29 May 2005 21:58:41 -0000 1.87 +++ sys/arch/i386/isa/clock.c 22 Nov 2005 13:39:48 -0000 @@ -1,3 +1,4 @@ +/* XXXXXXXXXXXXXXXXXXX lots of timecounter review needed here XXXXXXXXXXXXXXXXXXX */ /* $NetBSD: clock.c,v 1.87 2005/05/29 21:58:41 christos Exp $ */ /*- @@ -132,10 +133,12 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1. #include #include #include +#include #include #include #include +#include #include #include #include @@ -176,15 +179,15 @@ int clock_debug = 0; #define DPRINTF(arg) #endif -void spinwait(int); -int clockintr(void *, struct intrframe); -int gettick(void); -void sysbeep(int, int); -void rtcinit(void); -int rtcget(mc_todregs *); -void rtcput(mc_todregs *); -int bcdtobin(int); -int bintobcd(int); +int gettick(void); +void sysbeep(int, int); + +static int clockintr(void *, struct intrframe); +static void rtcinit(void); +static int rtcget(mc_todregs *); +static void rtcput(mc_todregs *); +static int bcdtobin(int); +static int bintobcd(int); static int cmoscheck(void); @@ -192,10 +195,27 @@ static int clock_expandyear(int); static inline int gettick_broken_latch(void); +int clkintr_pending; +static int timer0_max_count; + +static uint32_t i8254_lastcount; +static uint32_t i8254_offset; +static int i8254_ticked; __inline u_int mc146818_read(void *, u_int); __inline void mc146818_write(void *, u_int, u_int); +static u_int i8254_get_timecount(struct timecounter *); + +static struct timecounter i8254_timecounter = { + i8254_get_timecount, /* get_timecount */ + 0, /* no poll_pps */ + ~0u, /* counter_mask */ + TIMER_FREQ, /* frequency */ + "i8254", /* name */ + 0 /* quality */ +}; + /* XXX use sc? */ __inline u_int mc146818_read(void *sc, u_int reg) @@ -420,33 +440,16 @@ startrtclock(void) printf("RTC BIOS diagnostic error %s\n", bitmask_snprintf(s, NVRAM_DIAG_BITS, bits, sizeof(bits))); } + + tc_init(&i8254_timecounter); + + init_TSC(); } int clockintr(void *arg, struct intrframe frame) { -#if defined(I586_CPU) || defined(I686_CPU) - static int microset_iter; /* call cc_microset once/sec */ - struct cpu_info *ci = curcpu(); - - /* - * If we have a cycle counter, do the microset thing. - */ - if (ci->ci_feature_flags & CPUID_TSC) { - if ( -#if defined(MULTIPROCESSOR) - CPU_IS_PRIMARY(ci) && -#endif - (microset_iter--) == 0) { - cc_microset_time = time; - microset_iter = hz - 1; -#if defined(MULTIPROCESSOR) - x86_broadcast_ipi(X86_IPI_MICROSET); -#endif - cc_microset(ci); - } - } -#endif + /* XXX need IPIs to sync time on other CPUs with timecounters? */ hardclock((struct clockframe *)&frame); @@ -459,6 +462,36 @@ clockintr(void *arg, struct intrframe fr return -1; } +static u_int +i8254_get_timecount(struct timecounter *tc) +{ + u_int count; + u_int high, low; + u_long eflags; + + /* XXX geode stuff */ + + /* Don't want someone screwing with the counter while we're here. */ + eflags = read_eflags(); + disable_intr(); + + /* Select timer0 and latch counter value. */ + outb(IO_TIMER1 + TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); + + low = inb(IO_TIMER1 + TIMER_CNTR0); + high = inb(IO_TIMER1 + TIMER_CNTR0); + count = timer0_max_count - ((high << 8) | low); + if (count < i8254_lastcount || (!i8254_ticked && clkintr_pending)) { + i8254_ticked = 1; + i8254_offset += timer0_max_count; + } + i8254_lastcount = count; + count += i8254_offset; + + write_eflags(eflags); + return (count); +} + int gettick(void) { @@ -594,22 +627,10 @@ sysbeep(int pitch, int period) #endif } -#ifdef NTP -extern int fixtick; /* XXX */ -#endif /* NTP */ - void i8254_initclocks(void) { -#ifdef NTP - /* - * we'll actually get (TIMER_FREQ/rtclock_tval) interrupts/sec. - */ - fixtick = 1000000 - - ((int64_t)tick * TIMER_FREQ + rtclock_tval / 2) / rtclock_tval; -#endif /* NTP */ - /* * XXX If you're doing strange things with multiple clocks, you might * want to keep track of clock handlers. @@ -782,10 +803,9 @@ inittodr(time_t base) { mc_todregs rtclk; struct clock_ymdhms dt; + struct timespec ts; int s; -#if defined(I586_CPU) || defined(I686_CPU) - struct cpu_info *ci = curcpu(); -#endif + /* * We mostly ignore the suggested time (which comes from the * file system) and go for the RTC clock time stored in the @@ -844,20 +864,16 @@ inittodr(time_t base) } } - time.tv_sec = clock_ymdhms_to_secs(&dt) + rtc_offset * 60; + ts.tv_sec = clock_ymdhms_to_secs(&dt) + rtc_offset * 60; + ts.tv_nsec = 0; + tc_setclock(&ts); #ifdef DEBUG_CLOCK printf("readclock: %ld (%ld)\n", time.tv_sec, base); #endif -#if defined(I586_CPU) || defined(I686_CPU) - if (ci->ci_feature_flags & CPUID_TSC) { - cc_microset_time = time; - cc_microset(ci); - } -#endif - if (base != 0 && base < time.tv_sec - 5*SECYR) + if (base != 0 && base < time_second - 5*SECYR) printf("WARNING: file system time much less than clock time\n"); - else if (base > time.tv_sec + 5*SECYR) { + else if (base > time_second + 5*SECYR) { printf("WARNING: clock time much less than file system time\n"); printf("WARNING: using file system time\n"); goto fstime; @@ -868,7 +884,9 @@ inittodr(time_t base) fstime: timeset = 1; - time.tv_sec = base; + ts.tv_sec = base; + ts.tv_nsec = 0; + tc_setclock(&ts); printf("WARNING: CHECK AND RESET THE DATE!\n"); } @@ -895,7 +913,7 @@ resettodr(void) memset(&rtclk, 0, sizeof(rtclk)); splx(s); - clock_secs_to_ymdhms(time.tv_sec - rtc_offset * 60, &dt); + clock_secs_to_ymdhms(time_second - rtc_offset * 60, &dt); rtclk[MC_SEC] = bintobcd(dt.dt_sec); rtclk[MC_MIN] = bintobcd(dt.dt_min); Index: sys/arch/i386/pci/geodecntr.c =================================================================== RCS file: sys/arch/i386/pci/geodecntr.c diff -N sys/arch/i386/pci/geodecntr.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/i386/pci/geodecntr.c 22 Nov 2005 13:39:49 -0000 @@ -0,0 +1,138 @@ +/* $NetBSD: geodecntr.c,v 1.8 2005/06/28 00:28:41 thorpej Exp $ */ + +/*- + * Copyright (c) 2005 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Frank Kardel inspired from the patches to FreeBSD by Poul Henning Kamp + * + * 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. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: geodecntr.c,v 1.8 2005/06/28 00:28:41 thorpej Exp $"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define SC1100_CONFIG_GBA 0x64 + +#define SC1100_GBA_WD_L 0x00 +#define SC1100_GBA_WDST_B 0x04 +#define SC1100_GBA_TMVALUE_L 0x08 +#define SC1100_GBA_TMSTS_B 0x0c +#define SC1100_GBA_TMTS_OVFL 0x01 /* set: timer overflow */ +#define SC1100_GBA_TMCNFG_B 0x0d +#define SC1100_GBA_TMCNFG_TM27MPD 0x04 /* powerdown on SUSPA# */ +#define SC1100_GBA_TMCNFG_TMCLKSEL 0x02 /* set: 27MHz clock, clear: 1MHz */ +#define SC1100_GBA_TMCNFG_TMEN 0x01 /* enable timer interrupt */ +#define SC1100_GBA_IID_B 0x3c /* chip identification register */ +#define SC1100_GBA_REV_B 0x3d /* revision register */ +#define SC1100_GBA_LEN 0x40 + +struct geodecntr_softc { + struct device sc_dev; + + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; +}; + +static unsigned geode_get_timecount(struct timecounter *tc); + +static struct timecounter geode_timecounter = { + geode_get_timecount, + NULL, + 0xffffffff, + 27000000, + "Geode", + 1000 +}; + +static int +geodecntr_match(struct device *parent, struct cfdata *match, void *aux) +{ + struct pci_attach_args *pa = aux; + + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NS && + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NS_SC1100_XBUS) + return (1); + return (0); +} + +static void +geodecntr_attach(struct device *parent, struct device *self, void *aux) +{ + struct geodecntr_softc *sc = (struct geodecntr_softc *) self; + struct pci_attach_args *pa = aux; + pcireg_t reg; + aprint_naive("\n"); + aprint_normal("\n"); + + sc->sc_iot = pa->pa_iot; + + reg = pci_conf_read(pa->pa_pc, pa->pa_tag, SC1100_CONFIG_GBA); + + if (bus_space_map(sc->sc_iot, reg, SC1100_GBA_LEN, 0, &sc->sc_ioh)) { + aprint_error("%s: failed to map GBA space\n", + sc->sc_dev.dv_xname); + return; + } + + aprint_normal("%s: high resolution counter", self->dv_xname); + + /* + * select 27MHz, no powerdown, no interrupt + */ + bus_space_write_1(sc->sc_iot, sc->sc_ioh, SC1100_GBA_TMCNFG_B, + SC1100_GBA_TMCNFG_TMCLKSEL); + + aprint_normal("\n"); + geode_timecounter.tc_priv = sc; + tc_init(&geode_timecounter); + +} + +static unsigned geode_get_timecount(struct timecounter *tc) +{ + struct geodecntr_softc *sc = (struct geodecntr_softc *)tc->tc_priv; + + return bus_space_read_4(sc->sc_iot, sc->sc_ioh, SC1100_GBA_TMVALUE_L); +} + +CFATTACH_DECL(geodecntr, sizeof(struct geodecntr_softc), + geodecntr_match, geodecntr_attach, NULL, NULL); Index: sys/arch/macppc/dev/adb_direct.c =================================================================== RCS file: /cvsroot/src/sys/arch/macppc/dev/adb_direct.c,v retrieving revision 1.32 diff -d -p -u -r1.32 adb_direct.c --- sys/arch/macppc/dev/adb_direct.c 5 Jun 2005 20:03:55 -0000 1.32 +++ sys/arch/macppc/dev/adb_direct.c 22 Nov 2005 13:39:53 -0000 @@ -1461,7 +1461,7 @@ set_adb_info(ADBSetInfoBlock * info, int /* caller should really use machine-independant version: getPramTime */ /* this version does pseudo-adb access only */ int -adb_read_date_time(unsigned long *time) +adb_read_date_time(unsigned long *t) { u_char output[ADB_MAX_MSG_LENGTH]; int result; @@ -1469,7 +1469,7 @@ adb_read_date_time(unsigned long *time) switch (adbHardware) { case ADB_HW_PMU: - pm_read_date_time(time); + pm_read_date_time(t); return 0; case ADB_HW_CUDA: @@ -1484,7 +1484,7 @@ adb_read_date_time(unsigned long *time) while (0 == flag) /* wait for result */ ; - memcpy(time, output + 1, 4); + memcpy(t, output + 1, 4); return 0; case ADB_HW_UNKNOWN: @@ -1496,7 +1496,7 @@ adb_read_date_time(unsigned long *time) /* caller should really use machine-independant version: setPramTime */ /* this version does pseudo-adb access only */ int -adb_set_date_time(unsigned long time) +adb_set_date_time(unsigned long t) { u_char output[ADB_MAX_MSG_LENGTH]; int result; @@ -1508,10 +1508,10 @@ adb_set_date_time(unsigned long time) output[0] = 0x06; /* 6 byte message */ output[1] = 0x01; /* to pram/rtc device */ output[2] = 0x09; /* set date/time */ - output[3] = (u_char)(time >> 24); - output[4] = (u_char)(time >> 16); - output[5] = (u_char)(time >> 8); - output[6] = (u_char)(time); + output[3] = (u_char)(t >> 24); + output[4] = (u_char)(t >> 16); + output[5] = (u_char)(t >> 8); + output[6] = (u_char)(t); result = send_adb_cuda((u_char *)output, (u_char *)0, adb_op_comprout, &flag, (int)0); if (result != 0) /* exit if not sent */ @@ -1523,7 +1523,7 @@ adb_set_date_time(unsigned long time) return 0; case ADB_HW_PMU: - pm_set_date_time(time); + pm_set_date_time(t); return 0; case ADB_HW_UNKNOWN: Index: sys/arch/macppc/dev/pm_direct.c =================================================================== RCS file: /cvsroot/src/sys/arch/macppc/dev/pm_direct.c,v retrieving revision 1.28 diff -d -p -u -r1.28 pm_direct.c --- sys/arch/macppc/dev/pm_direct.c 7 Jun 2005 12:14:13 -0000 1.28 +++ sys/arch/macppc/dev/pm_direct.c 22 Nov 2005 13:39:55 -0000 @@ -862,8 +862,8 @@ pm_adb_poweroff() } void -pm_read_date_time(time) - u_long *time; +pm_read_date_time(t) + u_long *t; { PMData p; @@ -873,19 +873,19 @@ pm_read_date_time(time) p.r_buf = p.data; pmgrop(&p); - memcpy(time, p.data, 4); + memcpy(t, p.data, 4); } void -pm_set_date_time(time) - u_long time; +pm_set_date_time(t) + u_long t; { PMData p; p.command = PMU_SET_RTC; p.num_data = 4; p.s_buf = p.r_buf = p.data; - memcpy(p.data, &time, 4); + memcpy(p.data, &t, 4); pmgrop(&p); } Index: sys/arch/x86/x86/lapic.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/x86/lapic.c,v retrieving revision 1.12 diff -d -p -u -r1.12 lapic.c --- sys/arch/x86/x86/lapic.c 29 May 2005 21:36:40 -0000 1.12 +++ sys/arch/x86/x86/lapic.c 22 Nov 2005 13:40:09 -0000 @@ -42,8 +42,8 @@ __KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.12 2005/05/29 21:36:40 christos Exp $"); #include "opt_ddb.h" -#include "opt_multiprocessor.h" #include "opt_mpbios.h" /* for MPDEBUG */ +#include "opt_multiprocessor.h" #include "opt_ntp.h" #include @@ -235,7 +235,8 @@ u_int32_t lapic_delaytab[26]; void lapic_clockintr(void *arg, struct intrframe frame) { -#if defined(I586_CPU) || defined(I686_CPU) || defined(__x86_64__) +#if !defined(__HAVE_TIMECOUNTER) && \ + (defined(I586_CPU) || defined(I686_CPU) || defined(__x86_64__)) static int microset_iter; /* call cc_microset once/sec */ struct cpu_info *ci = curcpu(); @@ -258,26 +259,26 @@ lapic_clockintr(void *arg, struct intrfr cc_microset(ci); } } -#endif +#endif /* !__HAVE_TIMECOUNTER && (I586_CPU || I686_CPU || __x86_64__) */ hardclock((struct clockframe *)&frame); } -#ifdef NTP +#if !defined(__HAVE_TIMECOUNTER) && defined(NTP) extern int fixtick; -#endif /* NTP */ +#endif /* !__HAVE_TIMECOUNTER && NTP */ void lapic_initclocks() { -#ifdef NTP +#if !defined(__HAVE_TIMECOUNTER) && defined(NTP) /* * we'll actually get (lapic_per_second/lapic_tval) interrupts/sec. */ fixtick = 1000000 - ((int64_t)tick * lapic_per_second + lapic_tval / 2) / lapic_tval; -#endif /* NTP */ +#endif /* !__HAVE_TIMECOUNTER && NTP */ /* * Start local apic countdown timer running, in repeated mode. Index: sys/arch/x86/x86/mtrr_i686.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/x86/mtrr_i686.c,v retrieving revision 1.3 diff -d -p -u -r1.3 mtrr_i686.c --- sys/arch/x86/x86/mtrr_i686.c 1 Nov 2003 17:00:50 -0000 1.3 +++ sys/arch/x86/x86/mtrr_i686.c 22 Nov 2005 13:40:10 -0000 @@ -127,8 +127,6 @@ struct mtrr_funcs i686_mtrr_funcs = { static volatile uint32_t mtrr_waiting; #endif -static uint64_t i686_mtrr_cap; - static void i686_mtrr_dump(const char *tag) { @@ -297,7 +295,6 @@ i686_mtrr_init_first(void) for (i = 0; i < nmtrr_raw; i++) mtrr_raw[i].msrval = rdmsr(mtrr_raw[i].msraddr); - i686_mtrr_cap = rdmsr(MSR_MTRRcap); #if 0 mtrr_dump("init mtrr"); #endif Index: sys/compat/linux/common/linux_misc.c =================================================================== RCS file: /cvsroot/src/sys/compat/linux/common/linux_misc.c,v retrieving revision 1.143 diff -d -p -u -r1.143 linux_misc.c --- sys/compat/linux/common/linux_misc.c 7 Nov 2005 14:17:45 -0000 1.143 +++ sys/compat/linux/common/linux_misc.c 22 Nov 2005 13:40:15 -0000 @@ -754,7 +754,7 @@ linux_sys_times(l, v, retval) } */ *uap = v; struct proc *p = l->l_proc; struct timeval t; - int error, s; + int error; if (SCARG(uap, tms)) { struct linux_tms ltms; @@ -771,9 +771,7 @@ linux_sys_times(l, v, retval) return error; } - s = splclock(); - timersub(&time, &boottime, &t); - splx(s); + getmicrouptime(&t); retval[0] = ((linux_clock_t)(CONVTCK(t))); return 0; @@ -1593,7 +1591,7 @@ linux_sys_sysinfo(l, v, retval) struct linux_sysinfo si; struct loadavg *la; - si.uptime = time.tv_sec - boottime.tv_sec; + si.uptime = time_uptime; la = &averunnable; si.loads[0] = la->ldavg[0] * LINUX_SYSINFO_LOADS_SCALE / la->fscale; si.loads[1] = la->ldavg[1] * LINUX_SYSINFO_LOADS_SCALE / la->fscale; Index: sys/compat/linux/common/linux_misc_notalpha.c =================================================================== RCS file: /cvsroot/src/sys/compat/linux/common/linux_misc_notalpha.c,v retrieving revision 1.74 diff -d -p -u -r1.74 linux_misc_notalpha.c --- sys/compat/linux/common/linux_misc_notalpha.c 3 May 2005 16:26:28 -0000 1.74 +++ sys/compat/linux/common/linux_misc_notalpha.c 22 Nov 2005 13:40:15 -0000 @@ -100,9 +100,10 @@ linux_sys_alarm(l, v, retval) syscallarg(unsigned int) secs; } */ *uap = v; struct proc *p = l->l_proc; - int s; + struct timeval now; struct itimerval *itp, it; struct ptimer *ptp; + int s; if (p->p_timers && p->p_timers->pts_timers[ITIMER_REAL]) itp = &p->p_timers->pts_timers[ITIMER_REAL]->pt_time; @@ -115,9 +116,10 @@ linux_sys_alarm(l, v, retval) if (itp) { callout_stop(&p->p_timers->pts_timers[ITIMER_REAL]->pt_ch); timerclear(&itp->it_interval); + getmicrotime(&now); if (timerisset(&itp->it_value) && - timercmp(&itp->it_value, &time, >)) - timersub(&itp->it_value, &time, &itp->it_value); + timercmp(&itp->it_value, &now, >)) + timersub(&itp->it_value, &now, &itp->it_value); /* * Return how many seconds were left (rounded up) */ @@ -169,7 +171,8 @@ linux_sys_alarm(l, v, retval) * Don't need to check hzto() return value, here. * callout_reset() does it for us. */ - timeradd(&it.it_value, &time, &it.it_value); + getmicrotime(&now); + timeradd(&it.it_value, &now, &it.it_value); callout_reset(&ptp->pt_ch, hzto(&it.it_value), realtimerexpire, ptp); } Index: sys/conf/files =================================================================== RCS file: /cvsroot/src/sys/conf/files,v retrieving revision 1.740 diff -d -p -u -r1.740 files --- sys/conf/files 18 Nov 2005 21:55:14 -0000 1.740 +++ sys/conf/files 22 Nov 2005 13:40:19 -0000 @@ -14,15 +14,15 @@ devclass tty # (note, these are case-sensitive) # defflag INSECURE -defflag MBUFTRACE -defflag KMEMSTATS defflag KCONT +defflag KMEMSTATS defflag KTRACE +defflag MBUFTRACE defflag SYSTRACE +defparam DEFCORENAME +defparam HZ defparam MAXUPRC defparam RTC_OFFSET -defparam HZ -defparam DEFCORENAME defflag opt_pipe.h PIPE_SOCKETPAIR PIPE_NODIRECT defflag BUFQ_DISKSORT @@ -1247,6 +1247,7 @@ file kern/kern_systrace.c systrace file kern/kern_subr.c file kern/kern_synch.c file kern/kern_sysctl.c +file kern/kern_tc.c file kern/kern_time.c file kern/kern_timeout.c file kern/kern_uuid.c Index: sys/contrib/dev/ic/athhal_osdep.c =================================================================== RCS file: /cvsroot/src/sys/contrib/dev/ic/athhal_osdep.c,v retrieving revision 1.5 diff -d -p -u -r1.5 athhal_osdep.c --- sys/contrib/dev/ic/athhal_osdep.c 19 Oct 2005 09:04:23 -0000 1.5 +++ sys/contrib/dev/ic/athhal_osdep.c 22 Nov 2005 13:40:20 -0000 @@ -407,16 +407,11 @@ ath_hal_delay(int n) u_int32_t ath_hal_getuptime(struct ath_hal *ah) { - struct timeval boot, cur, diff; - int s; - s = splclock(); - boot = boottime; - cur = time; - splx(s); - - timersub(&cur, &boot, &diff); + /* XXX nothing seems to use this function! */ + struct timeval tv; - return diff.tv_sec * 1000 + diff.tv_usec / 1000; + getmicrouptime(&tv); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; } void Index: sys/dev/clockctl.c =================================================================== RCS file: /cvsroot/src/sys/dev/clockctl.c,v retrieving revision 1.13 diff -d -p -u -r1.13 clockctl.c --- sys/dev/clockctl.c 27 Feb 2005 00:26:58 -0000 1.13 +++ sys/dev/clockctl.c 22 Nov 2005 13:40:20 -0000 @@ -93,6 +93,7 @@ clockctlioctl(dev, cmd, data, flags, p) struct sys_adjtime_args *args = (struct sys_adjtime_args *)data; + /* XXX kardel - why FreeBSD kern_adjtime here? */ error = adjtime1(SCARG(args, delta), SCARG(args, olddelta), p); if (error) Index: sys/dev/mm.c =================================================================== RCS file: /cvsroot/src/sys/dev/mm.c,v retrieving revision 1.6 diff -d -p -u -r1.6 mm.c --- sys/dev/mm.c 20 Dec 2003 16:22:14 -0000 1.6 +++ sys/dev/mm.c 22 Nov 2005 13:40:20 -0000 @@ -78,6 +78,6 @@ mmioctl(dev, cmd, data, flag, p) return 0; /*FALLTHROUGH*/ } - return EOPNOTSUPP; + return EOPNOTSUPP; /* XXXsimonb: ENOTTY here too? */ } } Index: sys/dev/ic/com.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/com.c,v retrieving revision 1.237 diff -d -p -u -r1.237 com.c --- sys/dev/ic/com.c 6 Nov 2005 21:34:37 -0000 1.237 +++ sys/dev/ic/com.c 22 Nov 2005 13:40:25 -0000 @@ -218,11 +218,13 @@ static int comconsrate; static tcflag_t comconscflag; static struct cnm_state com_cnm_state; +#ifndef __HAVE_TIMECOUNTER static int ppscap = PPS_TSFMT_TSPEC | PPS_CAPTUREASSERT | PPS_CAPTURECLEAR | PPS_OFFSETASSERT | PPS_OFFSETCLEAR; +#endif /* !__HAVE_TIMECOUNTER */ #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS #ifdef __NO_SOFT_SERIAL_INTERRUPT @@ -762,9 +764,11 @@ com_shutdown(struct com_softc *sc) /* Clear any break condition set with TIOCSBRK. */ com_break(sc, 0); +#ifndef __HAVE_TIMECOUNTER /* Turn off PPS capture on last close. */ sc->sc_ppsmask = 0; sc->ppsparam.mode = 0; +#endif /* !__HAVE_TIMECOUNTER */ /* * Hang up if necessary. Wait a bit, so the other side has time to @@ -879,8 +883,14 @@ comopen(dev_t dev, int flag, int mode, s sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr); /* Clear PPS capture state on first open. */ +#ifdef __HAVE_TIMECOUNTER + 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); +#else /* !__HAVE_TIMECOUNTER */ sc->sc_ppsmask = 0; sc->ppsparam.mode = 0; +#endif /* !__HAVE_TIMECOUNTER */ COM_UNLOCK(sc); splx(s2); @@ -1099,6 +1109,19 @@ comioctl(dev_t dev, u_long cmd, caddr_t *(int *)data = com_to_tiocm(sc); break; +#ifdef __HAVE_TIMECOUNTER + case PPS_IOC_CREATE: + case PPS_IOC_DESTROY: + case PPS_IOC_GETPARAMS: + case PPS_IOC_SETPARAMS: + case PPS_IOC_GETCAP: + case PPS_IOC_FETCH: +#ifdef PPS_SYNC + case PPS_IOC_KCBIND: +#endif + error = pps_ioctl(cmd, data, &sc->sc_pps_state); + break; +#else /* !__HAVE_TIMECOUNTER */ case PPS_IOC_CREATE: break; @@ -1191,8 +1214,18 @@ comioctl(dev_t dev, u_long cmd, caddr_t break; } #endif /* PPS_SYNC */ +#endif /* !__HAVE_TIMECOUNTER */ case TIOCDCDTIMESTAMP: /* XXX old, overloaded API used by xntpd v3 */ +#ifdef __HAVE_TIMECOUNTER +#ifndef PPS_TRAILING_EDGE + TIMESPEC_TO_TIMEVAL((struct timeval *)data, + &sc->sc_pps_state.ppsinfo.assert_timestamp); +#else + TIMESPEC_TO_TIMEVAL((struct timeval *)data, + &sc->sc_pps_state.ppsinfo.clear_timestamp); +#endif +#else /* !__HAVE_TIMECOUNTER */ /* * Some GPS clocks models use the falling rather than * rising edge as the on-the-second signal. @@ -1210,6 +1243,7 @@ comioctl(dev_t dev, u_long cmd, caddr_t TIMESPEC_TO_TIMEVAL((struct timeval *)data, &sc->ppsinfo.clear_timestamp); #endif +#endif /* !__HAVE_TIMECOUNTER */ break; default: @@ -2151,6 +2185,16 @@ again: do { msr = bus_space_read_1(iot, ioh, com_msr); delta = msr ^ sc->sc_msr; sc->sc_msr = msr; +#ifdef __HAVE_TIMECOUNTER + if ((sc->sc_pps_state.ppsparam.mode & PPS_CAPTUREBOTH) && + (delta & MSR_DCD)) { + pps_capture(&sc->sc_pps_state); + pps_event(&sc->sc_pps_state, + (msr & MSR_DCD) ? + PPS_CAPTUREASSERT : + PPS_CAPTURECLEAR); + } +#else /* !__HAVE_TIMECOUNTER */ /* * Pulse-per-second (PSS) signals on edge of DCD? * Process these even if line discipline is ignoring DCD. @@ -2198,6 +2242,7 @@ again: do { sc->ppsinfo.current_mode = sc->ppsparam.mode; } } +#endif /* !__HAVE_TIMECOUNTER */ /* * Process normal status changes Index: sys/dev/ic/comvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/comvar.h,v retrieving revision 1.48 diff -d -p -u -r1.48 comvar.h --- sys/dev/ic/comvar.h 4 Feb 2005 02:10:36 -0000 1.48 +++ sys/dev/ic/comvar.h 22 Nov 2005 13:40:27 -0000 @@ -139,12 +139,16 @@ struct com_softc { void (*disable)(struct com_softc *); int enabled; +#ifdef __HAVE_TIMECOUNTER + struct pps_state sc_pps_state; /* pps state */ +#else /* !__HAVE_TIMECOUNTER */ /* PPS signal on DCD, with or without inkernel clock disciplining */ u_char sc_ppsmask; /* pps signal mask */ u_char sc_ppsassert; /* pps leading edge */ u_char sc_ppsclear; /* pps trailing edge */ pps_info_t ppsinfo; pps_params_t ppsparam; +#endif /* !__HAVE_TIMECOUNTER */ #if NRND > 0 && defined(RND_COM) rndsource_element_t rnd_source; Index: sys/dev/ic/hd64570.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/hd64570.c,v retrieving revision 1.29 diff -d -p -u -r1.29 hd64570.c --- sys/dev/ic/hd64570.c 27 Feb 2005 00:27:01 -0000 1.29 +++ sys/dev/ic/hd64570.c 22 Nov 2005 13:40:30 -0000 @@ -413,6 +413,7 @@ sca_init(struct sca_softc *sc) void sca_port_attach(struct sca_softc *sc, u_int port) { + struct timeval now; sca_port_t *scp = &sc->sc_ports[port]; struct ifnet *ifp; static u_int ntwo_unit = 0; @@ -475,7 +476,8 @@ sca_port_attach(struct sca_softc *sc, u_ /* * reset the last seen times on the cisco keepalive protocol */ - scp->cka_lasttx = time.tv_usec; + getmicrotime(&now); + scp->cka_lasttx = now.tv_usec; scp->cka_lastrx = 0; } @@ -1568,7 +1570,7 @@ sca_frame_process(sca_port_t *scp) u_int16_t len; u_int32_t t; - t = (time.tv_sec - boottime.tv_sec) * 1000; + t = time_uptime * 1000; desc = &scp->sp_rxdesc[scp->sp_rxstart]; bufp = scp->sp_rxbuf + SCA_BSIZE * scp->sp_rxstart; len = sca_desc_read_buflen(scp->sca, desc); @@ -1821,6 +1823,7 @@ static void sca_port_up(sca_port_t *scp) { struct sca_softc *sc = scp->sca; + struct timeval now; #if 0 u_int8_t ier0, ier1; #endif @@ -1885,7 +1888,8 @@ sca_port_up(sca_port_t *scp) */ scp->sp_txinuse = 0; scp->sp_txcur = 0; - scp->cka_lasttx = time.tv_usec; + getmicrotime(&now); + scp->cka_lasttx = now.tv_usec; scp->cka_lastrx = 0; } Index: sys/dev/ic/icp.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/icp.c,v retrieving revision 1.16 diff -d -p -u -r1.16 icp.c --- sys/dev/ic/icp.c 25 Aug 2005 22:33:19 -0000 1.16 +++ sys/dev/ic/icp.c 22 Nov 2005 13:40:33 -0000 @@ -1321,7 +1321,7 @@ icp_store_event(struct icp_softc *icp, u (evt->size == 0 && e->event_data.size == 0 && strcmp((char *) e->event_data.event_string, (char *) evt->event_string) == 0))) { - e->last_stamp = time.tv_sec; + e->last_stamp = time_second; e->same_count++; } else { if (icp_event_buffer[icp_event_lastidx].event_source != 0) { @@ -1337,7 +1337,7 @@ icp_store_event(struct icp_softc *icp, u e = &icp_event_buffer[icp_event_lastidx]; e->event_source = source; e->event_idx = idx; - e->first_stamp = e->last_stamp = time.tv_sec; + e->first_stamp = e->last_stamp = time_second; e->same_count = 1; e->event_data = *evt; e->application = 0; Index: sys/dev/ic/mlx.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/mlx.c,v retrieving revision 1.36 diff -d -p -u -r1.36 mlx.c --- sys/dev/ic/mlx.c 25 Aug 2005 22:33:19 -0000 1.36 +++ sys/dev/ic/mlx.c 22 Nov 2005 13:40:36 -0000 @@ -135,8 +135,6 @@ static int mlx_rebuild(struct mlx_softc static void mlx_shutdown(void *); static int mlx_user_command(struct mlx_softc *, struct mlx_usercommand *); -static __inline__ time_t mlx_curtime(void); - dev_type_open(mlxopen); dev_type_close(mlxclose); dev_type_ioctl(mlxioctl); @@ -254,23 +252,6 @@ struct { }; /* - * Return the current time in seconds - we're not particularly interested in - * precision here. - */ -static __inline__ time_t -mlx_curtime(void) -{ - time_t rt; - int s; - - s = splclock(); - rt = mono_time.tv_sec; - splx(s); - - return (rt); -} - -/* * Initialise the controller and our interface. */ void @@ -810,7 +791,7 @@ mlxioctl(dev_t dev, u_long cmd, caddr_t /* Looks ok, go with it. */ mlx->mlx_pause.mp_which = mp->mp_which; - mlx->mlx_pause.mp_when = mlx_curtime() + mp->mp_when; + mlx->mlx_pause.mp_when = time_second + mp->mp_when; mlx->mlx_pause.mp_howlong = mlx->mlx_pause.mp_when + mp->mp_howlong; @@ -999,13 +980,10 @@ mlx_periodic(struct mlx_softc *mlx) { struct mlx_ccb *mc, *nmc; int etype, s; - time_t ct; - - ct = mlx_curtime(); if ((mlx->mlx_pause.mp_which != 0) && (mlx->mlx_pause.mp_when > 0) && - (ct >= mlx->mlx_pause.mp_when)) { + (time_second >= mlx->mlx_pause.mp_when)) { /* * Start bus pause. */ @@ -1016,15 +994,15 @@ mlx_periodic(struct mlx_softc *mlx) /* * Stop pause if required. */ - if (ct >= mlx->mlx_pause.mp_howlong) { + if (time_second >= mlx->mlx_pause.mp_howlong) { mlx_pause_action(mlx); mlx->mlx_pause.mp_which = 0; } - } else if (ct > (mlx->mlx_lastpoll + 10)) { + } else if (time_second > (mlx->mlx_lastpoll + 10)) { /* * Run normal periodic activities... */ - mlx->mlx_lastpoll = ct; + mlx->mlx_lastpoll = time_second; /* * Check controller status. @@ -1068,7 +1046,7 @@ mlx_periodic(struct mlx_softc *mlx) s = splbio(); for (mc = TAILQ_FIRST(&mlx->mlx_ccb_worklist); mc != NULL; mc = nmc) { nmc = TAILQ_NEXT(mc, mc_chain.tailq); - if (mc->mc_expiry > ct) { + if (mc->mc_expiry > time_second) { /* * The remaining CCBs will expire after this one, so * there's no point in going further. @@ -1479,9 +1457,6 @@ mlx_pause_action(struct mlx_softc *mlx) { struct mlx_ccb *mc; int failsafe, i, cmd; - time_t ct; - - ct = mlx_curtime(); /* What are we doing here? */ if (mlx->mlx_pause.mp_when == 0) { @@ -1495,11 +1470,12 @@ mlx_pause_action(struct mlx_softc *mlx) * period, which is specified in multiples of 30 seconds. * This constrains us to a maximum pause of 450 seconds. */ - failsafe = ((mlx->mlx_pause.mp_howlong - ct) + 5) / 30; + failsafe = ((mlx->mlx_pause.mp_howlong - time_second) + 5) / 30; if (failsafe > 0xf) { failsafe = 0xf; - mlx->mlx_pause.mp_howlong = ct + (0xf * 30) - 5; + mlx->mlx_pause.mp_howlong = + time_second + (0xf * 30) - 5; } } @@ -1542,7 +1518,7 @@ mlx_pause_done(struct mlx_ccb *mc) else if (command == MLX_CMD_STOPCHANNEL) printf("%s: channel %d pausing for %ld seconds\n", mlx->mlx_dv.dv_xname, channel, - (long)(mlx->mlx_pause.mp_howlong - mlx_curtime())); + (long)(mlx->mlx_pause.mp_howlong - time_second)); else printf("%s: channel %d resuming\n", mlx->mlx_dv.dv_xname, channel); @@ -2087,7 +2063,7 @@ mlx_ccb_submit(struct mlx_softc *mlx, st /* Mark the command as currently being processed. */ mc->mc_status = MLX_STATUS_BUSY; - mc->mc_expiry = mlx_curtime() + MLX_TIMEOUT; + mc->mc_expiry = time_second + MLX_TIMEOUT; /* Spin waiting for the mailbox. */ for (i = 100; i != 0; i--) { Index: sys/dev/ic/ncr53c9x.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/ncr53c9x.c,v retrieving revision 1.116 diff -d -p -u -r1.116 ncr53c9x.c --- sys/dev/ic/ncr53c9x.c 6 Nov 2005 10:31:46 -0000 1.116 +++ sys/dev/ic/ncr53c9x.c 22 Nov 2005 13:40:41 -0000 @@ -1110,7 +1110,7 @@ ncr53c9x_sched(sc) if (lun < NCR_NLUN) ti->lun[lun] = li; } - li->last_used = time.tv_sec; + li->last_used = time_second; if (tag == 0) { /* Try to issue this as an un-tagged command */ if (li->untagged == NULL) @@ -2948,7 +2948,7 @@ ncr53c9x_watch(arg) struct ncr53c9x_linfo *li; int t, s; /* Delete any structures that have not been used in 10min. */ - time_t old = time.tv_sec - (10 * 60); + time_t old = time_second - (10 * 60); s = splbio(); simple_lock(&sc->sc_lock); Index: sys/dev/ic/nslm7x.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/nslm7x.c,v retrieving revision 1.23 diff -d -p -u -r1.23 nslm7x.c --- sys/dev/ic/nslm7x.c 15 Oct 2005 00:41:48 -0000 1.23 +++ sys/dev/ic/nslm7x.c 22 Nov 2005 13:40:42 -0000 @@ -512,27 +512,20 @@ lm_gtredata(sme, tred) struct sysmon_envsys *sme; struct envsys_tre_data *tred; { - static const struct timeval onepointfive = { 1, 500000 }; - struct timeval t; - struct lm_softc *sc = sme->sme_cookie; - int i, s; - - /* read new values at most once every 1.5 seconds */ - timeradd(&sc->lastread, &onepointfive, &t); - s = splclock(); - i = timercmp(&mono_time, &t, >); - if (i) { - sc->lastread.tv_sec = mono_time.tv_sec; - sc->lastread.tv_usec = mono_time.tv_usec; - } - splx(s); + static const struct timeval onepointfive = { 1, 500000 }; + struct timeval t, utv; + struct lm_softc *sc = sme->sme_cookie; - if (i) - sc->refresh_sensor_data(sc); + /* read new values at most once every 1.5 seconds */ + getmicrouptime(&utv); + timeradd(&sc->lastread, &onepointfive, &t); + if (timercmp(&utv, &t, >)) { + sc->lastread = utv; + sc->refresh_sensor_data(sc); - *tred = sc->sensors[tred->sensor]; + *tred = sc->sensors[tred->sensor]; - return 0; + return 0; } int Index: sys/dev/ic/z8530tty.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/z8530tty.c,v retrieving revision 1.100 diff -d -p -u -r1.100 z8530tty.c --- sys/dev/ic/z8530tty.c 6 Sep 2005 21:40:39 -0000 1.100 +++ sys/dev/ic/z8530tty.c 22 Nov 2005 13:40:47 -0000 @@ -236,10 +236,14 @@ struct zstty_softc { /* PPS signal on DCD, with or without inkernel clock disciplining */ u_char zst_ppsmask; /* pps signal mask */ +#ifdef __HAVE_TIMECOUNTER + struct pps_state zst_pps_state; +#else /* !__HAVE_TIMECOUNTER */ u_char zst_ppsassert; /* pps leading edge */ u_char zst_ppsclear; /* pps trailing edge */ pps_info_t ppsinfo; pps_params_t ppsparam; +#endif /* !__HAVE_TIMECOUNTER */ }; /* Macros to clear/set/test flags. */ @@ -506,9 +510,11 @@ zs_shutdown(zst) /* Clear any break condition set with TIOCSBRK. */ zs_break(cs, 0); +#ifndef __HAVE_TIMECOUNTER /* Turn off PPS capture on last close. */ zst->zst_ppsmask = 0; zst->ppsparam.mode = 0; +#endif /* __HAVE_TIMECOUNTER */ /* * Hang up if necessary. Wait a bit, so the other side has time to @@ -632,7 +638,13 @@ zsopen(dev, flags, mode, p) /* Clear PPS capture state on first open. */ zst->zst_ppsmask = 0; +#ifdef __HAVE_TIMECOUNTER + memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state)); + sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; + pps_init(&zst->zst_pps_state); +#else /* !__HAVE_TIMECOUNTER */ zst->ppsparam.mode = 0; +#endif /* !__HAVE_TIMECOUNTER */ simple_unlock(&cs->cs_lock); splx(s2); @@ -847,6 +859,23 @@ zsioctl(dev, cmd, data, flag, p) *(int *)data = zs_to_tiocm(zst); break; +#ifdef __HAVE_TIMECOUNTER + case PPS_IOC_CREATE: + case PPS_IOC_DESTROY: + case PPS_IOC_GETPARAMS: + case PPS_IOC_SETPARAMS: + case PPS_IOC_GETCAP: + case PPS_IOC_FETCH: +#ifdef PPS_SYNC + case PPS_IOC_KCBIND: +#endif + error = pps_ioctl(cmd, data, &zst->zst_pps_state); + if (zst->zst_pps_state.ppsparm.mode & PPS_CAPTUREBOTH) + zst->zst_ppsmask = ZSRR0_DCD; + else + zst->zst_ppsmask = 0; + break; +#else /* !__HAVE_TIMECOUNTER */ case PPS_IOC_CREATE: break; @@ -961,17 +990,22 @@ zsioctl(dev, cmd, data, flag, p) break; } #endif /* PPS_SYNC */ +#endif /* !__HAVE_TIMECOUNTER */ case TIOCDCDTIMESTAMP: /* XXX old, overloaded API used by xntpd v3 */ if (cs->cs_rr0_pps == 0) { error = EINVAL; break; } - /* - * Some GPS clocks models use the falling rather than - * rising edge as the on-the-second signal. - * The old API has no way to specify PPS polarity. - */ +#ifdef __HAVE_TIMECOUNTER +#ifndef PPS_TRAILING_EDGE + TIMESPEC_TO_TIMEVAL((struct timeval *)data, + &sc->sc_pps_state.ppsinfo.assert_timestamp); +#else + TIMESPEC_TO_TIMEVAL((struct timeval *)data, + &sc->sc_pps_state.ppsinfo.clear_timestamp); +#endif +#else /* !__HAVE_TIMECOUNTER */ zst->zst_ppsmask = ZSRR0_DCD; #ifndef PPS_TRAILING_EDGE zst->zst_ppsassert = ZSRR0_DCD; @@ -984,6 +1018,7 @@ zsioctl(dev, cmd, data, flag, p) TIMESPEC_TO_TIMEVAL((struct timeval *)data, &zst->ppsinfo.clear_timestamp); #endif +#endif /* !__HAVE_TIMECOUNTER */ /* * Now update interrupts. */ @@ -1652,6 +1687,15 @@ zstty_stint(cs, force) * Pulse-per-second clock signal on edge of DCD? */ if (ISSET(delta, zst->zst_ppsmask)) { +#ifdef __HAVE_TIMECOUNTER + if (zst->sc_pps_state.ppsparam.mode & PPS_CAPTUREBOTH) { + pps_capture(&zst->sc_pps_state); + pps_event(&zst->sc_pps_state, + (ISSET(cs->cs_rr0, zst->zst_ppsmask)) + ? PPS_CAPTUREASSERT + : PPS_CAPTURECLEAR); + } +#else /* !__HAVE_TIMECOUNTER */ struct timeval tv; if (ISSET(rr0, zst->zst_ppsmask) == zst->zst_ppsassert) { /* XXX nanotime() */ @@ -1693,6 +1737,7 @@ zstty_stint(cs, force) zst->ppsinfo.clear_sequence++; zst->ppsinfo.current_mode = zst->ppsparam.mode; } +#endif /* !__HAVE_TIMECOUNTER */ } /* Index: sys/dev/pci/amr.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/amr.c,v retrieving revision 1.29 diff -d -p -u -r1.29 amr.c --- sys/dev/pci/amr.c 26 Aug 2005 11:20:33 -0000 1.29 +++ sys/dev/pci/amr.c 22 Nov 2005 13:40:50 -0000 @@ -813,7 +813,6 @@ amr_thread(void *cookie) struct amr_ccb *ac; struct amr_logdrive *al; struct amr_enquiry *ae; - time_t curtime; int rv, i, s; amr = cookie; @@ -830,10 +829,9 @@ amr_thread(void *cookie) s = splbio(); amr_intr(cookie); - curtime = (time_t)mono_time.tv_sec; ac = TAILQ_FIRST(&amr->amr_ccb_active); while (ac != NULL) { - if (ac->ac_start_time + AMR_TIMEOUT > curtime) + if (ac->ac_start_time + AMR_TIMEOUT > time_uptime) break; if ((ac->ac_flags & AC_MOAN) == 0) { printf("%s: ccb %d timed out; mailbox:\n", @@ -1169,7 +1167,7 @@ amr_quartz_submit(struct amr_softc *amr, bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0, sizeof(struct amr_mailbox), BUS_DMASYNC_PREWRITE); - ac->ac_start_time = (time_t)mono_time.tv_sec; + ac->ac_start_time = time_uptime; ac->ac_flags |= AC_ACTIVE; amr_outl(amr, AMR_QREG_IDB, (amr->amr_mbox_paddr + 16) | AMR_QIDB_SUBMIT); @@ -1203,7 +1201,7 @@ amr_std_submit(struct amr_softc *amr, st bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 0, sizeof(struct amr_mailbox), BUS_DMASYNC_PREWRITE); - ac->ac_start_time = (time_t)mono_time.tv_sec; + ac->ac_start_time = time_uptime; ac->ac_flags |= AC_ACTIVE; amr_outb(amr, AMR_SREG_CMD, AMR_SCMD_POST); return (0); Index: sys/dev/pci/viaenv.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/viaenv.c,v retrieving revision 1.12 diff -d -p -u -r1.12 viaenv.c --- sys/dev/pci/viaenv.c 23 Oct 2005 14:01:36 -0000 1.12 +++ sys/dev/pci/viaenv.c 22 Nov 2005 13:40:52 -0000 @@ -202,17 +202,16 @@ static void viaenv_refresh_sensor_data(struct viaenv_softc *sc) { static const struct timeval onepointfive = { 1, 500000 }; - struct timeval t; + struct timeval t, utv; u_int8_t v, v2; - int i, s; + int i; /* Read new values at most once every 1.5 seconds. */ timeradd(&sc->sc_lastread, &onepointfive, &t); - s = splclock(); - i = timercmp(&mono_time, &t, >); + getmicrouptime(&utv); + i = timercmp(&utv, &t, >); if (i) - sc->sc_lastread = mono_time; - splx(s); + sc->sc_lastread = utv; if (i == 0) return; Index: sys/dev/pckbport/pms.c =================================================================== RCS file: /cvsroot/src/sys/dev/pckbport/pms.c,v retrieving revision 1.8 diff -d -p -u -r1.8 pms.c --- sys/dev/pckbport/pms.c 8 Nov 2005 22:12:16 -0000 1.8 +++ sys/dev/pckbport/pms.c 22 Nov 2005 13:40:52 -0000 @@ -493,16 +493,13 @@ pmsinput(void *vsc, int data) u_int changed; int dx, dy, dz = 0; int newbuttons = 0; - int s; if (!sc->sc_enabled) { /* Interrupts are not expected. Discard the byte. */ return; } - s = splclock(); - sc->current = mono_time; - splx(s); + getmicrouptime(&sc->current); if (sc->inputstate > 0) { struct timeval diff; Index: sys/dev/pckbport/synaptics.c =================================================================== RCS file: /cvsroot/src/sys/dev/pckbport/synaptics.c,v retrieving revision 1.7 diff -d -p -u -r1.7 synaptics.c --- sys/dev/pckbport/synaptics.c 26 Oct 2005 17:20:19 -0000 1.7 +++ sys/dev/pckbport/synaptics.c 22 Nov 2005 13:40:54 -0000 @@ -657,9 +657,7 @@ pms_synaptics_input(void *vsc, int data) return; } - s = splclock(); - psc->current = mono_time; - splx(s); + getmicrouptime(&psc->current); if (psc->inputstate > 0) { timersub(&psc->current, &psc->last, &diff); Index: sys/dev/raidframe/rf_etimer.h =================================================================== RCS file: /cvsroot/src/sys/dev/raidframe/rf_etimer.h,v retrieving revision 1.9 diff -d -p -u -r1.9 rf_etimer.h --- sys/dev/raidframe/rf_etimer.h 29 May 2005 22:03:09 -0000 1.9 +++ sys/dev/raidframe/rf_etimer.h 22 Nov 2005 13:40:55 -0000 @@ -42,19 +42,13 @@ struct RF_Etimer_s { #define RF_ETIMER_START(_t_) \ { \ - int _s; \ memset(&(_t_), 0, sizeof (_t_)); \ - _s = splclock(); \ - (_t_).st = mono_time; \ - splx(_s); \ + getmicrouptime(&(_t_).st); \ } #define RF_ETIMER_STOP(_t_) \ { \ - int _s; \ - _s = splclock(); \ - (_t_).et = mono_time; \ - splx(_s); \ + getmicrouptime(&(_t_).et); \ } #define RF_ETIMER_EVAL(_t_) \ Index: sys/dev/scsipi/st.c =================================================================== RCS file: /cvsroot/src/sys/dev/scsipi/st.c,v retrieving revision 1.185 diff -d -p -u -r1.185 st.c --- sys/dev/scsipi/st.c 15 Oct 2005 17:29:26 -0000 1.185 +++ sys/dev/scsipi/st.c 22 Nov 2005 13:40:59 -0000 @@ -1187,7 +1187,7 @@ ststart(struct scsipi_periph *periph) struct buf *bp; struct scsi_rw_tape cmd; struct scsipi_xfer *xs; - int flags, error, s; + int flags, error; SC_DEBUG(periph, SCSIPI_DB2, ("ststart ")); /* @@ -1224,11 +1224,8 @@ ststart(struct scsipi_periph *periph) if ((bp = BUFQ_PEEK(st->buf_queue)) == NULL) return; - if (st->stats->busy++ == 0) { - s = splclock(); - st->stats->timestamp = mono_time; - splx(s); - } + if (st->stats->busy++ == 0) + getmicrouptime(&st->stats->timestamp); /* * only FIXEDBLOCK devices have pending I/O or space operations. @@ -1356,7 +1353,6 @@ stdone(struct scsipi_xfer *xs, int error { struct st_softc *st = (void *)xs->xs_periph->periph_dev; struct buf *bp = xs->bp; - int s; struct timeval st_time, diff_time; if (bp) { @@ -1375,9 +1371,7 @@ stdone(struct scsipi_xfer *xs, int error printf("%s: busy < 0, Oops.\n", st->stats->name); st->stats->busy = 0; } else { - s = splclock(); - st_time = mono_time; - splx(s); + getmicrouptime(&st_time); timersub(&st_time, &st->stats->timestamp, &diff_time); timeradd(&st->stats->time, &diff_time, @@ -2563,7 +2557,6 @@ struct tape * drive_attach(char *name) { struct tape *stats; - int s; /* Allocate and initialise statistics */ stats = (struct tape *) malloc(sizeof(struct tape), M_DEVBUF, @@ -2574,9 +2567,7 @@ drive_attach(char *name) /* * Set the attached timestamp. */ - s = splclock(); - stats->attachtime = mono_time; - splx(s); + getmicrouptime(&stats->attachtime); /* and clear the utilisation time */ timerclear(&stats->time); Index: sys/dev/wscons/wsmouse.c =================================================================== RCS file: /cvsroot/src/sys/dev/wscons/wsmouse.c,v retrieving revision 1.36 diff -d -p -u -r1.36 wsmouse.c --- sys/dev/wscons/wsmouse.c 21 Jun 2005 14:01:13 -0000 1.36 +++ sys/dev/wscons/wsmouse.c 22 Nov 2005 13:41:00 -0000 @@ -346,13 +346,7 @@ wsmouse_input(struct device *wsmousedev, } \ any = 1 /* TIMESTAMP sets `time' field of the event to the current time */ -#define TIMESTAMP \ - do { \ - int s; \ - s = splhigh(); \ - TIMEVAL_TO_TIMESPEC(&time, &ev->time); \ - splx(s); \ - } while (0) +#define TIMESTAMP getnanotime(&ev->time) if (flags & WSMOUSE_INPUT_ABSOLUTE_X) { if (sc->sc_x != x) { Index: sys/dist/pf/net/pfvar.h =================================================================== RCS file: /cvsroot/src/sys/dist/pf/net/pfvar.h,v retrieving revision 1.9 diff -d -p -u -r1.9 pfvar.h --- sys/dist/pf/net/pfvar.h 1 Jul 2005 12:37:35 -0000 1.9 +++ sys/dist/pf/net/pfvar.h 22 Nov 2005 13:41:03 -0000 @@ -1606,6 +1606,7 @@ int pfil_ifaddr_wrapper(void *, struct m #define PRIu32 "u" /* XXX */ #endif #if !defined(__OpenBSD__) +#if !defined(__NetBSD__) #include /* mono_time */ static __inline void getmicrouptime(struct timeval *); static __inline void @@ -1618,9 +1619,10 @@ getmicrouptime(struct timeval *tvp) splx(s); } #define time_second time.tv_sec +#endif /* !__NetBSD__ */ #define m_copym2 m_dup #define pool_allocator_oldnointr pool_allocator_nointr -#endif +#endif /* !__OpenBSD__ */ #endif /* _KERNEL */ /* The fingerprint functions can be linked into userland programs (tcpdump) */ Index: sys/fs/msdosfs/msdosfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/msdosfs/msdosfs_vnops.c,v retrieving revision 1.22 diff -d -p -u -r1.22 msdosfs_vnops.c --- sys/fs/msdosfs/msdosfs_vnops.c 4 Nov 2005 21:04:20 -0000 1.22 +++ sys/fs/msdosfs/msdosfs_vnops.c 22 Nov 2005 13:41:05 -0000 @@ -1865,22 +1865,25 @@ msdosfs_detimes(struct denode *dep, cons struct timespec *ts = NULL, tsb; KASSERT(dep->de_flag & (DE_UPDATE | DE_CREATE | DE_ACCESS)); + /* XXX just call getnanotime early and use result if needed? */ dep->de_flag |= DE_MODIFIED; if (dep->de_flag & DE_UPDATE) { if (mod == NULL) - mod = ts == NULL ? (ts = nanotime(&tsb)) : ts; + mod = ts == NULL ? (getnanotime(&tsb), ts = &tsb) : ts; unix2dostime(mod, gmtoff, &dep->de_MDate, &dep->de_MTime, NULL); dep->de_Attributes |= ATTR_ARCHIVE; } if ((dep->de_pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0) { if (dep->de_flag & DE_ACCESS) { if (acc == NULL) - acc = ts == NULL ? (ts = nanotime(&tsb)) : ts; + acc = ts == NULL ? + (getnanotime(&tsb), ts = &tsb) : ts; unix2dostime(acc, gmtoff, &dep->de_ADate, NULL, NULL); } if (dep->de_flag & DE_CREATE) { if (cre == NULL) - cre = ts == NULL ? (ts = nanotime(&tsb)) : ts; + cre = ts == NULL ? + (getnanotime(&tsb), ts = &tsb) : ts; unix2dostime(cre, gmtoff, &dep->de_CDate, &dep->de_CTime, &dep->de_CHun); } Index: sys/fs/ptyfs/ptyfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/ptyfs/ptyfs_vnops.c,v retrieving revision 1.11 diff -d -p -u -r1.11 ptyfs_vnops.c --- sys/fs/ptyfs/ptyfs_vnops.c 2 Nov 2005 12:38:58 -0000 1.11 +++ sys/fs/ptyfs/ptyfs_vnops.c 22 Nov 2005 13:41:07 -0000 @@ -767,10 +767,10 @@ ptyfs_close(void *v) struct vnode *vp = ap->a_vp; struct ptyfsnode *ptyfs = VTOPTYFS(vp); - simple_lock(&vp->v_interlock); - if (vp->v_usecount > 1) + simple_lock(&vp->v_interlock); + if (vp->v_usecount > 1) PTYFS_ITIMES(ptyfs, NULL, NULL, NULL); - simple_unlock(&vp->v_interlock); + simple_unlock(&vp->v_interlock); switch (ptyfs->ptyfs_type) { case PTYFSpts: @@ -799,7 +799,7 @@ ptyfs_read(void *v) ptyfs->ptyfs_flag |= PTYFS_ACCESS; /* hardclock() resolution is good enough for ptyfs */ - TIMEVAL_TO_TIMESPEC(&time, &ts); + getnanotime(&ts); (void)ptyfs_update(vp, &ts, &ts, 0); switch (ptyfs->ptyfs_type) { @@ -835,8 +835,7 @@ ptyfs_write(void *v) int error; ptyfs->ptyfs_flag |= PTYFS_MODIFY; - /* hardclock() resolution is good enough for ptyfs */ - TIMEVAL_TO_TIMESPEC(&time, &ts); + getnanotime(&ts); (void)ptyfs_update(vp, &ts, &ts, 0); switch (ptyfs->ptyfs_type) { @@ -942,21 +941,22 @@ ptyfs_itimes(struct ptyfsnode *ptyfs, co const struct timespec *mod, const struct timespec *cre) { struct timespec *ts = NULL, tsb; - + KASSERT(ptyfs->ptyfs_flag & (PTYFS_ACCESS|PTYFS_CHANGE|PTYFS_MODIFY)); + /* XXX just call getnanotime early and use result if needed? */ if (ptyfs->ptyfs_flag & (PTYFS_ACCESS|PTYFS_MODIFY)) { if (acc == NULL) - acc = ts == NULL ? (ts = nanotime(&tsb)) : ts; + acc = ts == NULL ? (getnanotime(&tsb), ts = &tsb) : ts; ptyfs->ptyfs_atime = *acc; } if (ptyfs->ptyfs_flag & PTYFS_MODIFY) { if (mod == NULL) - mod = ts == NULL ? (ts = nanotime(&tsb)) : ts; + mod = ts == NULL ? (getnanotime(&tsb), ts = &tsb) : ts; ptyfs->ptyfs_mtime = *mod; } if (ptyfs->ptyfs_flag & PTYFS_CHANGE) { if (cre == NULL) - cre = ts == NULL ? (ts = nanotime(&tsb)) : ts; + cre = ts == NULL ? (getnanotime(&tsb), ts = &tsb) : ts; ptyfs->ptyfs_ctime = *cre; } ptyfs->ptyfs_flag &= ~(PTYFS_ACCESS|PTYFS_CHANGE|PTYFS_MODIFY); Index: sys/fs/smbfs/smbfs_node.c =================================================================== RCS file: /cvsroot/src/sys/fs/smbfs/smbfs_node.c,v retrieving revision 1.25 diff -d -p -u -r1.25 smbfs_node.c --- sys/fs/smbfs/smbfs_node.c 30 Aug 2005 19:04:51 -0000 1.25 +++ sys/fs/smbfs/smbfs_node.c 22 Nov 2005 13:41:07 -0000 @@ -311,7 +311,6 @@ void smbfs_attr_cacheenter(struct vnode *vp, struct smbfattr *fap) { struct smbnode *np = VTOSMB(vp); - int s; if (vp->v_type == VREG) { if (np->n_size != fap->fa_size) { @@ -326,9 +325,7 @@ smbfs_attr_cacheenter(struct vnode *vp, np->n_mtime = fap->fa_mtime; np->n_dosattr = fap->fa_attr; - s = splclock(); - np->n_attrage = mono_time.tv_sec; - splx(s); + np->n_attrage = time_uptime; } int @@ -336,12 +333,9 @@ smbfs_attr_cachelookup(struct vnode *vp, { struct smbnode *np = VTOSMB(vp); struct smbmount *smp = VTOSMBFS(vp); - int s; time_t diff; - s = splclock(); - diff = mono_time.tv_sec - np->n_attrage; - splx(s); + diff = time_uptime - np->n_attrage; if (diff > SMBFS_ATTRTIMO) /* XXX should be configurable */ return ENOENT; Index: sys/fs/smbfs/smbfs_smb.c =================================================================== RCS file: /cvsroot/src/sys/fs/smbfs/smbfs_smb.c,v retrieving revision 1.28 diff -d -p -u -r1.28 smbfs_smb.c --- sys/fs/smbfs/smbfs_smb.c 12 Sep 2005 16:54:35 -0000 1.28 +++ sys/fs/smbfs/smbfs_smb.c 22 Nov 2005 13:41:11 -0000 @@ -642,7 +642,7 @@ smbfs_smb_create(struct smbnode *dnp, co smb_rq_getrequest(rqp, &mbp); /* get current time */ - (void)nanotime(&ctime); + getnanotime(&ctime); smb_time_local2server(&ctime, SSTOVC(ssp)->vc_sopt.sv_tz, &tm); smb_rq_wstart(rqp); Index: sys/fs/tmpfs/tmpfs_subr.c =================================================================== RCS file: /cvsroot/src/sys/fs/tmpfs/tmpfs_subr.c,v retrieving revision 1.14 diff -d -p -u -r1.14 tmpfs_subr.c --- sys/fs/tmpfs/tmpfs_subr.c 11 Nov 2005 15:50:57 -0000 1.14 +++ sys/fs/tmpfs/tmpfs_subr.c 22 Nov 2005 13:41:13 -0000 @@ -130,7 +130,7 @@ tmpfs_alloc_node(struct tmpfs_mount *tmp nnode->tn_status = 0; nnode->tn_flags = 0; nnode->tn_links = 0; - (void)nanotime(&nnode->tn_atime); + getnanotime(&nnode->tn_atime); nnode->tn_birthtime = nnode->tn_ctime = nnode->tn_mtime = nnode->tn_atime; nnode->tn_uid = uid; @@ -1229,9 +1229,8 @@ void tmpfs_itimes(struct vnode *vp, const struct timespec *acc, const struct timespec *mod) { + struct timespec *ts = NULL, tsb; struct tmpfs_node *node; - const struct timespec *ts = NULL; - struct timespec tsb; node = VP_TO_TMPFS_NODE(vp); @@ -1239,21 +1238,23 @@ tmpfs_itimes(struct vnode *vp, const str TMPFS_NODE_CHANGED)) == 0) return; + /* XXX just call getnanotime early and use result if needed? */ if (node->tn_status & TMPFS_NODE_ACCESSED) { if (acc == NULL) - acc = ts == NULL ? (ts = nanotime(&tsb)) : ts; + acc = ts == NULL ? (getnanotime(&tsb), ts = &tsb) : ts; node->tn_atime = *acc; } if (node->tn_status & TMPFS_NODE_MODIFIED) { if (mod == NULL) - mod = ts == NULL ? (ts = nanotime(&tsb)) : ts; + mod = ts == NULL ? (getnanotime(&tsb), ts = &tsb) : ts; node->tn_mtime = *mod; } if (node->tn_status & TMPFS_NODE_CHANGED) { if (ts == NULL) - ts = nanotime(&tsb); + getnanotime(&tsb), ts = &tsb; node->tn_ctime = *ts; } + node->tn_status &= ~(TMPFS_NODE_ACCESSED | TMPFS_NODE_MODIFIED | TMPFS_NODE_CHANGED); } Index: sys/kern/init_main.c =================================================================== RCS file: /cvsroot/src/sys/kern/init_main.c,v retrieving revision 1.253 diff -d -p -u -r1.253 init_main.c --- sys/kern/init_main.c 18 Nov 2005 21:55:14 -0000 1.253 +++ sys/kern/init_main.c 22 Nov 2005 13:41:14 -0000 @@ -74,17 +74,18 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.253 2005/11/18 21:55:14 martin Exp $"); #include "fs_nfs.h" -#include "opt_nfsserver.h" #include "opt_ipsec.h" -#include "opt_sysv.h" +#include "opt_kcont.h" #include "opt_maxuprc.h" #include "opt_multiprocessor.h" +#include "opt_nfsserver.h" +#include "opt_ntp.h" #include "opt_pipe.h" -#include "opt_syscall_debug.h" -#include "opt_systrace.h" #include "opt_posix.h" -#include "opt_kcont.h" #include "opt_rootfs_magiclinks.h" +#include "opt_syscall_debug.h" +#include "opt_systrace.h" +#include "opt_sysv.h" #include "opt_verified_exec.h" #include "opencrypto.h" @@ -186,7 +187,9 @@ struct proc *initproc; struct vnode *rootvp, *swapdev_vp; int boothowto; int cold = 1; /* still working on startup */ -struct timeval boottime; +#ifndef __HAVE_TIMECOUNTER +struct timeval boottime; +#endif time_t rootfstime; /* recorded root fs time, if known */ __volatile int start_init_exec; /* semaphore for start_init() */ @@ -204,6 +207,9 @@ void main(void); void main(void) { +#ifdef __HAVE_TIMECOUNTER + struct timeval time; +#endif struct lwp *l; struct proc *p; struct pdevinit *pdev; @@ -447,6 +453,12 @@ main(void) */ inittodr(rootfstime); +#ifdef __HAVE_TIMECOUNTER +#ifdef NTP + ntp_init(); /* XXXXXXXXX right place?!?! XXXXXXXXX */ +#endif +#endif /* __HAVE_TIMECOUNTER */ + CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS; #ifdef ROOTFS_MAGICLINKS CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_MAGICLINKS; @@ -481,9 +493,15 @@ main(void) */ proclist_lock_read(); s = splsched(); +#ifdef __HAVE_TIMECOUNTER + getmicrotime(&time); +#else + mono_time = time; +#endif + boottime = time; LIST_FOREACH(p, &allproc, p_list) { KASSERT((p->p_flag & P_MARKER) == 0); - p->p_stats->p_start = mono_time = boottime = time; + p->p_stats->p_start = time; LIST_FOREACH(l, &p->p_lwps, l_sibling) { if (l->l_cpu != NULL) l->l_cpu->ci_schedstate.spc_runtime = time; Index: sys/kern/init_sysctl.c =================================================================== RCS file: /cvsroot/src/sys/kern/init_sysctl.c,v retrieving revision 1.56 diff -d -p -u -r1.56 init_sysctl.c --- sys/kern/init_sysctl.c 8 Oct 2005 06:35:56 -0000 1.56 +++ sys/kern/init_sysctl.c 22 Nov 2005 13:41:19 -0000 @@ -1076,7 +1076,7 @@ static int sysctl_kern_rtc_offset(SYSCTLFN_ARGS) { struct timeval tv, delta; - int s, error, new_rtc_offset; + int error, new_rtc_offset; struct sysctlnode node; new_rtc_offset = rtc_offset; @@ -1092,10 +1092,8 @@ sysctl_kern_rtc_offset(SYSCTLFN_ARGS) return (0); /* if we change the offset, adjust the time */ - s = splclock(); - tv = time; - splx(s); - delta.tv_sec = 60*(new_rtc_offset - rtc_offset); + getmicrotime(&tv); + delta.tv_sec = 60 * (new_rtc_offset - rtc_offset); delta.tv_usec = 0; timeradd(&tv, &delta, &tv); rtc_offset = new_rtc_offset; Index: sys/kern/kern_acct.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_acct.c,v retrieving revision 1.61 diff -d -p -u -r1.61 kern_acct.c --- sys/kern/kern_acct.c 23 Jun 2005 23:15:12 -0000 1.61 +++ sys/kern/kern_acct.c 22 Nov 2005 13:41:20 -0000 @@ -390,9 +390,9 @@ int acct_process(struct proc *p) { struct acct acct; - struct rusage *r; struct timeval ut, st, tmp; - int s, t, error = 0; + struct rusage *r; + int t, error = 0; struct plimit *oplim = NULL; ACCT_LOCK(); @@ -427,9 +427,8 @@ acct_process(struct proc *p) /* (3) The elapsed time the commmand ran (and its starting time) */ acct.ac_btime = p->p_stats->p_start.tv_sec; - s = splclock(); - timersub(&time, &p->p_stats->p_start, &tmp); - splx(s); + getmicrotime(&tmp); + timersub(&tmp, &p->p_stats->p_start, &tmp); acct.ac_etime = encode_comp_t(tmp.tv_sec, tmp.tv_usec); /* (4) The average amount of memory used */ Index: sys/kern/kern_clock.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_clock.c,v retrieving revision 1.95 diff -d -p -u -r1.95 kern_clock.c --- sys/kern/kern_clock.c 12 Sep 2005 16:21:31 -0000 1.95 +++ sys/kern/kern_clock.c 22 Nov 2005 13:41:22 -0000 @@ -93,6 +93,9 @@ __KERNEL_RCSID(0, "$NetBSD: kern_clock.c #include #include #include +#ifdef __HAVE_TIMECOUNTER +#include +#endif #include #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS @@ -127,6 +130,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_clock.c * profhz/stathz for statistics. (For profiling, every tick counts.) */ +#ifndef __HAVE_TIMECOUNTER #ifdef NTP /* NTP phase-locked loop in kernel */ /* * Phase/frequency-lock loop (PLL/FLL) definitions @@ -308,7 +312,6 @@ long clock_cpu = 0; /* CPU clock adjust #endif /* EXT_CLOCK */ #endif /* NTP */ - /* * Bump a timeval by a small number of usec's. */ @@ -322,6 +325,7 @@ long clock_cpu = 0; /* CPU clock adjust tp->tv_sec++; \ } \ } +#endif /* !__HAVE_TIMECOUNTER */ int stathz; int profhz; @@ -332,6 +336,7 @@ int hardclock_ticks; static int statscheddiv; /* stat => sched divider (used if schedhz == 0) */ static int psdiv; /* prof => stat divider */ int psratio; /* ratio: prof / stat */ +#ifndef __HAVE_TIMECOUNTER int tickfix, tickfixinterval; /* used if tick not really integral */ #ifndef NTP static int tickfixcnt; /* accumulated fractional error */ @@ -347,8 +352,11 @@ int shifthz; */ volatile struct timeval time __attribute__((__aligned__(__alignof__(quad_t)))); volatile struct timeval mono_time; +#endif /* !__HAVE_TIMECOUNTER */ +#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS void *softclock_si; +#endif /* * Initialize clock frequencies and start both clocks running. @@ -369,6 +377,9 @@ initclocks(void) * code do its bit. */ psdiv = 1; +#ifdef __HAVE_TIMECOUNTER + inittimecounter(); +#endif cpu_initclocks(); /* @@ -386,6 +397,7 @@ initclocks(void) panic("statscheddiv"); } +#ifndef __HAVE_TIMECOUNTER #ifdef NTP switch (hz) { case 1: @@ -455,7 +467,8 @@ initclocks(void) */ fixtick = (1000000 - (hz*tick)); } -#endif +#endif /* NTP */ +#endif /* !__HAVE_TIMECOUNTER */ } /* @@ -466,15 +479,17 @@ hardclock(struct clockframe *frame) { struct lwp *l; struct proc *p; + struct cpu_info *ci = curcpu(); + struct ptimer *pt; +#ifndef __HAVE_TIMECOUNTER int delta; extern int tickdelta; extern long timedelta; - struct cpu_info *ci = curcpu(); - struct ptimer *pt; #ifdef NTP int time_update; int ltemp; -#endif +#endif /* NTP */ +#endif /* __HAVE_TIMECOUNTER */ l = curlwp; if (l) { @@ -492,6 +507,11 @@ hardclock(struct clockframe *frame) itimerfire(pt); } +#ifdef __HAVE_TIMECOUNTER +/* XXX - correct place ifdef MULTIPROCESSOR? */ + tc_ticktock(); +#endif + /* * If no separate statistics clock is available, run it from here. */ @@ -505,10 +525,12 @@ hardclock(struct clockframe *frame) * If we are not the primary CPU, we're not allowed to do * any more work. */ +/* XXX - correct for timecounters? */ if (CPU_IS_PRIMARY(ci) == 0) return; #endif +#ifndef __HAVE_TIMECOUNTER /* * Increment the time-of-day. The increment is normally just * ``tick''. If the machine is one which has a clock frequency @@ -831,12 +853,16 @@ hardclock(struct clockframe *frame) } #endif /* NTP */ +#endif /* !__HAVE_TIMECOUNTER */ /* * Update real-time timeout queue. * Process callouts at a very low CPU priority, so we don't keep the * relatively high clock interrupt priority any longer than necessary. */ +#ifdef __HAVE_TIMECOUNTER + hardclock_ticks++; +#endif if (callout_hardclock()) { if (CLKF_BASEPRI(frame)) { /* @@ -858,6 +884,83 @@ hardclock(struct clockframe *frame) } } +#ifdef __HAVE_TIMECOUNTER +/* + * Compute number of hz until specified time. Used to compute second + * argument to callout_reset() from an absolute time. + */ +int +hzto(struct timeval *tvp) +{ + struct timeval now, tv; + + tv = *tvp; /* Don't modify original tvp. */ + getmicrotime(&now); + timersub(&tv, &now, &tv); + return tvtohz(&tv); +} +#endif /* __HAVE_TIMECOUNTER */ + +/* + * Compute number of ticks in the specified amount of time. + */ +int +tvtohz(struct timeval *tv) +{ + unsigned long ticks; + long sec, usec; + + /* + * If the number of usecs in the whole seconds part of the time + * difference fits in a long, then the total number of usecs will + * fit in an unsigned long. Compute the total and convert it to + * ticks, rounding up and adding 1 to allow for the current tick + * to expire. Rounding also depends on unsigned long arithmetic + * to avoid overflow. + * + * Otherwise, if the number of ticks in the whole seconds part of + * the time difference fits in a long, then convert the parts to + * ticks separately and add, using similar rounding methods and + * overflow avoidance. This method would work in the previous + * case, but it is slightly slower and assumes that hz is integral. + * + * Otherwise, round the time difference down to the maximum + * representable value. + * + * If ints are 32-bit, then the maximum value for any timeout in + * 10ms ticks is 248 days. + */ + sec = tv->tv_sec; + usec = tv->tv_usec; + + if (usec < 0) { + sec--; + usec += 1000000; + } + + if (sec < 0 || (sec == 0 && usec <= 0)) { + /* + * Would expire now or in the past. Return 0 ticks. + * This is different from the legacy hzto() interface, + * and callers need to check for it. + */ + ticks = 0; + } else if (sec <= (LONG_MAX / 1000000)) + ticks = (((sec * 1000000) + (unsigned long)usec + (tick - 1)) + / tick) + 1; + else if (sec <= (LONG_MAX / hz)) + ticks = (sec * hz) + + (((unsigned long)usec + (tick - 1)) / tick) + 1; + else + ticks = LONG_MAX; + + if (ticks > INT_MAX) + ticks = INT_MAX; + + return ((int)ticks); +} + +#ifndef __HAVE_TIMECOUNTER /* * Compute number of hz until specified time. Used to compute second * argument to callout_reset() from an absolute time. @@ -920,6 +1023,23 @@ hzto(struct timeval *tv) return ((int)ticks); } +#endif /* !__HAVE_TIMECOUNTER */ + +/* + * Compute number of ticks in the specified amount of time. + */ +int +tstohz(struct timespec *ts) +{ + struct timeval tv; + + /* + * usec has great enough resolution for hz, so convert to a + * timeval and use tvtohz() above. + */ + TIMESPEC_TO_TIMEVAL(&tv, ts); + return tvtohz(&tv); +} /* * Start profiling on a process. @@ -1101,9 +1221,8 @@ statclock(struct clockframe *frame) } } - +#ifndef __HAVE_TIMECOUNTER #ifdef NTP /* NTP phase-locked loop in kernel */ - /* * hardupdate() - local clock update * @@ -1432,15 +1551,62 @@ hardpps(struct timeval *tvp, /* time at #endif /* PPS_SYNC */ #endif /* NTP */ -/* - * XXX: Until all md code has it. - */ -struct timespec * +/* timecounter compat functions */ +void nanotime(struct timespec *ts) { struct timeval tv; microtime(&tv); TIMEVAL_TO_TIMESPEC(&tv, ts); - return ts; } + +void +getbinuptime(struct bintime *bt) +{ + struct timeval tv; + + microtime(&tv); + timeval2bintime(&tv, bt); +} + +void +getnanouptime(struct timespec *tsp) +{ + int s; + + s = splclock(); + TIMEVAL_TO_TIMESPEC(&mono_time, tsp); + splx(s); +} + +void +getmicrouptime(struct timeval *tvp) +{ + int s; + + s = splclock(); + *tvp = mono_time; + splx(s); +} + +void +getnanotime(struct timespec *tsp) +{ + int s; + + s = splclock(); + TIMEVAL_TO_TIMESPEC(&time, tsp); + splx(s); +} + +void +getmicrotime(struct timeval *tvp) +{ + int s; + + s = splclock(); + *tvp = time; + splx(s); +} +#endif /* !__HAVE_TIMECOUNTER */ Index: sys/kern/kern_event.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_event.c,v retrieving revision 1.24 diff -d -p -u -r1.24 kern_event.c --- sys/kern/kern_event.c 23 Oct 2005 01:33:32 -0000 1.24 +++ sys/kern/kern_event.c 22 Nov 2005 13:41:25 -0000 @@ -920,10 +920,7 @@ kqueue_scan(struct file *fp, size_t maxe error = EINVAL; goto done; } - s = splclock(); - timeradd(&atv, &time, &atv); /* calc. time to wait until */ - splx(s); - timeout = hzto(&atv); + timeout = tvtohz(&atv); if (timeout <= 0) timeout = -1; /* do poll */ } else { Index: sys/kern/kern_fork.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_fork.c,v retrieving revision 1.122 diff -d -p -u -r1.122 kern_fork.c --- sys/kern/kern_fork.c 17 May 2005 19:22:19 -0000 1.122 +++ sys/kern/kern_fork.c 22 Nov 2005 13:41:26 -0000 @@ -432,7 +432,7 @@ fork1(struct lwp *l1, int flags, int exi * except if the parent requested the child to start in SSTOP state. */ SCHED_LOCK(s); - p2->p_stats->p_start = time; + getmicrotime(&p2->p_stats->p_start); p2->p_acflag = AFORK; if (p1->p_flag & P_STOPFORK) { p2->p_nrlwps = 0; Index: sys/kern/kern_ktrace.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_ktrace.c,v retrieving revision 1.97 diff -d -p -u -r1.97 kern_ktrace.c --- sys/kern/kern_ktrace.c 29 May 2005 22:24:15 -0000 1.97 +++ sys/kern/kern_ktrace.c 22 Nov 2005 13:41:27 -0000 @@ -231,8 +231,7 @@ ktraddentry(struct proc *p, struct ktrac { struct ktr_desc *ktd; #ifdef DEBUG - struct timeval t; - int s; + struct timeval t1, t2; #endif if (p->p_traceflag & KTRFAC_TRC_EMUL) { @@ -280,9 +279,7 @@ ktraddentry(struct proc *p, struct ktrac ktd->ktd_flags |= KTDF_WAIT; ktd_wakeup(ktd); #ifdef DEBUG - s = splclock(); - t = mono_time; - splx(s); + getmicrouptime(&t1); #endif if (ltsleep(&ktd->ktd_flags, PWAIT, "ktrsync", ktd_timeout * hz, &ktd->ktd_slock) != 0) { @@ -296,13 +293,12 @@ ktraddentry(struct proc *p, struct ktrac break; } #ifdef DEBUG - s = splclock(); - timersub(&mono_time, &t, &t); - splx(s); - if (t.tv_sec > 0) + getmicrouptime(&t2); + timersub(&t2, &t1, &t2); + if (t2.tv_sec > 0) log(LOG_NOTICE, "ktrace long wait: %ld.%06ld\n", - t.tv_sec, t.tv_usec); + t2.tv_sec, t2.tv_usec); #endif } while (p->p_tracep == ktd && (ktd->ktd_flags & (KTDF_WAIT | KTDF_DONE)) == KTDF_WAIT); Index: sys/kern/kern_microtime.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_microtime.c,v retrieving revision 1.14 diff -d -p -u -r1.14 kern_microtime.c --- sys/kern/kern_microtime.c 23 Jan 2005 08:39:51 -0000 1.14 +++ sys/kern/kern_microtime.c 22 Nov 2005 13:41:27 -0000 @@ -126,7 +126,7 @@ cc_microtime(struct timeval *tvp) */ /* XXXSMP: not atomic */ simple_lock(µtime_slock); - t = time; + getmicrotime(&t); } /* Index: sys/kern/kern_ntptime.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_ntptime.c,v retrieving revision 1.28 diff -d -p -u -r1.28 kern_ntptime.c --- sys/kern/kern_ntptime.c 26 Feb 2005 21:34:55 -0000 1.28 +++ sys/kern/kern_ntptime.c 22 Nov 2005 13:41:30 -0000 @@ -1,5 +1,1012 @@ /* $NetBSD: kern_ntptime.c,v 1.28 2005/02/26 21:34:55 perry Exp $ */ +#include /* XXX to get __HAVE_TIMECOUNTER */ +#ifdef __HAVE_TIMECOUNTER + +/*- + *********************************************************************** + * * + * Copyright (c) David L. Mills 1993-2001 * + * * + * Permission to use, copy, modify, and distribute this software and * + * its documentation for any purpose and without fee is hereby * + * granted, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission * + * notice appear in supporting documentation, and that the name * + * University of Delaware not be used in advertising or publicity * + * pertaining to distribution of the software without specific, * + * written prior permission. The University of Delaware makes no * + * representations about the suitability this software for any * + * purpose. It is provided "as is" without express or implied * + * warranty. * + * * + **********************************************************************/ + +/* + * Adapted from the original sources for FreeBSD and timecounters by: + * Poul-Henning Kamp . + * + * The 32bit version of the "LP" macros seems a bit past its "sell by" + * date so I have retained only the 64bit version and included it directly + * in this file. + * + * Only minor changes done to interface with the timecounters over in + * sys/kern/kern_clock.c. Some of the comments below may be (even more) + * confusing and/or plain wrong in that context. + */ + +#include +/* __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.28 2005/02/26 21:34:55 perry Exp $"); + +#include "opt_ntp.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#ifdef NTP +/* + * Single-precision macros for 64-bit machines + */ +typedef int64_t l_fp; +#define L_ADD(v, u) ((v) += (u)) +#define L_SUB(v, u) ((v) -= (u)) +#define L_ADDHI(v, a) ((v) += (int64_t)(a) << 32) +#define L_NEG(v) ((v) = -(v)) +#define L_RSHIFT(v, n) \ + do { \ + if ((v) < 0) \ + (v) = -(-(v) >> (n)); \ + else \ + (v) = (v) >> (n); \ + } while (0) +#define L_MPY(v, a) ((v) *= (a)) +#define L_CLR(v) ((v) = 0) +#define L_ISNEG(v) ((v) < 0) +#define L_LINT(v, a) ((v) = (int64_t)(a) << 32) +#define L_GINT(v) ((v) < 0 ? -(-(v) >> 32) : (v) >> 32) + +/* + * Generic NTP kernel interface + * + * These routines constitute the Network Time Protocol (NTP) interfaces + * for user and daemon application programs. The ntp_gettime() routine + * provides the time, maximum error (synch distance) and estimated error + * (dispersion) to client user application programs. The ntp_adjtime() + * routine is used by the NTP daemon to adjust the system clock to an + * externally derived time. The time offset and related variables set by + * this routine are used by other routines in this module to adjust the + * phase and frequency of the clock discipline loop which controls the + * system clock. + * + * When the kernel time is reckoned directly in nanoseconds (NTP_NANO + * defined), the time at each tick interrupt is derived directly from + * the kernel time variable. When the kernel time is reckoned in + * microseconds, (NTP_NANO undefined), the time is derived from the + * kernel time variable together with a variable representing the + * leftover nanoseconds at the last tick interrupt. In either case, the + * current nanosecond time is reckoned from these values plus an + * interpolated value derived by the clock routines in another + * architecture-specific module. The interpolation can use either a + * dedicated counter or a processor cycle counter (PCC) implemented in + * some architectures. + * + * Note that all routines must run at priority splclock or higher. + */ +/* + * Phase/frequency-lock loop (PLL/FLL) definitions + * + * The nanosecond clock discipline uses two variable types, time + * variables and frequency variables. Both types are represented as 64- + * bit fixed-point quantities with the decimal point between two 32-bit + * halves. On a 32-bit machine, each half is represented as a single + * word and mathematical operations are done using multiple-precision + * arithmetic. On a 64-bit machine, ordinary computer arithmetic is + * used. + * + * A time variable is a signed 64-bit fixed-point number in ns and + * fraction. It represents the remaining time offset to be amortized + * over succeeding tick interrupts. The maximum time offset is about + * 0.5 s and the resolution is about 2.3e-10 ns. + * + * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |s s s| ns | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | fraction | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * A frequency variable is a signed 64-bit fixed-point number in ns/s + * and fraction. It represents the ns and fraction to be added to the + * kernel time variable at each second. The maximum frequency offset is + * about +-500000 ns/s and the resolution is about 2.3e-10 ns/s. + * + * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |s s s s s s s s s s s s s| ns/s | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | fraction | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ +/* + * The following variables establish the state of the PLL/FLL and the + * residual time and frequency offset of the local clock. + */ +#define SHIFT_PLL 4 /* PLL loop gain (shift) */ +#define SHIFT_FLL 2 /* FLL loop gain (shift) */ + +static int time_state = TIME_OK; /* clock state */ +static int time_status = STA_UNSYNC; /* clock status bits */ +static long time_tai; /* TAI offset (s) */ +static long time_monitor; /* last time offset scaled (ns) */ +static long time_constant; /* poll interval (shift) (s) */ +static long time_precision = 1; /* clock precision (ns) */ +static long time_maxerror = MAXPHASE / 1000; /* maximum error (us) */ +static long time_esterror = MAXPHASE / 1000; /* estimated error (us) */ +static long time_reftime; /* time at last adjustment (s) */ +static l_fp time_offset; /* time offset (ns) */ +static l_fp time_freq; /* frequency offset (ns/s) */ +static l_fp time_adj; /* tick adjust (ns/s) */ + +static int64_t time_adjtime; /* correction from adjtime(2) (usec) */ + +extern int time_adjusted; /* ntp might have changed the system time */ /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX do we need this in the freebsd world?!? */ + +#ifdef PPS_SYNC +/* + * The following variables are used when a pulse-per-second (PPS) signal + * is available and connected via a modem control lead. They establish + * the engineering parameters of the clock discipline loop when + * controlled by the PPS signal. + */ +#define PPS_FAVG 2 /* min freq avg interval (s) (shift) */ +#define PPS_FAVGDEF 8 /* default freq avg int (s) (shift) */ +#define PPS_FAVGMAX 15 /* max freq avg interval (s) (shift) */ +#define PPS_PAVG 4 /* phase avg interval (s) (shift) */ +#define PPS_VALID 120 /* PPS signal watchdog max (s) */ +#define PPS_MAXWANDER 100000 /* max PPS wander (ns/s) */ +#define PPS_POPCORN 2 /* popcorn spike threshold (shift) */ + +static struct timespec pps_tf[3]; /* phase median filter */ +static l_fp pps_freq; /* scaled frequency offset (ns/s) */ +static long pps_fcount; /* frequency accumulator */ +static long pps_jitter; /* nominal jitter (ns) */ +static long pps_stabil; /* nominal stability (scaled ns/s) */ +static long pps_lastsec; /* time at last calibration (s) */ +static int pps_valid; /* signal watchdog counter */ +static int pps_shift = PPS_FAVG; /* interval duration (s) (shift) */ +static int pps_shiftmax = PPS_FAVGDEF; /* max interval duration (s) (shift) */ +static int pps_intcnt; /* wander counter */ + +/* + * PPS signal quality monitors + */ +static long pps_calcnt; /* calibration intervals */ +static long pps_jitcnt; /* jitter limit exceeded */ +static long pps_stbcnt; /* stability limit exceeded */ +static long pps_errcnt; /* calibration errors */ +#endif /* PPS_SYNC */ +/* + * End of phase/frequency-lock loop (PLL/FLL) definitions + */ + +static void hardupdate(long offset); + +/*ARGSUSED*/ +/* + * ntp_gettime() - NTP user application interface + */ +int +sys_ntp_gettime(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; + +{ + struct sys_ntp_gettime_args /* { + syscallarg(struct ntptimeval *) ntvp; + } */ *uap = v; + struct ntptimeval ntv; + int error = 0; + + if (SCARG(uap, ntvp)) { + nanotime(&ntv.time); + ntv.maxerror = time_maxerror; + ntv.esterror = time_esterror; + ntv.tai = time_tai; + ntv.time_state = time_state; + + error = copyout((caddr_t)&ntv, (caddr_t)SCARG(uap, ntvp), + sizeof(ntv)); + } + if (!error) { + + /* + * Status word error decode. If any of these conditions occur, + * an error is returned, instead of the status word. Most + * applications will care only about the fact the system clock + * may not be trusted, not about the details. + * + * Hardware or software error + */ + if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) || + + /* + * PPS signal lost when either time or frequency synchronization + * requested + */ + (time_status & (STA_PPSFREQ | STA_PPSTIME) && + !(time_status & STA_PPSSIGNAL)) || + + /* + * PPS jitter exceeded when time synchronization requested + */ + (time_status & STA_PPSTIME && + time_status & STA_PPSJITTER) || + + /* + * PPS wander exceeded or calibration error when frequency + * synchronization requested + */ + (time_status & STA_PPSFREQ && + time_status & (STA_PPSWANDER | STA_PPSERROR))) + ntv.time_state = TIME_ERROR; + + *retval = (register_t)ntv.time_state; + } + return(error); +} + +/* ARGSUSED */ +/* + * ntp_adjtime() - NTP daemon application interface + */ +int +sys_ntp_adjtime(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; +{ + struct sys_ntp_adjtime_args /* { + syscallarg(struct timex *) tp; + } */ *uap = v; + struct proc *p = l->l_proc; + struct timex ntv; + int error = 0; + + if ((error = copyin((caddr_t)SCARG(uap, tp), (caddr_t)&ntv, + sizeof(ntv))) != 0) + return (error); + + if (ntv.modes != 0 && (error = suser(p->p_ucred, &p->p_acflag)) != 0) + return (error); + + return (ntp_adjtime1(&ntv, v, retval)); +} + +int +ntp_adjtime1(ntv, v, retval) + struct timex *ntv; + void *v; + register_t *retval; +{ + struct sys_ntp_adjtime_args /* { + syscallarg(struct timex *) tp; + } */ *uap = v; + long freq; + int modes; + int s; + int error = 0; + + /* + * Update selected clock variables - only the superuser can + * change anything. Note that there is no error checking here on + * the assumption the superuser should know what it is doing. + * Note that either the time constant or TAI offset are loaded + * from the ntv.constant member, depending on the mode bits. If + * the STA_PLL bit in the status word is cleared, the state and + * status words are reset to the initial values at boot. + */ + 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) + time_esterror = ntv->esterror; + if (modes & MOD_STATUS) { + if (time_status & STA_PLL && !(ntv->status & STA_PLL)) { + time_state = TIME_OK; + time_status = STA_UNSYNC; +#ifdef PPS_SYNC + pps_shift = PPS_FAVG; +#endif /* PPS_SYNC */ + } + time_status &= STA_RONLY; + time_status |= ntv->status & ~STA_RONLY; + } + if (modes & MOD_TIMECONST) { + if (ntv->constant < 0) + time_constant = 0; + else if (ntv->constant > MAXTC) + time_constant = MAXTC; + else + time_constant = ntv->constant; + } + if (modes & MOD_TAI) { + if (ntv->constant > 0) /* XXX zero & negative numbers ? */ + time_tai = ntv->constant; + } +#ifdef PPS_SYNC + if (modes & MOD_PPSMAX) { + if (ntv->shift < PPS_FAVG) + pps_shiftmax = PPS_FAVG; + else if (ntv->shift > PPS_FAVGMAX) + pps_shiftmax = PPS_FAVGMAX; + else + pps_shiftmax = ntv.shift; + } +#endif /* PPS_SYNC */ + if (modes & MOD_NANO) + time_status |= STA_NANO; + if (modes & MOD_MICRO) + time_status &= ~STA_NANO; + if (modes & MOD_CLKB) + time_status |= STA_CLK; + if (modes & MOD_CLKA) + time_status &= ~STA_CLK; + if (modes & MOD_FREQUENCY) { + freq = (ntv->freq * 1000LL) >> 16; + if (freq > MAXFREQ) + L_LINT(time_freq, MAXFREQ); + else if (freq < -MAXFREQ) + L_LINT(time_freq, -MAXFREQ); + else { + /* + * ntv.freq is [PPM * 2^16] = [us/s * 2^16] + * time_freq is [ns/s * 2^32] + */ + time_freq = ntv->freq * 1000LL * 65536LL; + } +#ifdef PPS_SYNC + pps_freq = time_freq; +#endif /* PPS_SYNC */ + } + if (modes & MOD_OFFSET) { + if (time_status & STA_NANO) + hardupdate(ntv->offset); + else + hardupdate(ntv->offset * 1000); + } + + /* + * Retrieve all clock variables. Note that the TAI offset is + * returned only by ntp_gettime(); + */ + if (time_status & STA_NANO) + ntv->offset = L_GINT(time_offset); + else + ntv->offset = L_GINT(time_offset) / 1000; /* XXX rounding ? */ + ntv->freq = L_GINT((time_freq / 1000LL) << 16); + ntv->maxerror = time_maxerror; + ntv->esterror = time_esterror; + ntv->status = time_status; + ntv->constant = time_constant; + if (time_status & STA_NANO) + ntv->precision = time_precision; + else + ntv->precision = time_precision / 1000; + ntv->tolerance = MAXFREQ * SCALE_PPM; +#ifdef PPS_SYNC + ntv->shift = pps_shift; + ntv->ppsfreq = L_GINT((pps_freq / 1000LL) << 16); + if (time_status & STA_NANO) + ntv->jitter = pps_jitter; + else + ntv->jitter = pps_jitter / 1000; + ntv->stabil = pps_stabil; + ntv->calcnt = pps_calcnt; + ntv->errcnt = pps_errcnt; + ntv->jitcnt = pps_jitcnt; + ntv->stbcnt = pps_stbcnt; +#endif /* PPS_SYNC */ + splx(s); + + error = copyout((caddr_t)ntv, (caddr_t)SCARG(uap, tp), sizeof(*ntv)); + if (!error) { + + /* + * Status word error decode. See comments in + * ntp_gettime() routine. + */ + if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) || + (time_status & (STA_PPSFREQ | STA_PPSTIME) && + !(time_status & STA_PPSSIGNAL)) || + (time_status & STA_PPSTIME && + time_status & STA_PPSJITTER) || + (time_status & STA_PPSFREQ && + time_status & (STA_PPSWANDER | STA_PPSERROR))) { + *retval = TIME_ERROR; + } else + *retval = (register_t)time_state; + } + return error; +} + +/* + * second_overflow() - called after ntp_tick_adjust() + * + * This routine is ordinarily called immediately following the above + * routine ntp_tick_adjust(). While these two routines are normally + * combined, they are separated here only for the purposes of + * simulation. + */ +void +ntp_update_second(int64_t *adjustment, time_t *newsec) +{ + int tickrate; + l_fp ftemp; /* 32/64-bit temporary */ + + /* + * On rollover of the second both the nanosecond and microsecond + * clocks are updated and the state machine cranked as + * necessary. The phase adjustment to be used for the next + * second is calculated and the maximum error is increased by + * the tolerance. + */ + time_maxerror += MAXFREQ / 1000; + + /* + * Leap second processing. If in leap-insert state at + * the end of the day, the system clock is set back one + * second; if in leap-delete state, the system clock is + * set ahead one second. The nano_time() routine or + * external clock driver will insure that reported time + * is always monotonic. + */ + switch (time_state) { + + /* + * No warning. + */ + case TIME_OK: + if (time_status & STA_INS) + time_state = TIME_INS; + else if (time_status & STA_DEL) + time_state = TIME_DEL; + break; + + /* + * Insert second 23:59:60 following second + * 23:59:59. + */ + case TIME_INS: + if (!(time_status & STA_INS)) + time_state = TIME_OK; + else if ((*newsec) % 86400 == 0) { + (*newsec)--; + time_state = TIME_OOP; + time_tai++; + } + break; + + /* + * Delete second 23:59:59. + */ + case TIME_DEL: + if (!(time_status & STA_DEL)) + time_state = TIME_OK; + else if (((*newsec) + 1) % 86400 == 0) { + (*newsec)++; + time_tai--; + time_state = TIME_WAIT; + } + break; + + /* + * Insert second in progress. + */ + case TIME_OOP: + time_state = TIME_WAIT; + break; + + /* + * Wait for status bits to clear. + */ + case TIME_WAIT: + if (!(time_status & (STA_INS | STA_DEL))) + time_state = TIME_OK; + } + + /* + * Compute the total time adjustment for the next second + * in ns. The offset is reduced by a factor depending on + * whether the PPS signal is operating. Note that the + * value is in effect scaled by the clock frequency, + * since the adjustment is added at each tick interrupt. + */ + ftemp = time_offset; +#ifdef PPS_SYNC + /* XXX even if PPS signal dies we should finish adjustment ? */ + if (time_status & STA_PPSTIME && time_status & + STA_PPSSIGNAL) + L_RSHIFT(ftemp, pps_shift); + else + L_RSHIFT(ftemp, SHIFT_PLL + time_constant); +#else + L_RSHIFT(ftemp, SHIFT_PLL + time_constant); +#endif /* PPS_SYNC */ + time_adj = ftemp; + L_SUB(time_offset, ftemp); + L_ADD(time_adj, time_freq); + + /* + * Apply any correction from adjtime(2). If more than one second + * off we slew at a rate of 5ms/s (5000 PPM) else 500us/s (500PPM) + * until the last second is slewed the final < 500 usecs. + */ + if (time_adjtime != 0) { + if (time_adjtime > 1000000) + tickrate = 5000; + else if (time_adjtime < -1000000) + tickrate = -5000; + else if (time_adjtime > 500) + tickrate = 500; + else if (time_adjtime < -500) + tickrate = -500; + else + tickrate = time_adjtime; + time_adjtime -= tickrate; + L_LINT(ftemp, tickrate * 1000); + L_ADD(time_adj, ftemp); + } + *adjustment = time_adj; + +#ifdef PPS_SYNC + if (pps_valid > 0) + pps_valid--; + else + time_status &= ~STA_PPSSIGNAL; +#endif /* PPS_SYNC */ +} + +/* + * ntp_init() - initialize variables and structures + * + * This routine must be called after the kernel variables hz and tick + * are set or changed and before the next tick interrupt. In this + * particular implementation, these values are assumed set elsewhere in + * the kernel. The design allows the clock frequency and tick interval + * to be changed while the system is running. So, this routine should + * probably be integrated with the code that does that. + */ +void +ntp_init(void) +{ + + /* + * The following variables are initialized only at startup. Only + * those structures not cleared by the compiler need to be + * initialized, and these only in the simulator. In the actual + * kernel, any nonzero values here will quickly evaporate. + */ + L_CLR(time_offset); + L_CLR(time_freq); +#ifdef PPS_SYNC + pps_tf[0].tv_sec = pps_tf[0].tv_nsec = 0; + pps_tf[1].tv_sec = pps_tf[1].tv_nsec = 0; + pps_tf[2].tv_sec = pps_tf[2].tv_nsec = 0; + pps_fcount = 0; + L_CLR(pps_freq); +#endif /* PPS_SYNC */ +} + +/* + * hardupdate() - local clock update + * + * This routine is called by ntp_adjtime() to update the local clock + * phase and frequency. The implementation is of an adaptive-parameter, + * hybrid phase/frequency-lock loop (PLL/FLL). The routine computes new + * time and frequency offset estimates for each call. If the kernel PPS + * discipline code is configured (PPS_SYNC), the PPS signal itself + * determines the new time offset, instead of the calling argument. + * Presumably, calls to ntp_adjtime() occur only when the caller + * believes the local clock is valid within some bound (+-128 ms with + * NTP). If the caller's time is far different than the PPS time, an + * argument will ensue, and it's not clear who will lose. + * + * For uncompensated quartz crystal oscillators and nominal update + * intervals less than 256 s, operation should be in phase-lock mode, + * where the loop is disciplined to phase. For update intervals greater + * than 1024 s, operation should be in frequency-lock mode, where the + * loop is disciplined to frequency. Between 256 s and 1024 s, the mode + * is selected by the STA_MODE status bit. + * + * Note: splclock() is in effect. + */ +void +hardupdate(long offset) +{ + long mtemp; + l_fp ftemp; + + /* + * Select how the phase is to be controlled and from which + * source. If the PPS signal is present and enabled to + * discipline the time, the PPS offset is used; otherwise, the + * argument offset is used. + */ + if (!(time_status & STA_PLL)) + return; + if (!(time_status & STA_PPSTIME && time_status & + STA_PPSSIGNAL)) { + if (offset > MAXPHASE) + time_monitor = MAXPHASE; + else if (offset < -MAXPHASE) + time_monitor = -MAXPHASE; + else + time_monitor = offset; + L_LINT(time_offset, time_monitor); + } + + /* + * Select how the frequency is to be controlled and in which + * mode (PLL or FLL). If the PPS signal is present and enabled + * to discipline the frequency, the PPS frequency is used; + * otherwise, the argument offset is used to compute it. + */ + if (time_status & STA_PPSFREQ && time_status & STA_PPSSIGNAL) { + time_reftime = time_second; + return; + } + if (time_status & STA_FREQHOLD || time_reftime == 0) + time_reftime = time_second; + mtemp = time_second - time_reftime; + L_LINT(ftemp, time_monitor); + L_RSHIFT(ftemp, (SHIFT_PLL + 2 + time_constant) << 1); + L_MPY(ftemp, mtemp); + L_ADD(time_freq, ftemp); + time_status &= ~STA_MODE; + if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > + MAXSEC)) { + L_LINT(ftemp, (time_monitor << 4) / mtemp); + L_RSHIFT(ftemp, SHIFT_FLL + 4); + L_ADD(time_freq, ftemp); + time_status |= STA_MODE; + } + time_reftime = time_second; + if (L_GINT(time_freq) > MAXFREQ) + L_LINT(time_freq, MAXFREQ); + else if (L_GINT(time_freq) < -MAXFREQ) + L_LINT(time_freq, -MAXFREQ); +} + +#ifdef PPS_SYNC +/* + * hardpps() - discipline CPU clock oscillator to external PPS signal + * + * This routine is called at each PPS interrupt in order to discipline + * the CPU clock oscillator to the PPS signal. It measures the PPS phase + * and leaves it in a handy spot for the hardclock() routine. It + * integrates successive PPS phase differences and calculates the + * frequency offset. This is used in hardclock() to discipline the CPU + * clock oscillator so that intrinsic frequency error is cancelled out. + * The code requires the caller to capture the time and hardware counter + * value at the on-time PPS signal transition. + * + * Note that, on some Unix systems, this routine runs at an interrupt + * priority level higher than the timer interrupt routine hardclock(). + * Therefore, the variables used are distinct from the hardclock() + * variables, except for certain exceptions: The PPS frequency pps_freq + * and phase pps_offset variables are determined by this routine and + * updated atomically. The time_tolerance variable can be considered a + * constant, since it is infrequently changed, and then only when the + * PPS signal is disabled. The watchdog counter pps_valid is updated + * once per second by hardclock() and is atomically cleared in this + * routine. + */ +void +hardpps(struct timespec *tvp, /* time at PPS */ + long usec /* hardware counter at PPS */) +{ + long u_sec, u_nsec, v_nsec; /* temps */ + l_fp ftemp; + + /* + * The signal is first processed by a range gate and frequency + * discriminator. The range gate rejects noise spikes outside + * the range +-500 us. The frequency discriminator rejects input + * signals with apparent frequency outside the range 1 +-500 + * PPM. If two hits occur in the same second, we ignore the + * later hit; if not and a hit occurs outside the range gate, + * keep the later hit for later comparison, but do not process + * it. + */ + time_status |= STA_PPSSIGNAL | STA_PPSJITTER; + time_status &= ~(STA_PPSWANDER | STA_PPSERROR); + pps_valid = PPS_VALID; + u_sec = tsp->tv_sec; + u_nsec = tsp->tv_nsec; + if (u_nsec >= (NANOSECOND >> 1)) { + u_nsec -= NANOSECOND; + u_sec++; + } + v_nsec = u_nsec - pps_tf[0].tv_nsec; + if (u_sec == pps_tf[0].tv_sec && v_nsec < NANOSECOND - + MAXFREQ) + return; + pps_tf[2] = pps_tf[1]; + pps_tf[1] = pps_tf[0]; + pps_tf[0].tv_sec = u_sec; + pps_tf[0].tv_nsec = u_nsec; + + /* + * Compute the difference between the current and previous + * counter values. If the difference exceeds 0.5 s, assume it + * has wrapped around, so correct 1.0 s. If the result exceeds + * the tick interval, the sample point has crossed a tick + * boundary during the last second, so correct the tick. Very + * intricate. + */ + u_nsec = nsec; + if (u_nsec > (NANOSECOND >> 1)) + u_nsec -= NANOSECOND; + else if (u_nsec < -(NANOSECOND >> 1)) + u_nsec += NANOSECOND; + pps_fcount += u_nsec; + if (v_nsec > MAXFREQ || v_nsec < -MAXFREQ) + return; + time_status &= ~STA_PPSJITTER; + + /* + * A three-stage median filter is used to help denoise the PPS + * time. The median sample becomes the time offset estimate; the + * difference between the other two samples becomes the time + * dispersion (jitter) estimate. + */ + if (pps_tf[0].tv_nsec > pps_tf[1].tv_nsec) { + if (pps_tf[1].tv_nsec > pps_tf[2].tv_nsec) { + v_nsec = pps_tf[1].tv_nsec; /* 0 1 2 */ + u_nsec = pps_tf[0].tv_nsec - pps_tf[2].tv_nsec; + } else if (pps_tf[2].tv_nsec > pps_tf[0].tv_nsec) { + v_nsec = pps_tf[0].tv_nsec; /* 2 0 1 */ + u_nsec = pps_tf[2].tv_nsec - pps_tf[1].tv_nsec; + } else { + v_nsec = pps_tf[2].tv_nsec; /* 0 2 1 */ + u_nsec = pps_tf[0].tv_nsec - pps_tf[1].tv_nsec; + } + } else { + if (pps_tf[1].tv_nsec < pps_tf[2].tv_nsec) { + v_nsec = pps_tf[1].tv_nsec; /* 2 1 0 */ + u_nsec = pps_tf[2].tv_nsec - pps_tf[0].tv_nsec; + } else if (pps_tf[2].tv_nsec < pps_tf[0].tv_nsec) { + v_nsec = pps_tf[0].tv_nsec; /* 1 0 2 */ + u_nsec = pps_tf[1].tv_nsec - pps_tf[2].tv_nsec; + } else { + v_nsec = pps_tf[2].tv_nsec; /* 1 2 0 */ + u_nsec = pps_tf[1].tv_nsec - pps_tf[0].tv_nsec; + } + } + + /* + * Nominal jitter is due to PPS signal noise and interrupt + * latency. If it exceeds the popcorn threshold, the sample is + * discarded. otherwise, if so enabled, the time offset is + * updated. We can tolerate a modest loss of data here without + * much degrading time accuracy. + */ + if (u_nsec > (pps_jitter << PPS_POPCORN)) { + time_status |= STA_PPSJITTER; + pps_jitcnt++; + } else if (time_status & STA_PPSTIME) { + time_monitor = -v_nsec; + L_LINT(time_offset, time_monitor); + } + pps_jitter += (u_nsec - pps_jitter) >> PPS_FAVG; + u_sec = pps_tf[0].tv_sec - pps_lastsec; + if (u_sec < (1 << pps_shift)) + return; + + /* + * At the end of the calibration interval the difference between + * the first and last counter values becomes the scaled + * frequency. It will later be divided by the length of the + * interval to determine the frequency update. If the frequency + * exceeds a sanity threshold, or if the actual calibration + * interval is not equal to the expected length, the data are + * discarded. We can tolerate a modest loss of data here without + * much degrading frequency accuracy. + */ + pps_calcnt++; + v_nsec = -pps_fcount; + pps_lastsec = pps_tf[0].tv_sec; + pps_fcount = 0; + u_nsec = MAXFREQ << pps_shift; + if (v_nsec > u_nsec || v_nsec < -u_nsec || u_sec != (1 << + pps_shift)) { + time_status |= STA_PPSERROR; + pps_errcnt++; + return; + } + + /* + * Here the raw frequency offset and wander (stability) is + * calculated. If the wander is less than the wander threshold + * for four consecutive averaging intervals, the interval is + * doubled; if it is greater than the threshold for four + * consecutive intervals, the interval is halved. The scaled + * frequency offset is converted to frequency offset. The + * stability metric is calculated as the average of recent + * frequency changes, but is used only for performance + * monitoring. + */ + L_LINT(ftemp, v_nsec); + L_RSHIFT(ftemp, pps_shift); + L_SUB(ftemp, pps_freq); + u_nsec = L_GINT(ftemp); + if (u_nsec > PPS_MAXWANDER) { + L_LINT(ftemp, PPS_MAXWANDER); + pps_intcnt--; + time_status |= STA_PPSWANDER; + pps_stbcnt++; + } else if (u_nsec < -PPS_MAXWANDER) { + L_LINT(ftemp, -PPS_MAXWANDER); + pps_intcnt--; + time_status |= STA_PPSWANDER; + pps_stbcnt++; + } else { + pps_intcnt++; + } + if (pps_intcnt >= 4) { + pps_intcnt = 4; + if (pps_shift < pps_shiftmax) { + pps_shift++; + pps_intcnt = 0; + } + } else if (pps_intcnt <= -4 || pps_shift > pps_shiftmax) { + pps_intcnt = -4; + if (pps_shift > PPS_FAVG) { + pps_shift--; + pps_intcnt = 0; + } + } + if (u_nsec < 0) + u_nsec = -u_nsec; + pps_stabil += (u_nsec * SCALE_PPM - pps_stabil) >> PPS_FAVG; + + /* + * The PPS frequency is recalculated and clamped to the maximum + * MAXFREQ. If enabled, the system clock frequency is updated as + * well. + */ + L_ADD(pps_freq, ftemp); + u_nsec = L_GINT(pps_freq); + if (u_nsec > MAXFREQ) + L_LINT(pps_freq, MAXFREQ); + else if (u_nsec < -MAXFREQ) + L_LINT(pps_freq, -MAXFREQ); + if (time_status & STA_PPSFREQ) + time_freq = pps_freq; +} +#endif /* PPS_SYNC */ + +/* + * return information about kernel precision timekeeping + * XXXXXXX this should share code with sys_ntp_gettime XXXXXXX + */ +static int +sysctl_kern_ntptime(SYSCTLFN_ARGS) +{ + struct sysctlnode node; + struct ntptimeval ntv; + + /* + * Construct ntp_timeval. + */ + + nanotime(&ntv.time); + ntv.maxerror = time_maxerror; + ntv.esterror = time_esterror; + ntv.tai = time_tai; + ntv.time_state = time_state; + +#ifdef notyet /* XXX why not!?? */ + /* + * Status word error decode. If any of these conditions occur, + * an error is returned, instead of the status word. Most + * applications will care only about the fact the system clock + * may not be trusted, not about the details. + * + * Hardware or software error + */ + if ((time_status & (STA_UNSYNC | STA_CLOCKERR)) || + + /* + * PPS signal lost when either time or frequency synchronization + * requested + */ + (time_status & (STA_PPSFREQ | STA_PPSTIME) && + !(time_status & STA_PPSSIGNAL)) || + + /* + * PPS jitter exceeded when time synchronization requested + */ + (time_status & STA_PPSTIME && + time_status & STA_PPSJITTER) || + + /* + * PPS wander exceeded or calibration error when frequency + * synchronization requested + */ + (time_status & STA_PPSFREQ && + time_status & (STA_PPSWANDER | STA_PPSERROR))) + ntv.time_state = TIME_ERROR; + else + ntv.time_state = time_state; +#endif /* notyet */ + + node = *rnode; + node.sysctl_data = &ntv; + node.sysctl_size = sizeof(ntv); + return (sysctl_lookup(SYSCTLFN_CALL(&node))); +} + +SYSCTL_SETUP(sysctl_kern_ntptime_setup, "sysctl kern.ntptime node setup") +{ + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_NODE, "kern", NULL, + NULL, 0, NULL, 0, + CTL_KERN, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_STRUCT, "ntptime", + SYSCTL_DESCR("Kernel clock values for NTP"), + sysctl_kern_ntptime, 0, NULL, + sizeof(struct ntptimeval), + CTL_KERN, KERN_NTPTIME, CTL_EOL); +} +#if 0 /* XXXXXXXXXXXXXXX freebsd - add these?? XXXXXXXXXXXXXXX */ +#ifdef PPS_SYNC +SYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shiftmax, CTLFLAG_RW, &pps_shiftmax, 0, ""); +SYSCTL_INT(_kern_ntp_pll, OID_AUTO, pps_shift, CTLFLAG_RW, &pps_shift, 0, ""); +SYSCTL_INT(_kern_ntp_pll, OID_AUTO, time_monitor, CTLFLAG_RD, &time_monitor, 0, ""); + +SYSCTL_OPAQUE(_kern_ntp_pll, OID_AUTO, pps_freq, CTLFLAG_RD, &pps_freq, sizeof(pps_freq), "I", ""); +SYSCTL_OPAQUE(_kern_ntp_pll, OID_AUTO, time_freq, CTLFLAG_RD, &time_freq, sizeof(time_freq), "I", ""); +#endif +#endif /* XXXXXXXXXXXXXXX freebsd - add these?? XXXXXXXXXXXXXXX */ +#else /* !NTP */ +/* For some reason, raising SIGSYS (as sys_nosys would) is problematic. */ + +int +sys_ntp_gettime(l, v, retval) + struct lwp *l; + void *v; + register_t *retval; +{ + + return(ENOSYS); +} +#endif /* !NTP */ +#else /* !__HAVE_TIMECOUNTER */ /****************************************************************************** * * * Copyright (c) David L. Mills 1993, 1994 * @@ -419,3 +1426,4 @@ sys_ntp_gettime(l, v, retval) return(ENOSYS); } #endif /* !NTP */ +#endif /* !__HAVE_TIMECOUNTER */ Index: sys/kern/kern_sig.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_sig.c,v retrieving revision 1.211 diff -d -p -u -r1.211 kern_sig.c --- sys/kern/kern_sig.c 12 Nov 2005 02:27:48 -0000 1.211 +++ sys/kern/kern_sig.c 22 Nov 2005 13:41:34 -0000 @@ -2347,10 +2347,9 @@ __sigtimedwait1(struct lwp *l, void *v, } */ *uap = v; sigset_t *waitset, twaitset; struct proc *p = l->l_proc; - int error, signum, s; + int error, signum; int timo = 0; - struct timeval tvstart; - struct timespec ts; + struct timespec ts, tsstart; ksiginfo_t *ksi; MALLOC(waitset, sigset_t *, sizeof(sigset_t), M_TEMP, M_WAITOK); @@ -2405,12 +2404,10 @@ __sigtimedwait1(struct lwp *l, void *v, return (EAGAIN); /* - * Remember current mono_time, it would be used in + * Remember current uptime, it would be used in * ECANCELED/ERESTART case. */ - s = splclock(); - tvstart = mono_time; - splx(s); + getnanouptime(&tsstart); } /* @@ -2457,26 +2454,22 @@ __sigtimedwait1(struct lwp *l, void *v, * or called again. */ if (timo && (error == ERESTART || error == ECANCELED)) { - struct timeval tvnow, tvtimo; + struct timespec tsnow; int err; - s = splclock(); - tvnow = mono_time; - splx(s); - - TIMESPEC_TO_TIMEVAL(&tvtimo, &ts); +/* XXX double check the following change */ + getnanouptime(&tsnow); /* compute how much time has passed since start */ - timersub(&tvnow, &tvstart, &tvnow); + timespecsub(&tsnow, &tsstart, &tsnow); /* substract passed time from timeout */ - timersub(&tvtimo, &tvnow, &tvtimo); + timespecsub(&ts, &tsnow, &ts); - if (tvtimo.tv_sec < 0) { + if (ts.tv_sec < 0) { error = EAGAIN; goto fail; } - - TIMEVAL_TO_TIMESPEC(&tvtimo, &ts); +/* XXX double check the previous change */ /* copy updated timeout to userland */ if ((err = (*put_timeout)(&ts, SCARG(uap, timeout), Index: sys/kern/kern_synch.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_synch.c,v retrieving revision 1.153 diff -d -p -u -r1.153 kern_synch.c --- sys/kern/kern_synch.c 1 Nov 2005 09:07:53 -0000 1.153 +++ sys/kern/kern_synch.c 22 Nov 2005 13:41:35 -0000 @@ -426,6 +426,7 @@ ltsleep(__volatile const void *ident, in int relock = (priority & PNORELOCK) == 0; int exiterr = (priority & PNOEXITERR) == 0; +//XXX debug printf("ltsleep(%p, %d, %s, %d, %p)\n", ident, priority, wmesg, timo, interlock); /* * XXXSMP * This is probably bogus. Figure out what the right @@ -494,7 +495,10 @@ ltsleep(__volatile const void *ident, in *(qp->sq_tailp = &l->l_forw) = 0; if (timo) +{ +//XXX debug printf("callout_reset(%p, %d, %p, %p);\n", &l->l_tsleep_ch, timo, endtsleep, l); callout_reset(&l->l_tsleep_ch, timo, endtsleep, l); +} /* * We can now release the interlock; the scheduler_slock @@ -573,7 +577,10 @@ ltsleep(__volatile const void *ident, in return (EWOULDBLOCK); } } else if (timo) +{ +//XXX debug printf("callout_stop(%p)\n", &l->l_tsleep_ch); callout_stop(&l->l_tsleep_ch); +} if (catch) { const int cancelled = l->l_flag & L_CANCELLED; Index: sys/kern/kern_sysctl.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_sysctl.c,v retrieving revision 1.187 diff -d -p -u -r1.187 kern_sysctl.c --- sys/kern/kern_sysctl.c 29 Oct 2005 12:26:37 -0000 1.187 +++ sys/kern/kern_sysctl.c 22 Nov 2005 13:41:39 -0000 @@ -325,6 +325,7 @@ sys___sysctl(struct lwp *l, void *v, reg * that's an ENOMEM error */ if (error == 0 && SCARG(uap, old) != NULL && savelen < oldlen) +/* XXX */ error = ENOMEM; return (error); Index: sys/kern/kern_tc.c =================================================================== RCS file: sys/kern/kern_tc.c diff -N sys/kern/kern_tc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/kern/kern_tc.c 22 Nov 2005 13:41:41 -0000 @@ -0,0 +1,824 @@ +/* $NetBSD$ */ + +/*- + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +#include +/* __FBSDID("$FreeBSD: src/sys/kern/kern_tc.c,v 1.166 2005/09/19 22:16:31 andre Exp $"); */ +__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.94 2005/10/02 17:51:27 chs Exp $"); + +#include "opt_ntp.h" + +#include +#ifdef __HAVE_TIMECOUNTER /* XXX */ +#include +#include /* XXX just to get AB_VERBOSE */ +#include +#include +#include +#include +#include +#include + +/* + * A large step happens on boot. This constant detects such steps. + * It is relatively small so that ntp_update_second gets called enough + * in the typical 'missed a couple of seconds' case, but doesn't loop + * forever when the time step is large. + */ +#define LARGE_STEP 200 + +/* + * Implement a dummy timecounter which we can use until we get a real one + * in the air. This allows the console and other early stuff to use + * time services. + */ + +static u_int +dummy_get_timecount(struct timecounter *tc) +{ + static u_int now; + + return (++now); +} + +static struct timecounter dummy_timecounter = { + dummy_get_timecount, 0, ~0u, 1000000, "dummy", -1000000 +}; + +struct timehands { + /* These fields must be initialized by the driver. */ + struct timecounter *th_counter; + int64_t th_adjustment; + u_int64_t th_scale; + u_int th_offset_count; + struct bintime th_offset; + struct timeval th_microtime; + struct timespec th_nanotime; + /* Fields not to be copied in tc_windup start with th_generation. */ + volatile 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 th0 = { + &dummy_timecounter, + 0, + (uint64_t)-1 / 1000000, + 0, + {1, 0}, + {0, 0}, + {0, 0}, + 1, + &th1 +}; + +static struct timehands *volatile timehands = &th0; +struct timecounter *timecounter = &dummy_timecounter; +static struct timecounter *timecounters = &dummy_timecounter; + +time_t time_second = 1; +time_t time_uptime = 1; + +static struct bintime boottimebin; +struct timeval boottime; +#if 0 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX freebsd sysctl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +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"); + +SYSCTL_NODE(_kern, OID_AUTO, timecounter, CTLFLAG_RW, 0, ""); + +#endif /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX freebsd sysctl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +static int timestepwarnings; +#if 0 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX freebsd sysctl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +SYSCTL_INT(_kern_timecounter, OID_AUTO, stepwarnings, CTLFLAG_RW, + ×tepwarnings, 0, ""); + +#define TC_STATS(foo) \ + static u_int foo; \ + SYSCTL_UINT(_kern_timecounter, OID_AUTO, foo, CTLFLAG_RD, &foo, 0, "");\ + struct __hack + +TC_STATS(nbinuptime); TC_STATS(nnanouptime); TC_STATS(nmicrouptime); +TC_STATS(nbintime); TC_STATS(nnanotime); TC_STATS(nmicrotime); +TC_STATS(ngetbinuptime); TC_STATS(ngetnanouptime); TC_STATS(ngetmicrouptime); +TC_STATS(ngetbintime); TC_STATS(ngetnanotime); TC_STATS(ngetmicrotime); +TC_STATS(nsetclock); + +#undef TC_STATS +#else /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX freebsd sysctl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +u_int nbinuptime; +u_int nnanouptime; +u_int nmicrouptime; + +u_int nbintime; +u_int nnanotime; +u_int nmicrotime; + +u_int ngetbinuptime; +u_int ngetnanouptime; +u_int ngetmicrouptime; + +u_int ngetbintime; +u_int ngetnanotime; +u_int ngetmicrotime; + +u_int nsetclock; +#endif /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX freebsd sysctl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ + +static void tc_windup(void); +#if 0 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX freebsd sysctl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ + +static int +sysctl_kern_boottime(SYSCTL_HANDLER_ARGS) +{ +#ifdef SCTL_MASK32 + int tv[2]; + + if (req->flags & SCTL_MASK32) { + tv[0] = boottime.tv_sec; + tv[1] = boottime.tv_usec; + return SYSCTL_OUT(req, tv, sizeof(tv)); + } else +#endif + return SYSCTL_OUT(req, &boottime, sizeof(boottime)); +} +#endif /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX freebsd sysctl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ + +/* + * Return the difference between the timehands' counter value now and what + * was when we copied it to the timehands' offset_count. + */ +static __inline u_int +tc_delta(struct timehands *th) +{ + struct timecounter *tc; + + tc = th->th_counter; + return ((tc->tc_get_timecount(tc) - th->th_offset_count) & + tc->tc_counter_mask); +} + +/* + * Functions for reading the time. We have to loop until we are sure that + * the timehands that we operated on was not updated under our feet. See + * the comment in for a description of these 12 functions. + */ + +void +binuptime(struct bintime *bt) +{ + struct timehands *th; + u_int gen; + + nbinuptime++; + do { + th = timehands; + gen = th->th_generation; + *bt = th->th_offset; + bintime_addx(bt, th->th_scale * tc_delta(th)); + } while (gen == 0 || gen != th->th_generation); +} + +void +nanouptime(struct timespec *tsp) +{ + struct bintime bt; + + nnanouptime++; + binuptime(&bt); + bintime2timespec(&bt, tsp); +} + +void +microuptime(struct timeval *tvp) +{ + struct bintime bt; + + nmicrouptime++; + binuptime(&bt); + bintime2timeval(&bt, tvp); +} + +void +bintime(struct bintime *bt) +{ + + nbintime++; + binuptime(bt); + bintime_add(bt, &boottimebin); +} + +void +nanotime(struct timespec *tsp) +{ + struct bintime bt; + + nnanotime++; + bintime(&bt); + bintime2timespec(&bt, tsp); +} + +void +microtime(struct timeval *tvp) +{ + struct bintime bt; + + nmicrotime++; + bintime(&bt); + bintime2timeval(&bt, tvp); +} + +void +getbinuptime(struct bintime *bt) +{ + struct timehands *th; + u_int gen; + + ngetbinuptime++; + do { + th = timehands; + gen = th->th_generation; + *bt = th->th_offset; + } while (gen == 0 || gen != th->th_generation); +} + +void +getnanouptime(struct timespec *tsp) +{ + struct timehands *th; + u_int gen; + + ngetnanouptime++; + do { + th = timehands; + gen = th->th_generation; + bintime2timespec(&th->th_offset, tsp); + } while (gen == 0 || gen != th->th_generation); +} + +void +getmicrouptime(struct timeval *tvp) +{ + struct timehands *th; + u_int gen; + + ngetmicrouptime++; + do { + th = timehands; + gen = th->th_generation; + bintime2timeval(&th->th_offset, tvp); + } while (gen == 0 || gen != th->th_generation); +} + +void +getbintime(struct bintime *bt) +{ + struct timehands *th; + u_int gen; + + ngetbintime++; + do { + th = timehands; + gen = th->th_generation; + *bt = th->th_offset; + } while (gen == 0 || gen != th->th_generation); + bintime_add(bt, &boottimebin); +} + +void +getnanotime(struct timespec *tsp) +{ + struct timehands *th; + u_int gen; + + ngetnanotime++; + do { + th = timehands; + gen = th->th_generation; + *tsp = th->th_nanotime; + } while (gen == 0 || gen != th->th_generation); +} + +void +getmicrotime(struct timeval *tvp) +{ + struct timehands *th; + u_int gen; + + ngetmicrotime++; + do { + th = timehands; + gen = th->th_generation; + *tvp = th->th_microtime; + } while (gen == 0 || gen != th->th_generation); +} + +/* + * Initialize a new timecounter and possibly use it. + */ +void +tc_init(struct timecounter *tc) +{ + u_int u; + + u = tc->tc_frequency / tc->tc_counter_mask; + /* XXX: We need some margin here, 10% is a guess */ + u *= 11; + u /= 10; + if (u > hz && tc->tc_quality >= 0) { + tc->tc_quality = -2000; + if (bootverbose) { + printf("Timecounter \"%s\" frequency %ju Hz", + tc->tc_name, (uintmax_t)tc->tc_frequency); + printf(" -- Insufficient hz, needs at least %u\n", u); + } + } else if (tc->tc_quality >= 0 || bootverbose) { + printf("Timecounter \"%s\" frequency %ju Hz quality %d\n", + tc->tc_name, (uintmax_t)tc->tc_frequency, + tc->tc_quality); + } + + tc->tc_next = timecounters; + timecounters = tc; + /* + * Never automatically use a timecounter with negative quality. + * Even though we run on the dummy counter, switching here may be + * worse since this timecounter may not be monotonous. + */ + if (tc->tc_quality < 0) + return; + if (tc->tc_quality < timecounter->tc_quality) + return; + if (tc->tc_quality == timecounter->tc_quality && + tc->tc_frequency < timecounter->tc_frequency) + return; + (void)tc->tc_get_timecount(tc); + (void)tc->tc_get_timecount(tc); + timecounter = tc; +} + +/* Report the frequency of the current timecounter. */ +u_int64_t +tc_getfrequency(void) +{ + + return (timehands->th_counter->tc_frequency); +} + +/* + * 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) +{ + struct timespec ts2; + struct bintime bt, bt2; + + nsetclock++; + binuptime(&bt2); + timespec2bintime(ts, &bt); + 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(); + if (timestepwarnings) { + bintime2timespec(&bt2, &ts2); + log(LOG_INFO, "Time stepped from %jd.%09ld to %jd.%09ld\n", + (intmax_t)ts2.tv_sec, ts2.tv_nsec, + (intmax_t)ts->tv_sec, ts->tv_nsec); + } +} + +/* + * Initialize the next struct timehands in the ring and make + * it the active timehands. Along the way we might switch to a different + * timecounter and/or do seconds processing in NTP. Slightly magic. + */ +static void +tc_windup(void) +{ + struct bintime bt; + struct timehands *th, *tho; + u_int64_t scale; + u_int delta, ncount, ogen; +#ifdef NTP + int i; + time_t t; +#endif /* NTP */ + + /* + * Make the next timehands a copy of the current one, but do not + * overwrite the generation or next pointer. While we update + * the contents, the generation must be zero. + */ + tho = timehands; + th = tho->th_next; + ogen = th->th_generation; + th->th_generation = 0; + bcopy(tho, th, offsetof(struct timehands, th_generation)); + + /* + * Capture a timecounter delta on the current timecounter and if + * changing timecounters, a counter value from the new timecounter. + * Update the offset fields accordingly. + */ + delta = tc_delta(th); + if (th->th_counter != timecounter) + ncount = timecounter->tc_get_timecount(timecounter); + else + ncount = 0; + th->th_offset_count += delta; + th->th_offset_count &= th->th_counter->tc_counter_mask; + bintime_addx(&th->th_offset, th->th_scale * delta); + +#ifdef PPS_SYNC + /* + * Hardware latching timecounters may not generate interrupts on + * PPS events, so instead we poll them. There is a finite risk that + * the hardware might capture a count which is later than the one we + * got above, and therefore possibly in the next NTP second which might + * have a different rate than the current NTP second. It doesn't + * matter in practice. + */ + if (tho->th_counter->tc_poll_pps) + tho->th_counter->tc_poll_pps(tho->th_counter); +#endif /* PPS_SYNC */ + +#ifdef NTP + /* + * Deal with NTP second processing. The for loop normally + * iterates at most once, but in extreme situations it might + * keep NTP sane if timeouts are not run for several seconds. + * At boot, the time step can be large when the TOD hardware + * has been read, so on really large steps, we call + * ntp_update_second only twice. We need to call it twice in + * case we missed a leap second. + */ + bt = th->th_offset; + bintime_add(&bt, &boottimebin); + i = bt.sec - tho->th_microtime.tv_sec; + if (i > LARGE_STEP) + i = 2; + for (; i > 0; i--) { + t = bt.sec; + ntp_update_second(&th->th_adjustment, &bt.sec); + if (bt.sec != t) + boottimebin.sec += bt.sec - t; + } +#endif /* NTP */ + + /* Update the UTC timestamps used by the get*() functions. */ + /* XXX shouldn't do this here. Should force non-`get' versions. */ + bintime2timeval(&bt, &th->th_microtime); + bintime2timespec(&bt, &th->th_nanotime); + + /* Now is a good time to change timecounters. */ + if (th->th_counter != timecounter) { + th->th_counter = timecounter; + th->th_offset_count = ncount; + } + + /*- + * Recalculate the scaling factor. We want the number of 1/2^64 + * fractions of a second per period of the hardware counter, taking + * into account the th_adjustment factor which the NTP PLL/adjtime(2) + * processing provides us with. + * + * The th_adjustment is nanoseconds per second with 32 bit binary + * fraction and we want 64 bit binary fraction of second: + * + * x = a * 2^32 / 10^9 = a * 4.294967296 + * + * The range of th_adjustment is +/- 5000PPM so inside a 64bit int + * we can only multiply by about 850 without overflowing, but that + * leaves suitably precise fractions for multiply before divide. + * + * Divide before multiply with a fraction of 2199/512 results in a + * systematic undercompensation of 10PPM of th_adjustment. On a + * 5000PPM adjustment this is a 0.05PPM error. This is acceptable. + * + * We happily sacrifice the lowest of the 64 bits of our result + * to the goddess of code clarity. + * + */ + scale = (u_int64_t)1 << 63; + scale += (th->th_adjustment / 1024) * 2199; + scale /= th->th_counter->tc_frequency; + th->th_scale = scale * 2; + + /* + * Now that the struct timehands is again consistent, set the new + * generation number, making sure to not make it zero. + */ + if (++ogen == 0) + ogen = 1; + th->th_generation = ogen; + + /* Go live with the new struct timehands. */ + time_second = th->th_microtime.tv_sec; + time_uptime = th->th_offset.sec; + timehands = th; +} + +#if 0 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX freebsd sysctl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +/* Report or change the active timecounter hardware. */ +static int +sysctl_kern_timecounter_hardware(SYSCTL_HANDLER_ARGS) +{ + char newname[32]; + struct timecounter *newtc, *tc; + int error; + + tc = timecounter; + strlcpy(newname, tc->tc_name, sizeof(newname)); + + error = sysctl_handle_string(oidp, &newname[0], sizeof(newname), req); + if (error != 0 || req->newptr == NULL || + strcmp(newname, tc->tc_name) == 0) + return (error); + for (newtc = timecounters; newtc != NULL; newtc = newtc->tc_next) { + if (strcmp(newname, newtc->tc_name) != 0) + continue; + + /* Warm up new timecounter. */ + (void)newtc->tc_get_timecount(newtc); + (void)newtc->tc_get_timecount(newtc); + + timecounter = newtc; + return (0); + } + return (EINVAL); +} + +SYSCTL_PROC(_kern_timecounter, OID_AUTO, hardware, CTLTYPE_STRING | CTLFLAG_RW, + 0, 0, sysctl_kern_timecounter_hardware, "A", ""); + + +/* Report or change the active timecounter hardware. */ +static int +sysctl_kern_timecounter_choice(SYSCTL_HANDLER_ARGS) +{ + char buf[32], *spc; + struct timecounter *tc; + int error; + + spc = ""; + error = 0; + for (tc = timecounters; error == 0 && tc != NULL; tc = tc->tc_next) { + sprintf(buf, "%s%s(%d)", + spc, tc->tc_name, tc->tc_quality); + error = SYSCTL_OUT(req, buf, strlen(buf)); + spc = " "; + } + return (error); +} + +SYSCTL_PROC(_kern_timecounter, OID_AUTO, choice, CTLTYPE_STRING | CTLFLAG_RD, + 0, 0, sysctl_kern_timecounter_choice, "A", ""); +#endif /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX freebsd sysctl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ + +/* + * RFC 2783 PPS-API implementation. + */ + +int +pps_ioctl(u_long cmd, caddr_t data, struct pps_state *pps) +{ + pps_params_t *app; + struct pps_fetch_args *fapi; +#ifdef PPS_SYNC + struct pps_kcbind_args *kapi; +#endif + + KASSERT(pps != NULL); /* XXX ("NULL pps pointer in pps_ioctl") */ + switch (cmd) { + case PPS_IOC_CREATE: + return (0); + case PPS_IOC_DESTROY: + return (0); + case PPS_IOC_SETPARAMS: + app = (pps_params_t *)data; + if (app->mode & ~pps->ppscap) + return (EINVAL); + pps->ppsparam = *app; + return (0); + case PPS_IOC_GETPARAMS: + app = (pps_params_t *)data; + *app = pps->ppsparam; + app->api_version = PPS_API_VERS_1; + return (0); + case PPS_IOC_GETCAP: + *(int*)data = pps->ppscap; + return (0); + case PPS_IOC_FETCH: + fapi = (struct pps_fetch_args *)data; + if (fapi->tsformat && fapi->tsformat != PPS_TSFMT_TSPEC) + return (EINVAL); + if (fapi->timeout.tv_sec || fapi->timeout.tv_nsec) + return (EOPNOTSUPP); + pps->ppsinfo.current_mode = pps->ppsparam.mode; + fapi->pps_info_buf = pps->ppsinfo; + return (0); + case PPS_IOC_KCBIND: +#ifdef PPS_SYNC + kapi = (struct pps_kcbind_args *)data; + /* XXX Only root should be able to do this */ + if (kapi->tsformat && kapi->tsformat != PPS_TSFMT_TSPEC) + return (EINVAL); + if (kapi->kernel_consumer != PPS_KC_HARDPPS) + return (EINVAL); + if (kapi->edge & ~pps->ppscap) + return (EINVAL); + pps->kcmode = kapi->edge; + return (0); +#else + return (EOPNOTSUPP); +#endif + default: + return (EPASSTHROUGH); + } +} + +void +pps_init(struct pps_state *pps) +{ + pps->ppscap |= PPS_TSFMT_TSPEC; + if (pps->ppscap & PPS_CAPTUREASSERT) + pps->ppscap |= PPS_OFFSETASSERT; + if (pps->ppscap & PPS_CAPTURECLEAR) + pps->ppscap |= PPS_OFFSETCLEAR; +} + +void +pps_capture(struct pps_state *pps) +{ + struct timehands *th; + + KASSERT(pps != NULL); /* XXX ("NULL pps pointer in pps_capture") */ + th = timehands; + pps->capgen = th->th_generation; + pps->capth = th; + pps->capcount = th->th_counter->tc_get_timecount(th->th_counter); + if (pps->capgen != th->th_generation) + pps->capgen = 0; +} + +void +pps_event(struct pps_state *pps, int event) +{ + struct bintime bt; + struct timespec ts, *tsp, *osp; + u_int tcount, *pcount; + int foff, fhard; + pps_seq_t *pseq; + + 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) + return; + + /* Things would be easier with arrays. */ + if (event == PPS_CAPTUREASSERT) { + tsp = &pps->ppsinfo.assert_timestamp; + osp = &pps->ppsparam.assert_offset; + foff = pps->ppsparam.mode & PPS_OFFSETASSERT; + fhard = pps->kcmode & PPS_CAPTUREASSERT; + pcount = &pps->ppscount[0]; + pseq = &pps->ppsinfo.assert_sequence; + } else { + tsp = &pps->ppsinfo.clear_timestamp; + osp = &pps->ppsparam.clear_offset; + foff = pps->ppsparam.mode & PPS_OFFSETCLEAR; + fhard = pps->kcmode & PPS_CAPTURECLEAR; + pcount = &pps->ppscount[1]; + pseq = &pps->ppsinfo.clear_sequence; + } + + /* + * If the timecounter changed, we cannot compare the count values, so + * we have to drop the rest of the PPS-stuff until the next event. + */ + if (pps->ppstc != pps->capth->th_counter) { + pps->ppstc = pps->capth->th_counter; + *pcount = pps->capcount; + pps->ppscount[2] = pps->capcount; + return; + } + + /* Convert the count to a timespec. */ + tcount = pps->capcount - pps->capth->th_offset_count; + 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); + bintime2timespec(&bt, &ts); + + /* If the timecounter was wound up underneath us, bail out. */ + if (pps->capgen != pps->capth->th_generation) + return; + + *pcount = pps->capcount; + (*pseq)++; + *tsp = ts; + + if (foff) { + timespecadd(tsp, osp, tsp); + if (tsp->tv_nsec < 0) { + tsp->tv_nsec += 1000000000; + tsp->tv_sec -= 1; + } + } +#ifdef PPS_SYNC + if (fhard) { + u_int64_t scale; + + /* + * Feed the NTP PLL/FLL. + * The FLL wants to know how many (hardware) nanoseconds + * elapsed since the previous event. + */ + tcount = pps->capcount - pps->ppscount[2]; + pps->ppscount[2] = pps->capcount; + tcount &= pps->capth->th_counter->tc_counter_mask; + scale = (u_int64_t)1 << 63; + scale /= pps->capth->th_counter->tc_frequency; + scale *= 2; + bt.sec = 0; + bt.frac = 0; + bintime_addx(&bt, scale * tcount); + bintime2timespec(&bt, &ts); + hardpps(tsp, ts.tv_nsec + 1000000000 * ts.tv_sec); + } +#endif +} + +/* + * Timecounters need to be updated every so often to prevent the hardware + * counter from overflowing. Updating also recalculates the cached values + * used by the get*() family of functions, so their precision depends on + * the update frequency. + */ + +static int tc_tick; +#if 0 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX freebsd sysctl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +SYSCTL_INT(_kern_timecounter, OID_AUTO, tick, CTLFLAG_RD, &tc_tick, 0, ""); +#endif /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX freebsd sysctl XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ + +void +tc_ticktock(void) +{ + static int count; + + if (++count < tc_tick) + return; + count = 0; + tc_windup(); +} + +void +inittimecounter(void) +{ + u_int p; + + /* + * Set the initial timeout to + * max(1, ). + * People should probably not use the sysctl to set the timeout + * to smaller than its inital value, since that value is the + * smallest reasonable one. If they want better timestamps they + * should use the non-"get"* functions. + */ + if (hz > 1000) + tc_tick = (hz + 500) / 1000; + else + tc_tick = 1; + p = (tc_tick * 1000000) / hz; + printf("Timecounters tick every %d.%03u msec\n", p / 1000, p % 1000); + + /* warm up new timecounter (again) and get rolling. */ + (void)timecounter->tc_get_timecount(timecounter); + (void)timecounter->tc_get_timecount(timecounter); +} +#endif /* __HAVE_TIMECOUNTER */ Index: sys/kern/kern_time.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_time.c,v retrieving revision 1.96 diff -d -p -u -r1.96 kern_time.c --- sys/kern/kern_time.c 11 Nov 2005 07:07:42 -0000 1.96 +++ sys/kern/kern_time.c 22 Nov 2005 13:41:44 -0000 @@ -85,7 +85,11 @@ __KERNEL_RCSID(0, "$NetBSD: kern_time.c, #include #include #include +#ifdef __HAVE_TIMECOUNTER +#include +#else /* !__HAVE_TIMECOUNTER */ #include +#endif /* !__HAVE_TIMECOUNTER */ #include #include @@ -102,6 +106,9 @@ __KERNEL_RCSID(0, "$NetBSD: kern_time.c, #include static void timerupcall(struct lwp *, void *); +#ifdef __HAVE_TIMECOUNTER +static int itimespecfix(struct timespec *); /* XXX move itimerfix to timespecs */ +#endif /* __HAVE_TIMECOUNTER */ /* Time of day and interval timer support. * @@ -116,13 +123,23 @@ static void timerupcall(struct lwp *, vo int settime(struct timeval *tv) { +#ifdef __HAVE_TIMECOUNTER + struct timeval delta, tv1; + struct timespec ts; +#else /* !__HAVE_TIMECOUNTER */ struct timeval delta; +#endif /* !__HAVE_TIMECOUNTER */ struct cpu_info *ci; int s; /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ s = splclock(); +#ifdef __HAVE_TIMECOUNTER + microtime(&tv1); + timersub(tv, &tv1, &delta); +#else /* !__HAVE_TIMECOUNTER */ timersub(tv, &time, &delta); +#endif /* !__HAVE_TIMECOUNTER */ if ((delta.tv_sec < 0 || delta.tv_usec < 0) && securelevel > 1) { splx(s); return (EPERM); @@ -133,7 +150,13 @@ settime(struct timeval *tv) return (EPERM); } #endif +#ifdef __HAVE_TIMECOUNTER + ts.tv_sec = tv->tv_sec; + ts.tv_nsec = tv->tv_usec * 1000; + tc_setclock(&ts); +#else /* !__HAVE_TIMECOUNTER */ time = *tv; +#endif /* !__HAVE_TIMECOUNTER */ (void) spllowersoftclock(); timeradd(&boottime, &delta, &boottime); /* @@ -145,9 +168,9 @@ settime(struct timeval *tv) ci = curcpu(); timeradd(&ci->ci_schedstate.spc_runtime, &delta, &ci->ci_schedstate.spc_runtime); -# if (defined(NFS) && !defined (NFS_V2_ONLY)) || defined(NFSSERVER) - nqnfs_lease_updatetime(delta.tv_sec); -# endif +#if (defined(NFS) && !defined (NFS_V2_ONLY)) || defined(NFSSERVER) + nqnfs_lease_updatetime(delta.tv_sec); +#endif splx(s); resettodr(); return (0); @@ -162,9 +185,7 @@ sys_clock_gettime(struct lwp *l, void *v syscallarg(struct timespec *) tp; } */ *uap = v; clockid_t clock_id; - struct timeval atv; struct timespec ats; - int s; clock_id = SCARG(uap, clock_id); switch (clock_id) { @@ -172,11 +193,18 @@ sys_clock_gettime(struct lwp *l, void *v nanotime(&ats); break; case CLOCK_MONOTONIC: +#ifdef __HAVE_TIMECOUNTER + nanouptime(&ats); +#else /* !__HAVE_TIMECOUNTER */ + { + int s; + /* XXX "hz" granularity */ s = splclock(); - atv = mono_time; + TIMEVAL_TO_TIMESPEC(&mono_time,&ats); splx(s); - TIMEVAL_TO_TIMESPEC(&atv,&ats); + } +#endif /* !__HAVE_TIMECOUNTER */ break; default: return (EINVAL); @@ -260,6 +288,52 @@ sys_clock_getres(struct lwp *l, void *v, int sys_nanosleep(struct lwp *l, void *v, register_t *retval) { +#ifdef __HAVE_TIMECOUNTER + static int nanowait; + struct sys_nanosleep_args/* { + syscallarg(struct timespec *) rqtp; + syscallarg(struct timespec *) rmtp; + } */ *uap = v; + struct timespec rmt, rqt; + int error, timo; + + error = copyin(SCARG(uap, rqtp), &rqt, sizeof(struct timespec)); + if (error) + return (error); + + if (itimespecfix(&rqt)) + return (EINVAL); + + timo = tstohz(&rqt); + /* + * Avoid inadvertantly sleeping forever + */ + if (timo == 0) + timo = 1; + + error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo); + if (error == ERESTART) + error = EINTR; + if (error == EWOULDBLOCK) + error = 0; + + if (SCARG(uap, rmtp)) { + int error1; + + getnanotime(&rmt); + + timespecsub(&rqt, &rmt, &rmt); + if (rmt.tv_sec < 0) + timespecclear(&rmt); + + error1 = copyout((caddr_t)&rmt, (caddr_t)SCARG(uap,rmtp), + sizeof(rmt)); + if (error1) + return (error1); + } + + return error; +#else /* !__HAVE_TIMECOUNTER */ static int nanowait; struct sys_nanosleep_args/* { syscallarg(struct timespec *) rqtp; @@ -313,6 +387,7 @@ sys_nanosleep(struct lwp *l, void *v, re } return error; +#endif /* !__HAVE_TIMECOUNTER */ } /* ARGSUSED */ @@ -679,6 +754,9 @@ timer_settime(struct ptimer *pt) void timer_gettime(struct ptimer *pt, struct itimerval *aitv) { +#ifdef __HAVE_TIMECOUNTER + struct timeval now; +#endif struct ptimer *ptn; *aitv = pt->pt_time; @@ -691,11 +769,20 @@ timer_gettime(struct ptimer *pt, struct * off. */ if (timerisset(&aitv->it_value)) { +#ifdef __HAVE_TIMECOUNTER + getmicrotime(&now); + if (timercmp(&aitv->it_value, &now, <)) + timerclear(&aitv->it_value); + else + timersub(&aitv->it_value, &now, + &aitv->it_value); +#else /* !__HAVE_TIMECOUNTER */ if (timercmp(&aitv->it_value, &time, <)) timerclear(&aitv->it_value); else timersub(&aitv->it_value, &time, &aitv->it_value); +#endif /* !__HAVE_TIMECOUNTER */ } } else if (pt->pt_active) { if (pt->pt_type == CLOCK_VIRTUAL) @@ -746,9 +833,12 @@ int dotimer_settime(int timerid, struct itimerspec *value, struct itimerspec *ovalue, int flags, struct proc *p) { - int s; +#ifdef __HAVE_TIMECOUNTER + struct timeval now; +#endif struct itimerval val, oval; struct ptimer *pt; + int s; if ((p->p_timers == NULL) || (timerid < 2) || (timerid >= TIMER_MAX) || @@ -773,13 +863,27 @@ dotimer_settime(int timerid, struct itim */ if (timerisset(&pt->pt_time.it_value)) { if (pt->pt_type == CLOCK_REALTIME) { +#ifdef __HAVE_TIMECOUNTER + if ((flags & TIMER_ABSTIME) == 0) { + getmicrotime(&now); + timeradd(&pt->pt_time.it_value, &now, + &pt->pt_time.it_value); + } +#else /* !__HAVE_TIMECOUNTER */ if ((flags & TIMER_ABSTIME) == 0) timeradd(&pt->pt_time.it_value, &time, &pt->pt_time.it_value); +#endif /* !__HAVE_TIMECOUNTER */ } else { if ((flags & TIMER_ABSTIME) != 0) { +#ifdef __HAVE_TIMECOUNTER + getmicrotime(&now); + timersub(&pt->pt_time.it_value, &now, + &pt->pt_time.it_value); +#else /* !__HAVE_TIMECOUNTER */ timersub(&pt->pt_time.it_value, &time, &pt->pt_time.it_value); +#endif /* !__HAVE_TIMECOUNTER */ if (!timerisset(&pt->pt_time.it_value) || pt->pt_time.it_value.tv_sec < 0) { pt->pt_time.it_value.tv_sec = 0; @@ -908,7 +1012,6 @@ timerupcall(struct lwp *l, void *arg) KERNEL_PROC_UNLOCK(l); } - /* * Real interval timer expired: * send process whose timer expired an alarm signal. @@ -920,6 +1023,9 @@ timerupcall(struct lwp *l, void *arg) void realtimerexpire(void *arg) { +#ifdef __HAVE_TIMECOUNTER + struct timeval now; +#endif struct ptimer *pt; int s; @@ -931,6 +1037,26 @@ realtimerexpire(void *arg) timerclear(&pt->pt_time.it_value); return; } +#ifdef __HAVE_TIMECOUNTER + for (;;) { + s = splclock(); /* XXX need spl now? */ + timeradd(&pt->pt_time.it_value, + &pt->pt_time.it_interval, &pt->pt_time.it_value); + getmicrotime(&now); + if (timercmp(&pt->pt_time.it_value, &now, >)) { + /* + * Don't need to check hzto() return value, here. + * callout_reset() does it for us. + */ + callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value), + realtimerexpire, pt); + splx(s); + return; + } + splx(s); + pt->pt_overruns++; + } +#else /* !__HAVE_TIMECOUNTER */ for (;;) { s = splclock(); timeradd(&pt->pt_time.it_value, @@ -948,6 +1074,7 @@ realtimerexpire(void *arg) splx(s); pt->pt_overruns++; } +#endif /* !__HAVE_TIMECOUNTER */ } /* BSD routine to get the value of an interval timer. */ @@ -1027,6 +1154,9 @@ sys_setitimer(struct lwp *l, void *v, re int dosetitimer(struct proc *p, int which, struct itimerval *itvp) { +#ifdef __HAVE_TIMECOUNTER + struct timeval now; +#endif struct ptimer *pt; int s; @@ -1074,7 +1204,13 @@ dosetitimer(struct proc *p, int which, s s = splclock(); if ((which == ITIMER_REAL) && timerisset(&pt->pt_time.it_value)) { /* Convert to absolute time */ +#ifdef __HAVE_TIMECOUNTER + /* XXX need to wrap in splclock for timecounters case? */ + getmicrotime(&now); + timeradd(&pt->pt_time.it_value, &now, &pt->pt_time.it_value); +#else /* !__HAVE_TIMECOUNTER */ timeradd(&pt->pt_time.it_value, &time, &pt->pt_time.it_value); +#endif /* !__HAVE_TIMECOUNTER */ } timer_settime(pt); splx(s); @@ -1180,6 +1316,19 @@ itimerfix(struct timeval *tv) return (0); } +#ifdef __HAVE_TIMECOUNTER +int +itimespecfix(struct timespec *ts) +{ + + if (ts->tv_sec < 0 || ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000) + return (EINVAL); + if (ts->tv_sec == 0 && ts->tv_nsec != 0 && ts->tv_nsec < tick * 1000) + ts->tv_nsec = tick * 1000; + return (0); +} +#endif /* __HAVE_TIMECOUNTER */ + /* * Decrement an interval timer by a specified number * of microseconds, which must be less than a second, @@ -1304,12 +1453,18 @@ int ratecheck(struct timeval *lasttime, const struct timeval *mininterval) { struct timeval tv, delta; - int s, rv = 0; + int rv = 0; +#ifndef __HAVE_TIMECOUNTER + int s; +#endif +#ifdef __HAVE_TIMECOUNTER + getmicrouptime(&tv); +#else /* !__HAVE_TIMECOUNTER */ s = splclock(); tv = mono_time; splx(s); - +#endif /* !__HAVE_TIMECOUNTER */ timersub(&tv, lasttime, &delta); /* @@ -1332,12 +1487,18 @@ int ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps) { struct timeval tv, delta; - int s, rv; + int rv; +#ifndef __HAVE_TIMECOUNTER + int s; +#endif +#ifdef __HAVE_TIMECOUNTER + getmicrouptime(&tv); +#else /* !__HAVE_TIMECOUNTER */ s = splclock(); tv = mono_time; splx(s); - +#endif /* !__HAVE_TIMECOUNTER */ timersub(&tv, lasttime, &delta); /* Index: sys/kern/subr_disk.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_disk.c,v retrieving revision 1.71 diff -d -p -u -r1.71 subr_disk.c --- sys/kern/subr_disk.c 15 Oct 2005 17:29:26 -0000 1.71 +++ sys/kern/subr_disk.c 22 Nov 2005 13:41:45 -0000 @@ -211,7 +211,6 @@ disk_init0(struct disk *diskp) static void disk_attach0(struct disk *diskp) { - int s; /* * Allocate and initialize the disklabel structures. Note that @@ -230,9 +229,7 @@ disk_attach0(struct disk *diskp) /* * Set the attached timestamp. */ - s = splclock(); - diskp->dk_attachtime = mono_time; - splx(s); + getmicrouptime(&diskp->dk_attachtime); /* * Link into the disklist. @@ -324,17 +321,9 @@ pseudo_disk_detach(struct disk *diskp) void disk_busy(struct disk *diskp) { - int s; - /* - * XXX We'd like to use something as accurate as microtime(), - * but that doesn't depend on the system TOD clock. - */ - if (diskp->dk_busy++ == 0) { - s = splclock(); - diskp->dk_timestamp = mono_time; - splx(s); - } + if (diskp->dk_busy++ == 0) + getmicrouptime(&diskp->dk_timestamp); } /* @@ -344,7 +333,6 @@ disk_busy(struct disk *diskp) void disk_unbusy(struct disk *diskp, long bcount, int read) { - int s; struct timeval dv_time, diff_time; if (diskp->dk_busy-- == 0) { @@ -352,10 +340,7 @@ disk_unbusy(struct disk *diskp, long bco panic("disk_unbusy"); } - s = splclock(); - dv_time = mono_time; - splx(s); - + getmicrouptime(&dv_time); timersub(&dv_time, &diskp->dk_timestamp, &diff_time); timeradd(&diskp->dk_time, &diff_time, &diskp->dk_time); @@ -380,17 +365,14 @@ disk_unbusy(struct disk *diskp, long bco void disk_resetstat(struct disk *diskp) { - int s = splbio(), t; + int s = splbio(); diskp->dk_rxfer = 0; diskp->dk_rbytes = 0; diskp->dk_wxfer = 0; diskp->dk_wbytes = 0; - t = splclock(); - diskp->dk_attachtime = mono_time; - splx(t); - + getmicrouptime(&diskp->dk_attachtime); timerclear(&diskp->dk_time); splx(s); Index: sys/kern/subr_pool.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_pool.c,v retrieving revision 1.107 diff -d -p -u -r1.107 subr_pool.c --- sys/kern/subr_pool.c 2 Nov 2005 14:32:54 -0000 1.107 +++ sys/kern/subr_pool.c 22 Nov 2005 13:41:49 -0000 @@ -1060,7 +1060,6 @@ pool_do_put(struct pool *pp, void *v, st struct pool_item *pi = v; struct pool_item_header *ph; caddr_t page; - int s; LOCK_ASSERT(simple_lock_held(&pp->pr_slock)); SCHED_ASSERT_UNLOCKED(); @@ -1155,9 +1154,7 @@ pool_do_put(struct pool *pp, void *v, st * be reclaimed by the pagedaemon. This minimizes * ping-pong'ing for memory. */ - s = splclock(); - ph->ph_time = mono_time; - splx(s); + getmicrotime(&ph->ph_time); } pool_update_curpage(pp); } @@ -1272,7 +1269,6 @@ pool_prime_page(struct pool *pp, caddr_t unsigned int align = pp->pr_align; unsigned int ioff = pp->pr_itemoffset; int n; - int s; LOCK_ASSERT(simple_lock_held(&pp->pr_slock)); @@ -1288,9 +1284,7 @@ pool_prime_page(struct pool *pp, caddr_t LIST_INIT(&ph->ph_itemlist); ph->ph_page = storage; ph->ph_nmissing = 0; - s = splclock(); - ph->ph_time = mono_time; - splx(s); + getmicrotime(&ph->ph_time); if ((pp->pr_roflags & PR_PHINPAGE) == 0) SPLAY_INSERT(phtree, &pp->pr_phtree, ph); @@ -1475,7 +1469,6 @@ pool_reclaim(struct pool *pp) struct pool_pagelist pq; struct pool_cache_grouplist pcgl; struct timeval curtime, diff; - int s; if (pp->pr_drain_hook != NULL) { /* @@ -1497,9 +1490,7 @@ pool_reclaim(struct pool *pp) LIST_FOREACH(pc, &pp->pr_cachelist, pc_poollist) pool_cache_reclaim(pc, &pq, &pcgl); - s = splclock(); - curtime = mono_time; - splx(s); + getmicrotime(&curtime); for (ph = LIST_FIRST(&pp->pr_emptypages); ph != NULL; ph = phnext) { phnext = LIST_NEXT(ph, ph_pagelist); Index: sys/kern/sys_generic.c =================================================================== RCS file: /cvsroot/src/sys/kern/sys_generic.c,v retrieving revision 1.83 diff -d -p -u -r1.83 sys_generic.c --- sys/kern/sys_generic.c 29 May 2005 22:24:15 -0000 1.83 +++ sys/kern/sys_generic.c 22 Nov 2005 13:41:50 -0000 @@ -718,10 +718,10 @@ int selcommon(struct lwp *l, register_t *retval, int nd, fd_set *u_in, fd_set *u_ou, fd_set *u_ex, struct timeval *tv, sigset_t *mask) { - struct proc * const p = l->l_proc; - caddr_t bits; char smallbits[howmany(FD_SETSIZE, NFDBITS) * sizeof(fd_mask) * 6]; + struct proc * const p = l->l_proc; + caddr_t bits; int s, ncoll, error, timo; size_t ni; sigset_t oldmask; @@ -752,14 +752,9 @@ selcommon(struct lwp *l, register_t *ret #undef getbits timo = 0; - if (tv) { - if (itimerfix(tv)) { - error = EINVAL; - goto done; - } - s = splclock(); - timeradd(tv, &time, tv); - splx(s); + if (tv && itimerfix(tv)) { + error = EINVAL; + goto done; } if (mask) (void)sigprocmask1(p, SIG_SETMASK, mask, &oldmask); @@ -775,7 +770,7 @@ selcommon(struct lwp *l, register_t *ret /* * We have to recalculate the timeout on every retry. */ - timo = hzto(tv); + timo = tvtohz(tv); if (timo <= 0) goto done; } @@ -917,9 +912,9 @@ pollcommon(struct lwp *l, register_t *re struct pollfd *u_fds, u_int nfds, struct timeval *tv, sigset_t *mask) { + char smallbits[32 * sizeof(struct pollfd)]; struct proc * const p = l->l_proc; caddr_t bits; - char smallbits[32 * sizeof(struct pollfd)]; sigset_t oldmask; int s, ncoll, error, timo; size_t ni; @@ -939,14 +934,9 @@ pollcommon(struct lwp *l, register_t *re goto done; timo = 0; - if (tv) { - if (itimerfix(tv)) { - error = EINVAL; - goto done; - } - s = splclock(); - timeradd(tv, &time, tv); - splx(s); + if (tv && itimerfix(tv)) { + error = EINVAL; + goto done; } if (mask != NULL) (void)sigprocmask1(p, SIG_SETMASK, mask, &oldmask); @@ -961,7 +951,7 @@ pollcommon(struct lwp *l, register_t *re /* * We have to recalculate the timeout on every retry. */ - timo = hzto(tv); + timo = tvtohz(tv); if (timo <= 0) goto done; } Index: sys/kern/sys_pipe.c =================================================================== RCS file: /cvsroot/src/sys/kern/sys_pipe.c,v retrieving revision 1.67 diff -d -p -u -r1.67 sys_pipe.c --- sys/kern/sys_pipe.c 29 Oct 2005 12:31:07 -0000 1.67 +++ sys/kern/sys_pipe.c 22 Nov 2005 13:41:52 -0000 @@ -113,14 +113,6 @@ __KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v #include /* - * Avoid microtime(9), it's slow. We don't guard the read from time(9) - * with splclock(9) since we don't actually need to be THAT sure the access - * is atomic. - */ -#define PIPE_TIMESTAMP(tvp) (*(tvp) = time) - - -/* * Use this define if you want to disable *fancy* VM things. Expect an * approx 30% decrease in transfer rate. */ @@ -320,7 +312,7 @@ pipe_create(pipep, allockva) memset(pipe, 0, sizeof(struct pipe)); pipe->pipe_state = PIPE_SIGNALR; - PIPE_TIMESTAMP(&pipe->pipe_ctime); + getmicrotime(&pipe->pipe_ctime); pipe->pipe_atime = pipe->pipe_ctime; pipe->pipe_mtime = pipe->pipe_ctime; simple_lock_init(&pipe->pipe_slock); @@ -571,7 +563,7 @@ again: } if (error == 0) - PIPE_TIMESTAMP(&rpipe->pipe_atime); + getmicrotime(&rpipe->pipe_atime); PIPE_LOCK(rpipe); pipeunlock(rpipe); @@ -1068,7 +1060,7 @@ retry: error = 0; if (error == 0) - PIPE_TIMESTAMP(&wpipe->pipe_mtime); + getmicrotime(&wpipe->pipe_mtime); /* * We have something to offer, wake up select/poll. Index: sys/kern/sysv_msg.c =================================================================== RCS file: /cvsroot/src/sys/kern/sysv_msg.c,v retrieving revision 1.39 diff -d -p -u -r1.39 sysv_msg.c --- sys/kern/sysv_msg.c 1 Apr 2005 11:59:37 -0000 1.39 +++ sys/kern/sysv_msg.c 22 Nov 2005 13:41:53 -0000 @@ -294,7 +294,7 @@ msgctl1(p, msqid, cmd, msqbuf) msqptr->msg_perm.mode = (msqptr->msg_perm.mode & ~0777) | (msqbuf->msg_perm.mode & 0777); msqptr->msg_qbytes = msqbuf->msg_qbytes; - msqptr->msg_ctime = time.tv_sec; + msqptr->msg_ctime = time_second; break; case IPC_STAT: @@ -391,7 +391,7 @@ sys_msgget(l, v, retval) msqptr->msg_lrpid = 0; msqptr->msg_stime = 0; msqptr->msg_rtime = 0; - msqptr->msg_ctime = time.tv_sec; + msqptr->msg_ctime = time_second; } else { MSG_PRINTF(("didn't find it and wasn't asked to create it\n")); return (ENOENT); @@ -673,7 +673,7 @@ sys_msgsnd(l, v, retval) msqptr->_msg_cbytes += msghdr->msg_ts; msqptr->msg_qnum++; msqptr->msg_lspid = p->p_pid; - msqptr->msg_stime = time.tv_sec; + msqptr->msg_stime = time_second; wakeup(msqptr); return (0); @@ -874,7 +874,7 @@ sys_msgrcv(l, v, retval) msqptr->_msg_cbytes -= msghdr->msg_ts; msqptr->msg_qnum--; msqptr->msg_lrpid = p->p_pid; - msqptr->msg_rtime = time.tv_sec; + msqptr->msg_rtime = time_second; /* * Make msgsz the actual amount that we'll be returning. Index: sys/kern/sysv_sem.c =================================================================== RCS file: /cvsroot/src/sys/kern/sysv_sem.c,v retrieving revision 1.58 diff -d -p -u -r1.58 sysv_sem.c --- sys/kern/sysv_sem.c 10 Nov 2005 18:45:36 -0000 1.58 +++ sys/kern/sysv_sem.c 22 Nov 2005 13:41:54 -0000 @@ -392,7 +392,7 @@ semctl1(p, semid, semnum, cmd, v, retval semaptr->sem_perm.gid = sembuf->sem_perm.gid; semaptr->sem_perm.mode = (semaptr->sem_perm.mode & ~0777) | (sembuf->sem_perm.mode & 0777); - semaptr->sem_ctime = time.tv_sec; + semaptr->sem_ctime = time_second; break; case IPC_STAT: @@ -549,7 +549,7 @@ sys_semget(l, v, retval) (sema[semid].sem_perm._seq + 1) & 0x7fff; sema[semid].sem_nsems = nsems; sema[semid].sem_otime = 0; - sema[semid].sem_ctime = time.tv_sec; + sema[semid].sem_ctime = time_second; sema[semid]._sem_base = &sem[semtot]; semtot += nsems; memset(sema[semid]._sem_base, 0, @@ -807,7 +807,7 @@ done: } /* Update sem_otime */ - semaptr->sem_otime = time.tv_sec; + semaptr->sem_otime = time_second; /* Do a wakeup if any semaphore was up'd. */ if (do_wakeup) { Index: sys/kern/sysv_shm.c =================================================================== RCS file: /cvsroot/src/sys/kern/sysv_shm.c,v retrieving revision 1.85 diff -d -p -u -r1.85 sysv_shm.c --- sys/kern/sysv_shm.c 10 Nov 2005 18:45:20 -0000 1.85 +++ sys/kern/sysv_shm.c 22 Nov 2005 13:41:57 -0000 @@ -210,7 +210,7 @@ shm_delete_mapping(vm, shmmap_s, shmmap_ SLIST_REMOVE(&shmmap_s->entries, shmmap_se, shmmap_entry, next); shmmap_s->nitems--; pool_put(&shmmap_entry_pool, shmmap_se); - shmseg->shm_dtime = time.tv_sec; + shmseg->shm_dtime = time_second; if ((--shmseg->shm_nattch <= 0) && (shmseg->shm_perm.mode & SHMSEG_REMOVED)) { shm_deallocate_segment(shmseg); @@ -381,7 +381,7 @@ sys_shmat(l, v, retval) SLIST_INSERT_HEAD(&shmmap_s->entries, shmmap_se, next); shmmap_s->nitems++; shmseg->shm_lpid = p->p_pid; - shmseg->shm_atime = time.tv_sec; + shmseg->shm_atime = time_second; shmseg->shm_nattch++; retval[0] = attach_va; @@ -448,7 +448,7 @@ shmctl1(p, shmid, cmd, shmbuf) shmseg->shm_perm.mode = (shmseg->shm_perm.mode & ~ACCESSPERMS) | (shmbuf->shm_perm.mode & ACCESSPERMS); - shmseg->shm_ctime = time.tv_sec; + shmseg->shm_ctime = time_second; break; case IPC_RMID: if ((error = ipcperm(cred, &shmseg->shm_perm, IPC_M)) != 0) @@ -563,7 +563,7 @@ shmget_allocate_segment(p, uap, mode, re shmseg->shm_cpid = p->p_pid; shmseg->shm_lpid = shmseg->shm_nattch = 0; shmseg->shm_atime = shmseg->shm_dtime = 0; - shmseg->shm_ctime = time.tv_sec; + shmseg->shm_ctime = time_second; shm_committed += btoc(size); shm_nused++; Index: sys/kern/tty.c =================================================================== RCS file: /cvsroot/src/sys/kern/tty.c,v retrieving revision 1.176 diff -d -p -u -r1.176 tty.c --- sys/kern/tty.c 13 Oct 2005 16:18:43 -0000 1.176 +++ sys/kern/tty.c 22 Nov 2005 13:41:59 -0000 @@ -1654,7 +1654,7 @@ ttread(struct tty *tp, struct uio *uio, struct proc *p; int c, s, first, error, has_stime, last_cc; long lflag, slp; - struct timeval stime; + struct timeval now, stime; cc = tp->t_cc; p = curproc; @@ -1725,25 +1725,28 @@ ttread(struct tty *tp, struct uio *uio, if (!has_stime) { /* first character, start timer */ has_stime = 1; - stime = time; + getmicrotime(&stime); slp = t; } else if (qp->c_cc > last_cc) { /* got a character, restart timer */ - stime = time; + getmicrotime(&stime); slp = t; } else { /* nothing, check expiration */ - slp = t - diff(time, stime); + getmicrotime(&now); + slp = t - diff(now, stime); } } else { /* m == 0 */ if (qp->c_cc > 0) goto read; if (!has_stime) { has_stime = 1; - stime = time; + getmicrotime(&stime); slp = t; - } else - slp = t - diff(time, stime); + } else { + getmicrotime(&now); + slp = t - diff(now, stime); + } } last_cc = qp->c_cc; #undef diff Index: sys/lib/libkern/arc4random.c =================================================================== RCS file: /cvsroot/src/sys/lib/libkern/arc4random.c,v retrieving revision 1.14 diff -d -p -u -r1.14 arc4random.c --- sys/lib/libkern/arc4random.c 26 Feb 2005 22:58:56 -0000 1.14 +++ sys/lib/libkern/arc4random.c 22 Nov 2005 13:42:01 -0000 @@ -72,14 +72,15 @@ #define ARC4_RESEED_SECONDS 300 #define ARC4_KEYBYTES 32 /* 256 bit key */ +#ifdef _STANDALONE +#define time_uptime 1 /* XXX ugly! */ +#endif /* _STANDALONE */ + static u_int8_t arc4_i, arc4_j; static int arc4_initialized = 0; static int arc4_numruns = 0; static u_int8_t arc4_sbox[256]; -static struct timeval arc4_tv_nextreseed; -#ifndef _KERNEL -extern struct timeval mono_time; -#endif +static time_t arc4_nextreseed; static inline u_int8_t arc4_randbyte(void); @@ -123,8 +124,7 @@ arc4_randrekey(void) RND_EXTRACT_ANY); } else { /* don't replace a good key with a bad one! */ - arc4_tv_nextreseed = mono_time; - arc4_tv_nextreseed.tv_sec += ARC4_RESEED_SECONDS; + arc4_nextreseed = time_uptime + ARC4_RESEED_SECONDS; arc4_numruns = 0; /* we should just ask rnd(4) to rekey us when it can, but for now, we'll just try later. */ @@ -143,8 +143,7 @@ arc4_randrekey(void) } /* Reset for next reseed cycle. */ - arc4_tv_nextreseed = mono_time; - arc4_tv_nextreseed.tv_sec += ARC4_RESEED_SECONDS; + arc4_nextreseed = time_uptime + ARC4_RESEED_SECONDS; arc4_numruns = 0; /* @@ -200,7 +199,7 @@ arc4random(void) arc4_init(); if ((++arc4_numruns > ARC4_MAXRUNS) || - (mono_time.tv_sec > arc4_tv_nextreseed.tv_sec)) { + (time_uptime > arc4_nextreseed)) { arc4_randrekey(); } @@ -221,7 +220,7 @@ arc4randbytes(void *p, size_t len) ; arc4_numruns += len / sizeof(u_int32_t); if ((arc4_numruns > ARC4_MAXRUNS) || - (mono_time.tv_sec > arc4_tv_nextreseed.tv_sec)) { + (time_uptime > arc4_nextreseed)) { arc4_randrekey(); } } Index: sys/miscfs/kernfs/kernfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/kernfs/kernfs_vnops.c,v retrieving revision 1.113 diff -d -p -u -r1.113 kernfs_vnops.c --- sys/miscfs/kernfs/kernfs_vnops.c 2 Nov 2005 12:38:59 -0000 1.113 +++ sys/miscfs/kernfs/kernfs_vnops.c 22 Nov 2005 13:42:04 -0000 @@ -819,17 +819,12 @@ kernfs_getattr(v) vap->va_flags = 0; vap->va_size = 0; vap->va_blocksize = DEV_BSIZE; - /* - * Make all times be current TOD, except for the "boottime" node. - * Avoid microtime(9), it's slow. - * We don't guard the read from time(9) with splclock(9) since we - * don't actually need to be THAT sure the access is atomic. - */ + /* Make all times be current TOD, except for the "boottime" node. */ if (kfs->kfs_kt && kfs->kfs_kt->kt_namlen == 8 && !memcmp(kfs->kfs_kt->kt_name, "boottime", 8)) { TIMEVAL_TO_TIMESPEC(&boottime, &vap->va_ctime); } else { - TIMEVAL_TO_TIMESPEC(&time, &vap->va_ctime); + getnanotime(&vap->va_ctime); } vap->va_atime = vap->va_mtime = vap->va_ctime; vap->va_gen = 0; Index: sys/miscfs/portal/portal_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/portal/portal_vnops.c,v retrieving revision 1.61 diff -d -p -u -r1.61 portal_vnops.c --- sys/miscfs/portal/portal_vnops.c 2 Nov 2005 12:38:59 -0000 1.61 +++ sys/miscfs/portal/portal_vnops.c 22 Nov 2005 13:42:05 -0000 @@ -541,12 +541,8 @@ portal_getattr(v) vap->va_fsid = vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0]; vap->va_size = DEV_BSIZE; vap->va_blocksize = DEV_BSIZE; - /* - * Make all times be current TOD. Avoid microtime(9), it's slow. - * We don't guard the read from time(9) with splclock(9) since we - * don't actually need to be THAT sure the access is atomic. - */ - TIMEVAL_TO_TIMESPEC(&time, &vap->va_ctime); + /* Make all times be current TOD. */ + getnanotime(&vap->va_ctime); vap->va_atime = vap->va_mtime = vap->va_ctime; vap->va_atime = vap->va_mtime = vap->va_ctime; vap->va_gen = 0; Index: sys/miscfs/procfs/procfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_vnops.c,v retrieving revision 1.127 diff -d -p -u -r1.127 procfs_vnops.c --- sys/miscfs/procfs/procfs_vnops.c 2 Nov 2005 12:38:59 -0000 1.127 +++ sys/miscfs/procfs/procfs_vnops.c 22 Nov 2005 13:42:09 -0000 @@ -583,9 +583,7 @@ procfs_getattr(v) vap->va_blocksize = PAGE_SIZE; /* - * Make all times be current TOD. Avoid microtime(9), it's slow. - * We don't guard the read from time(9) with splclock(9) since we - * don't actually need to be THAT sure the access is atomic. + * Make all times be current TOD. * * It would be possible to get the process start * time from the p_stats structure, but there's @@ -593,13 +591,13 @@ procfs_getattr(v) * p_stats structure is not addressable if u. gets * swapped out for that process. */ - TIMEVAL_TO_TIMESPEC(&time, &vap->va_ctime); + getnanotime(&vap->va_ctime); vap->va_atime = vap->va_mtime = vap->va_ctime; if (procp) TIMEVAL_TO_TIMESPEC(&procp->p_stats->p_start, &vap->va_birthtime); else - TIMEVAL_TO_TIMESPEC(&boottime, &vap->va_birthtime); + getnanotime(&vap->va_birthtime); switch (pfs->pfs_type) { case PFSmem: Index: sys/miscfs/syncfs/sync_subr.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/syncfs/sync_subr.c,v retrieving revision 1.19 diff -d -p -u -r1.19 sync_subr.c --- sys/miscfs/syncfs/sync_subr.c 11 Sep 2005 17:55:56 -0000 1.19 +++ sys/miscfs/syncfs/sync_subr.c 22 Nov 2005 13:42:09 -0000 @@ -170,7 +170,7 @@ sched_sync(v) updateproc = curlwp; for (;;) { - starttime = time.tv_sec; + starttime = time_second; /* * Push files whose dirty time has expired. Be careful @@ -241,7 +241,7 @@ sched_sync(v) * matter as we are just trying to generally pace the * filesystem activity. */ - if (time.tv_sec == starttime) + if (time_second == starttime) tsleep(&rushjob, PPAUSE, "syncer", hz); } } Index: sys/net/if_arcsubr.c =================================================================== RCS file: /cvsroot/src/sys/net/if_arcsubr.c,v retrieving revision 1.49 diff -d -p -u -r1.49 if_arcsubr.c --- sys/net/if_arcsubr.c 5 Jun 2005 22:31:40 -0000 1.49 +++ sys/net/if_arcsubr.c 22 Nov 2005 13:42:09 -0000 @@ -159,7 +159,7 @@ arc_output(ifp, m0, dst, rt0) } if (rt->rt_flags & RTF_REJECT) if (rt->rt_rmx.rmx_expire == 0 || - time.tv_sec < rt->rt_rmx.rmx_expire) + time_second < rt->rt_rmx.rmx_expire) senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } @@ -662,7 +662,7 @@ arc_ifattach(ifp, lla) ifp->if_output = arc_output; ifp->if_input = arc_input; ac = (struct arccom *)ifp; - ac->ac_seqid = (time.tv_sec) & 0xFFFF; /* try to make seqid unique */ + ac->ac_seqid = (time_second) & 0xFFFF; /* try to make seqid unique */ if (lla == 0) { /* XXX this message isn't entirely clear, to me -- cgd */ log(LOG_ERR,"%s: link address 0 reserved for broadcasts. Please change it and ifconfig %s down up\n", Index: sys/net/if_bridge.c =================================================================== RCS file: /cvsroot/src/sys/net/if_bridge.c,v retrieving revision 1.31 diff -d -p -u -r1.31 if_bridge.c --- sys/net/if_bridge.c 1 Jun 2005 19:45:34 -0000 1.31 +++ sys/net/if_bridge.c 22 Nov 2005 13:42:13 -0000 @@ -811,9 +811,9 @@ bridge_ioctl_rts(struct bridge_softc *sc strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname, sizeof(bareq.ifba_ifsname)); memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr)); - if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) - bareq.ifba_expire = brt->brt_expire - mono_time.tv_sec; - else + if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { + bareq.ifba_expire = brt->brt_expire - time_uptime; + } else bareq.ifba_expire = 0; bareq.ifba_flags = brt->brt_flags; @@ -1638,7 +1638,7 @@ bridge_rtupdate(struct bridge_softc *sc, return (ENOMEM); memset(brt, 0, sizeof(*brt)); - brt->brt_expire = mono_time.tv_sec + sc->sc_brttimeout; + brt->brt_expire = time_uptime + sc->sc_brttimeout; brt->brt_flags = IFBAF_DYNAMIC; memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN); @@ -1651,8 +1651,10 @@ bridge_rtupdate(struct bridge_softc *sc, brt->brt_ifp = dst_if; if (setflags) { brt->brt_flags = flags; - brt->brt_expire = (flags & IFBAF_STATIC) ? 0 : - mono_time.tv_sec + sc->sc_brttimeout; + if (flags & IFBAF_STATIC) + brt->brt_expire = 0; + else + brt->brt_expire = time_uptime + sc->sc_brttimeout; } return (0); @@ -1738,7 +1740,7 @@ bridge_rtage(struct bridge_softc *sc) for (brt = LIST_FIRST(&sc->sc_rtlist); brt != NULL; brt = nbrt) { nbrt = LIST_NEXT(brt, brt_list); if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { - if (mono_time.tv_sec >= brt->brt_expire) + if (time_uptime >= brt->brt_expire) bridge_rtnode_destroy(sc, brt); } } Index: sys/net/if_ecosubr.c =================================================================== RCS file: /cvsroot/src/sys/net/if_ecosubr.c,v retrieving revision 1.17 diff -d -p -u -r1.17 if_ecosubr.c --- sys/net/if_ecosubr.c 18 Aug 2005 00:30:58 -0000 1.17 +++ sys/net/if_ecosubr.c 22 Nov 2005 13:42:15 -0000 @@ -220,7 +220,7 @@ eco_output(struct ifnet *ifp, struct mbu } if (rt->rt_flags & RTF_REJECT) if (rt->rt_rmx.rmx_expire == 0 || - time.tv_sec < rt->rt_rmx.rmx_expire) + time_second < rt->rt_rmx.rmx_expire) senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } /* Index: sys/net/if_ethersubr.c =================================================================== RCS file: /cvsroot/src/sys/net/if_ethersubr.c,v retrieving revision 1.126 diff -d -p -u -r1.126 if_ethersubr.c --- sys/net/if_ethersubr.c 10 Jun 2005 11:11:38 -0000 1.126 +++ sys/net/if_ethersubr.c 22 Nov 2005 13:42:16 -0000 @@ -258,7 +258,7 @@ ether_output(struct ifnet *ifp, struct m } if (rt->rt_flags & RTF_REJECT) if (rt->rt_rmx.rmx_expire == 0 || - (u_long) time.tv_sec < rt->rt_rmx.rmx_expire) + (u_long) time_second < rt->rt_rmx.rmx_expire) senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } Index: sys/net/if_fddisubr.c =================================================================== RCS file: /cvsroot/src/sys/net/if_fddisubr.c,v retrieving revision 1.56 diff -d -p -u -r1.56 if_fddisubr.c --- sys/net/if_fddisubr.c 30 May 2005 04:17:59 -0000 1.56 +++ sys/net/if_fddisubr.c 22 Nov 2005 13:42:19 -0000 @@ -252,7 +252,7 @@ fddi_output(ifp, m0, dst, rt0) } if (rt->rt_flags & RTF_REJECT) if (rt->rt_rmx.rmx_expire == 0 || - time.tv_sec < rt->rt_rmx.rmx_expire) + time_second < rt->rt_rmx.rmx_expire) senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } #endif Index: sys/net/if_hippisubr.c =================================================================== RCS file: /cvsroot/src/sys/net/if_hippisubr.c,v retrieving revision 1.20 diff -d -p -u -r1.20 if_hippisubr.c --- sys/net/if_hippisubr.c 30 May 2005 04:17:59 -0000 1.20 +++ sys/net/if_hippisubr.c 22 Nov 2005 13:42:19 -0000 @@ -140,7 +140,7 @@ hippi_output(ifp, m0, dst, rt0) } if (rt->rt_flags & RTF_REJECT) if (rt->rt_rmx.rmx_expire == 0 || /* XXX: no ARP */ - time.tv_sec < rt->rt_rmx.rmx_expire) + time_second < rt->rt_rmx.rmx_expire) senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } Index: sys/net/if_ieee1394subr.c =================================================================== RCS file: /cvsroot/src/sys/net/if_ieee1394subr.c,v retrieving revision 1.30 diff -d -p -u -r1.30 if_ieee1394subr.c --- sys/net/if_ieee1394subr.c 6 Aug 2005 14:09:54 -0000 1.30 +++ sys/net/if_ieee1394subr.c 22 Nov 2005 13:42:20 -0000 @@ -139,7 +139,7 @@ ieee1394_output(struct ifnet *ifp, struc } if (rt->rt_flags & RTF_REJECT) if (rt->rt_rmx.rmx_expire == 0 || - time.tv_sec < rt->rt_rmx.rmx_expire) + time_second < rt->rt_rmx.rmx_expire) senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } Index: sys/net/if_ppp.c =================================================================== RCS file: /cvsroot/src/sys/net/if_ppp.c,v retrieving revision 1.101 diff -d -p -u -r1.101 if_ppp.c --- sys/net/if_ppp.c 29 May 2005 21:22:52 -0000 1.101 +++ sys/net/if_ppp.c 22 Nov 2005 13:42:22 -0000 @@ -144,7 +144,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_ppp.c,v 1 #include "bpfilter.h" #if NBPFILTER > 0 -#include #include #endif @@ -396,7 +395,7 @@ pppalloc(pid) sc->sc_npmode[i] = NPMODE_ERROR; sc->sc_npqueue = NULL; sc->sc_npqtail = &sc->sc_npqueue; - sc->sc_last_sent = sc->sc_last_recv = time.tv_sec; + sc->sc_last_sent = sc->sc_last_recv = time_second; return sc; } @@ -668,7 +667,7 @@ pppioctl(sc, cmd, data, flag, p) case PPPIOCGIDLE: s = splsoftnet(); - t = time.tv_sec; + t = time_second; ((struct ppp_idle *)data)->xmit_idle = t - sc->sc_last_sent; ((struct ppp_idle *)data)->recv_idle = t - sc->sc_last_recv; splx(s); @@ -997,12 +996,12 @@ pppoutput(ifp, m0, dst, rtp) if (sc->sc_active_filt_out.bf_insns == 0 || bpf_filter(sc->sc_active_filt_out.bf_insns, (u_char *) m0, len, 0)) - sc->sc_last_sent = time.tv_sec; + sc->sc_last_sent = time_second; #else /* * Update the time we sent the most recent packet. */ - sc->sc_last_sent = time.tv_sec; + sc->sc_last_sent = time_second; #endif /* PPP_FILTER */ } @@ -1651,12 +1650,12 @@ ppp_inproc(sc, m) if (sc->sc_active_filt_in.bf_insns == 0 || bpf_filter(sc->sc_active_filt_in.bf_insns, (u_char *) m, ilen, 0)) - sc->sc_last_recv = time.tv_sec; + sc->sc_last_recv = time_second; #else /* * Record the time that we received this packet. */ - sc->sc_last_recv = time.tv_sec; + sc->sc_last_recv = time_second; #endif /* PPP_FILTER */ } Index: sys/net/if_pppoe.c =================================================================== RCS file: /cvsroot/src/sys/net/if_pppoe.c,v retrieving revision 1.61 diff -d -p -u -r1.61 if_pppoe.c --- sys/net/if_pppoe.c 31 Aug 2005 00:00:26 -0000 1.61 +++ sys/net/if_pppoe.c 22 Nov 2005 13:42:25 -0000 @@ -1322,6 +1322,7 @@ pppoe_send_pado(struct pppoe_softc *sc) static int pppoe_send_pads(struct pppoe_softc *sc) { + struct bintime bt; struct mbuf *m0; u_int8_t *p; size_t len, l1 = 0; /* XXX: gcc */ @@ -1329,7 +1330,8 @@ pppoe_send_pads(struct pppoe_softc *sc) if (sc->sc_state != PPPOE_STATE_PADO_SENT) return EIO; - sc->sc_session = mono_time.tv_sec % 0xff + 1; + getbinuptime(&bt); + sc->sc_session = bt.sec % 0xff + 1; /* calc length */ len = 0; /* include hunique */ Index: sys/net/if_sl.c =================================================================== RCS file: /cvsroot/src/sys/net/if_sl.c,v retrieving revision 1.92 diff -d -p -u -r1.92 if_sl.c --- sys/net/if_sl.c 18 Aug 2005 00:30:58 -0000 1.92 +++ sys/net/if_sl.c 22 Nov 2005 13:42:27 -0000 @@ -471,11 +471,12 @@ sloutput(ifp, m, dst, rtp) s = spltty(); if (sc->sc_oqlen && sc->sc_ttyp->t_outq.c_cc == sc->sc_oqlen) { - struct timeval tv; + struct bintime bt; /* if output's been stalled for too long, and restart */ - timersub(&time, &sc->sc_lastpacket, &tv); - if (tv.tv_sec > 0) { + getbinuptime(&bt); + bintime_sub(&bt, &sc->sc_lastpacket); + if (bt.sec > 0) { sc->sc_otimeout++; slstart(sc->sc_ttyp); } @@ -492,7 +493,7 @@ sloutput(ifp, m, dst, rtp) splx(s); return error; } - sc->sc_lastpacket = time; + getbinuptime(&sc->sc_lastpacket); splx(s); s = spltty(); @@ -608,15 +609,15 @@ slinput(c, tp) * this one is within the time limit. */ if (sc->sc_abortcount && - time.tv_sec >= sc->sc_starttime + ABT_WINDOW) + time_second >= sc->sc_starttime + ABT_WINDOW) sc->sc_abortcount = 0; /* * If we see an abort after "idle" time, count it; * record when the first abort escape arrived. */ - if (time.tv_sec >= sc->sc_lasttime + ABT_IDLE) { + if (time_second >= sc->sc_lasttime + ABT_IDLE) { if (++sc->sc_abortcount == 1) - sc->sc_starttime = time.tv_sec; + sc->sc_starttime = time_second; if (sc->sc_abortcount >= ABT_COUNT) { slclose(tp); return; @@ -624,7 +625,7 @@ slinput(c, tp) } } else sc->sc_abortcount = 0; - sc->sc_lasttime = time.tv_sec; + sc->sc_lasttime = time_second; } switch (c) { @@ -791,7 +792,7 @@ slintr(void *arg) bpf_mtap_sl_out(sc->sc_if.if_bpf, mtod(m, u_char *), bpf_m); #endif - sc->sc_lastpacket = time; + getbinuptime(&sc->sc_lastpacket); s = spltty(); @@ -976,7 +977,7 @@ slintr(void *arg) } sc->sc_if.if_ipackets++; - sc->sc_lastpacket = time; + getbinuptime(&sc->sc_lastpacket); #ifdef INET s = splnet(); Index: sys/net/if_slvar.h =================================================================== RCS file: /cvsroot/src/sys/net/if_slvar.h,v retrieving revision 1.27 diff -d -p -u -r1.27 if_slvar.h --- sys/net/if_slvar.h 26 Feb 2005 22:45:09 -0000 1.27 +++ sys/net/if_slvar.h 22 Nov 2005 13:42:27 -0000 @@ -67,7 +67,7 @@ struct sl_softc { #ifdef INET /* XXX */ struct slcompress sc_comp; /* tcp compression data */ #endif - struct timeval sc_lastpacket; /* for watchdog */ + struct bintime sc_lastpacket; /* for watchdog */ LIST_ENTRY(sl_softc) sc_iflist; }; Index: sys/net/if_spppsubr.c =================================================================== RCS file: /cvsroot/src/sys/net/if_spppsubr.c,v retrieving revision 1.85 diff -d -p -u -r1.85 if_spppsubr.c --- sys/net/if_spppsubr.c 29 May 2005 21:22:53 -0000 1.85 +++ sys/net/if_spppsubr.c 22 Nov 2005 13:42:38 -0000 @@ -475,7 +475,7 @@ sppp_input(struct ifnet *ifp, struct mbu /* Count received bytes, add hardware framing */ ifp->if_ibytes += m->m_pkthdr.len + sp->pp_framebytes; /* Note time of last receive */ - sp->pp_last_receive = mono_time.tv_sec; + sp->pp_last_receive = time_uptime; } if (m->m_pkthdr.len <= PPP_HEADER_LEN) { @@ -612,7 +612,7 @@ sppp_input(struct ifnet *ifp, struct mbu if (sp->state[IDX_IPCP] == STATE_OPENED) { schednetisr(NETISR_IP); inq = &ipintrq; - sp->pp_last_activity = mono_time.tv_sec; + sp->pp_last_activity = time_uptime; } break; #endif @@ -627,7 +627,7 @@ sppp_input(struct ifnet *ifp, struct mbu if (sp->state[IDX_IPV6CP] == STATE_OPENED) { schednetisr(NETISR_IPV6); inq = &ip6intrq; - sp->pp_last_activity = mono_time.tv_sec; + sp->pp_last_activity = time_uptime; } break; #endif @@ -695,7 +695,7 @@ sppp_output(struct ifnet *ifp, struct mb s = splnet(); - sp->pp_last_activity = mono_time.tv_sec; + sp->pp_last_activity = time_uptime; if ((ifp->if_flags & IFF_UP) == 0 || (ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == 0) { @@ -1244,8 +1244,9 @@ sppp_cisco_send(struct sppp *sp, int typ struct ppp_header *h; struct cisco_packet *ch; struct mbuf *m; - u_int32_t t = (time.tv_sec - boottime.tv_sec) * 1000; + u_int32_t t; + t = time_uptime * 1000; MGETHDR(m, M_DONTWAIT, MT_DATA); if (! m) return; @@ -2024,7 +2025,7 @@ sppp_lcp_up(struct sppp *sp) STDDCL; /* Initialize activity timestamp: opening a connection is an activity */ - sp->pp_last_receive = sp->pp_last_activity = mono_time.tv_sec; + sp->pp_last_receive = sp->pp_last_activity = time_uptime; /* * If this interface is passive or dial-on-demand, and we are @@ -4637,7 +4638,7 @@ sppp_keepalive(void *dummy) time_t now; s = splnet(); - now = mono_time.tv_sec; + now = time_uptime; for (sp=spppq; sp; sp=sp->pp_next) { struct ifnet *ifp = &sp->pp_if; Index: sys/net/if_strip.c =================================================================== RCS file: /cvsroot/src/sys/net/if_strip.c,v retrieving revision 1.61 diff -d -p -u -r1.61 if_strip.c --- sys/net/if_strip.c 18 Aug 2005 00:30:58 -0000 1.61 +++ sys/net/if_strip.c 22 Nov 2005 13:42:41 -0000 @@ -313,7 +313,7 @@ void strip_timeout __P((void *x)); #define CLEAR_RESET_TIMER(sc) \ do {\ (sc)->sc_state = ST_ALIVE; \ - (sc)->sc_statetimo = time.tv_sec + ST_PROBE_INTERVAL; \ + (sc)->sc_statetimo = time_second + ST_PROBE_INTERVAL; \ } while (/*CONSTCOND*/ 0) /* @@ -322,13 +322,13 @@ void strip_timeout __P((void *x)); */ #define FORCE_RESET(sc) \ do {\ - (sc)->sc_statetimo = time.tv_sec - 1; \ + (sc)->sc_statetimo = time_second - 1; \ (sc)->sc_state = ST_DEAD; \ /*(sc)->sc_if.if_timer = 0;*/ \ } while (/*CONSTCOND*/ 0) #define RADIO_PROBE_TIMEOUT(sc) \ - ((sc)-> sc_statetimo > time.tv_sec) + ((sc)-> sc_statetimo > time_second) @@ -440,7 +440,7 @@ stripinit(sc) /* Initialize radio probe/reset state machine */ sc->sc_state = ST_DEAD; /* assumet the worst. */ - sc->sc_statetimo = time.tv_sec; /* do reset immediately */ + sc->sc_statetimo = time_second; /* do reset immediately */ return (1); } @@ -715,7 +715,7 @@ strip_send(sc, m0) * If a radio probe is due now, append it to this packet rather * than waiting until the watchdog routine next runs. */ - if (time.tv_sec >= sc->sc_statetimo && sc->sc_state == ST_ALIVE) + if (time_second >= sc->sc_statetimo && sc->sc_state == ST_ALIVE) strip_proberadio(sc, tp); } @@ -856,11 +856,12 @@ stripoutput(ifp, m, dst, rt) s = spltty(); if (sc->sc_oqlen && sc->sc_ttyp->t_outq.c_cc == sc->sc_oqlen) { - struct timeval tv; + struct bintime bt; /* if output's been stalled for too long, and restart */ - timersub(&time, &sc->sc_lastpacket, &tv); - if (tv.tv_sec > 0) { + getbinuptime(&bt); + bintime_sub(&bt, &sc->sc_lastpacket); + if (bt.sec > 0) { DPRINTF(("stripoutput: stalled, resetting\n")); sc->sc_otimeout++; stripstart(sc->sc_ttyp); @@ -874,7 +875,7 @@ stripoutput(ifp, m, dst, rt) splx(s); return error; } - sc->sc_lastpacket = time; + getbinuptime(&sc->sc_lastpacket); splx(s); s = spltty(); @@ -1180,7 +1181,7 @@ stripintr(void *arg) bpf_mtap_sl_out(sc->sc_if.if_bpf, mtod(m, u_char *), bpf_m); #endif - sc->sc_lastpacket = time; + getbinuptime(&sc->sc_lastpacket); s = spltty(); strip_send(sc, m); @@ -1283,7 +1284,7 @@ stripintr(void *arg) } sc->sc_if.if_ipackets++; - sc->sc_lastpacket = time; + getbinuptime(&sc->sc_lastpacket); #ifdef INET s = splnet(); @@ -1396,8 +1397,8 @@ strip_resetradio(sc, tp) * is so badlyhung it needs powercycling. */ sc->sc_state = ST_DEAD; - sc->sc_lastpacket = time; - sc->sc_statetimo = time.tv_sec + STRIP_RESET_INTERVAL; + getbinuptime(&sc->sc_lastpacket); + sc->sc_statetimo = time_second + STRIP_RESET_INTERVAL; /* * XXX Does calling the tty output routine now help resets? @@ -1435,7 +1436,7 @@ strip_proberadio(sc, tp) sc->sc_if.if_xname); /* Go to probe-sent state, set timeout accordingly. */ sc->sc_state = ST_PROBE_SENT; - sc->sc_statetimo = time.tv_sec + ST_PROBERESPONSE_INTERVAL; + sc->sc_statetimo = time_second + ST_PROBERESPONSE_INTERVAL; } else { addlog("%s: incomplete probe, tty queue %d bytes overfull\n", sc->sc_if.if_xname, overflow); @@ -1511,13 +1512,13 @@ strip_watchdog(ifp) ifp->if_xname, ((unsigned) sc->sc_state < 3) ? strip_statenames[sc->sc_state] : "<>", - sc->sc_statetimo - time.tv_sec); + sc->sc_statetimo - time_second); #endif /* * If time in this state hasn't yet expired, return. */ - if ((ifp->if_flags & IFF_UP) == 0 || sc->sc_statetimo > time.tv_sec) { + if ((ifp->if_flags & IFF_UP) == 0 || sc->sc_statetimo > time_second) { goto done; } Index: sys/net/if_stripvar.h =================================================================== RCS file: /cvsroot/src/sys/net/if_stripvar.h,v retrieving revision 1.13 diff -d -p -u -r1.13 if_stripvar.h --- sys/net/if_stripvar.h 5 Dec 2004 05:43:04 -0000 1.13 +++ sys/net/if_stripvar.h 22 Nov 2005 13:42:41 -0000 @@ -40,7 +40,7 @@ struct strip_softc { long sc_statetimo; /* When (secs) current state ends */ - struct timeval sc_lastpacket; /* for watchdog */ + struct bintime sc_lastpacket; /* for watchdog */ LIST_ENTRY(strip_softc) sc_iflist; }; Index: sys/net/if_tap.c =================================================================== RCS file: /cvsroot/src/sys/net/if_tap.c,v retrieving revision 1.10 diff -d -p -u -r1.10 if_tap.c --- sys/net/if_tap.c 20 Jun 2005 02:49:19 -0000 1.10 +++ sys/net/if_tap.c 22 Nov 2005 13:42:43 -0000 @@ -250,24 +250,26 @@ tap_match(struct device *self, struct cf void tap_attach(struct device *parent, struct device *self, void *aux) { - struct tap_softc *sc = (struct tap_softc *)self; - struct ifnet *ifp; + char enaddrstr[18]; u_int8_t enaddr[ETHER_ADDR_LEN] = { 0xf2, 0x0b, 0xa4, 0xff, 0xff, 0xff }; - char enaddrstr[18]; + struct timeval tv; + struct tap_softc *sc = (struct tap_softc *)self; + struct ifnet *ifp; + const struct sysctlnode *node; uint32_t ui; int error; - const struct sysctlnode *node; aprint_normal("%s: faking Ethernet device\n", self->dv_xname); /* * In order to obtain unique initial Ethernet address on a host, - * do some randomisation using mono_time. It's not meant for anything - * but avoiding hard-coding an address. + * do some randomisation using the current uptime. It's not meant + * for anything but avoiding hard-coding an address. */ - ui = (mono_time.tv_sec ^ mono_time.tv_usec) & 0xffffff; + getmicrouptime(&tv); + ui = (tv.tv_sec ^ tv.tv_usec) & 0xffffff; memcpy(enaddr+3, (u_int8_t *)&ui, 3); aprint_normal("%s: Ethernet address %s\n", sc->sc_dev.dv_xname, Index: sys/net/if_tokensubr.c =================================================================== RCS file: /cvsroot/src/sys/net/if_tokensubr.c,v retrieving revision 1.32 diff -d -p -u -r1.32 if_tokensubr.c --- sys/net/if_tokensubr.c 30 May 2005 04:17:59 -0000 1.32 +++ sys/net/if_tokensubr.c 22 Nov 2005 13:42:45 -0000 @@ -248,7 +248,7 @@ token_output(ifp, m0, dst, rt0) } if (rt->rt_flags & RTF_REJECT) if (rt->rt_rmx.rmx_expire == 0 || - time.tv_sec < rt->rt_rmx.rmx_expire) + time_second < rt->rt_rmx.rmx_expire) senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } Index: sys/net/route.c =================================================================== RCS file: /cvsroot/src/sys/net/route.c,v retrieving revision 1.66 diff -d -p -u -r1.66 route.c --- sys/net/route.c 29 May 2005 21:22:53 -0000 1.66 +++ sys/net/route.c 22 Nov 2005 13:42:46 -0000 @@ -946,12 +946,6 @@ rt_timer_add(struct rtentry *rt, struct rttimer_queue *queue) { struct rttimer *r; - long current_time; - int s; - - s = splclock(); - current_time = mono_time.tv_sec; - splx(s); /* * If there's already a timer with this action, destroy it before @@ -977,7 +971,7 @@ rt_timer_add(struct rtentry *rt, Bzero(r, sizeof(*r)); r->rtt_rt = rt; - r->rtt_time = current_time; + r->rtt_time = time_uptime; r->rtt_func = func; r->rtt_queue = queue; LIST_INSERT_HEAD(&rt->rt_timer, r, rtt_link); @@ -993,18 +987,13 @@ rt_timer_timer(void *arg) { struct rttimer_queue *rtq; struct rttimer *r; - long current_time; int s; - s = splclock(); - current_time = mono_time.tv_sec; - splx(s); - s = splsoftnet(); for (rtq = LIST_FIRST(&rttimer_queue_head); rtq != NULL; rtq = LIST_NEXT(rtq, rtq_link)) { while ((r = TAILQ_FIRST(&rtq->rtq_head)) != NULL && - (r->rtt_time + rtq->rtq_timeout) < current_time) { + (r->rtt_time + rtq->rtq_timeout) < time_uptime) { LIST_REMOVE(r, rtt_link); TAILQ_REMOVE(&rtq->rtq_head, r, rtt_next); RTTIMER_CALLOUT(r); Index: sys/netatalk/at_control.c =================================================================== RCS file: /cvsroot/src/sys/netatalk/at_control.c,v retrieving revision 1.10 diff -d -p -u -r1.10 at_control.c --- sys/netatalk/at_control.c 26 Feb 2005 22:45:09 -0000 1.10 +++ sys/netatalk/at_control.c 22 Nov 2005 13:42:48 -0000 @@ -468,7 +468,7 @@ at_ifinit(ifp, aa, sat) */ if (nnets != 1) { net = ntohs(nr.nr_firstnet) + - time.tv_sec % (nnets - 1); + time_second % (nnets - 1); } else { net = ntohs(nr.nr_firstnet); } @@ -507,7 +507,7 @@ at_ifinit(ifp, aa, sat) * not specified, be random about it... XXX use /dev/random? */ if (sat->sat_addr.s_node == ATADDR_ANYNODE) { - AA_SAT(aa)->sat_addr.s_node = time.tv_sec; + AA_SAT(aa)->sat_addr.s_node = time_second; } else { AA_SAT(aa)->sat_addr.s_node = sat->sat_addr.s_node; } @@ -526,7 +526,7 @@ at_ifinit(ifp, aa, sat) * Once again, starting at the (possibly random) * initial node address. */ - for (j = 0, nodeinc = time.tv_sec | 1; j < 256; + for (j = 0, nodeinc = time_second | 1; j < 256; j++, AA_SAT(aa)->sat_addr.s_node += nodeinc) { if (AA_SAT(aa)->sat_addr.s_node > 253 || AA_SAT(aa)->sat_addr.s_node < 1) { @@ -570,7 +570,7 @@ at_ifinit(ifp, aa, sat) break; /* reset node for next network */ - AA_SAT(aa)->sat_addr.s_node = time.tv_sec; + AA_SAT(aa)->sat_addr.s_node = time_second; } /* Index: sys/netccitt/pk_acct.c =================================================================== RCS file: /cvsroot/src/sys/netccitt/pk_acct.c,v retrieving revision 1.20 diff -d -p -u -r1.20 pk_acct.c --- sys/netccitt/pk_acct.c 6 Oct 2005 16:32:14 -0000 1.20 +++ sys/netccitt/pk_acct.c 22 Nov 2005 13:42:48 -0000 @@ -156,7 +156,7 @@ pk_acct(lcp) if (sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) acbuf.x25acct_revcharge = 1; acbuf.x25acct_stime = lcp -> lcd_stime; - acbuf.x25acct_etime = time.tv_sec - acbuf.x25acct_stime; + acbuf.x25acct_etime = time_second - acbuf.x25acct_stime; acbuf.x25acct_uid = curproc -> p_cred -> p_ruid; acbuf.x25acct_psize = sa -> x25_opts.op_psize; acbuf.x25acct_net = sa -> x25_net; Index: sys/netccitt/pk_subr.c =================================================================== RCS file: /cvsroot/src/sys/netccitt/pk_subr.c,v retrieving revision 1.30 diff -d -p -u -r1.30 pk_subr.c --- sys/netccitt/pk_subr.c 29 May 2005 21:53:52 -0000 1.30 +++ sys/netccitt/pk_subr.c 22 Nov 2005 13:42:49 -0000 @@ -504,7 +504,7 @@ pk_assoc(pkp, lcp, sa) sa->x25_opts.op_wsize = lcp->lcd_windowsize; sa->x25_net = pkp->pk_xcp->xc_addr.x25_net; lcp->lcd_flags |= sa->x25_opts.op_flags; - lcp->lcd_stime = time.tv_sec; + lcp->lcd_stime = time_second; } int Index: sys/netinet/if_arp.c =================================================================== RCS file: /cvsroot/src/sys/netinet/if_arp.c,v retrieving revision 1.106 diff -d -p -u -r1.106 if_arp.c --- sys/netinet/if_arp.c 20 Jun 2005 02:49:18 -0000 1.106 +++ sys/netinet/if_arp.c 22 Nov 2005 13:42:52 -0000 @@ -91,6 +91,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1 #include #include #include +#include #include #include #include @@ -350,8 +351,8 @@ arptimer(void *arg) nla = LIST_NEXT(la, la_list); if (rt->rt_expire == 0) continue; - if ((rt->rt_expire - time.tv_sec) < arpt_refresh && - rt->rt_pksent > (time.tv_sec - arpt_keep)) { + if ((rt->rt_expire - time_second) < arpt_refresh && + rt->rt_pksent > (time_second - arpt_keep)) { /* * If the entry has been used during since last * refresh, try to renew it before deleting. @@ -360,7 +361,7 @@ arptimer(void *arg) &SIN(rt->rt_ifa->ifa_addr)->sin_addr, &SIN(rt_key(rt))->sin_addr, LLADDR(rt->rt_ifp->if_sadl)); - } else if (rt->rt_expire <= time.tv_sec) + } else if (rt->rt_expire <= time_second) arptfree(la); /* timer has expired; clear */ } @@ -387,11 +388,18 @@ arp_rtrequest(int req, struct rtentry *r if (!arpinit_done) { arpinit_done = 1; /* - * We generate expiration times from time.tv_sec + * We generate expiration times from time_second * so avoid accidently creating permanent routes. */ - if (time.tv_sec == 0) { + if (time_second == 0) { +#ifdef __HAVE_TIMECOUNTER + struct timespec ts; + ts.tv_sec = 1; + ts.tv_nsec = 0; + tc_setclock(&ts); +#else /* !__HAVE_TIMECOUNTER */ time.tv_sec++; +#endif /* !__HAVE_TIMECOUNTER */ } callout_init(&arptimer_ch); callout_reset(&arptimer_ch, hz, arptimer, NULL); @@ -456,7 +464,7 @@ arp_rtrequest(int req, struct rtentry *r * it's a "permanent" route, so that routes cloned * from it do not need their expiration time set. */ - rt->rt_expire = time.tv_sec; + rt->rt_expire = time_second; /* * linklayers with particular link MTU limitation. */ @@ -687,11 +695,11 @@ arpresolve(struct ifnet *ifp, struct rte * Check the address family and length is valid, the address * is resolved; otherwise, try to resolve. */ - if ((rt->rt_expire == 0 || rt->rt_expire > time.tv_sec) && + if ((rt->rt_expire == 0 || rt->rt_expire > time_second) && sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) { bcopy(LLADDR(sdl), desten, min(sdl->sdl_alen, ifp->if_addrlen)); - rt->rt_pksent = time.tv_sec; /* Time for last pkt sent */ + rt->rt_pksent = time_second; /* Time for last pkt sent */ return 1; } /* @@ -719,13 +727,13 @@ arpresolve(struct ifnet *ifp, struct rte /* This should never happen. (Should it? -gwr) */ printf("arpresolve: unresolved and rt_expire == 0\n"); /* Set expiration time to now (expired). */ - rt->rt_expire = time.tv_sec; + rt->rt_expire = time_second; } #endif if (rt->rt_expire) { rt->rt_flags &= ~RTF_REJECT; - if (la->la_asked == 0 || rt->rt_expire != time.tv_sec) { - rt->rt_expire = time.tv_sec; + if (la->la_asked == 0 || rt->rt_expire != time_second) { + rt->rt_expire = time_second; if (la->la_asked++ < arp_maxtries) arprequest(ifp, &SIN(rt->rt_ifa->ifa_addr)->sin_addr, @@ -1031,7 +1039,7 @@ in_arpinput(struct mbuf *m) bcopy((caddr_t)ar_sha(ah), LLADDR(sdl), sdl->sdl_alen = ah->ar_hln); if (rt->rt_expire) - rt->rt_expire = time.tv_sec + arpt_keep; + rt->rt_expire = time_second + arpt_keep; rt->rt_flags &= ~RTF_REJECT; la->la_asked = 0; Index: sys/netinet/in_gif.c =================================================================== RCS file: /cvsroot/src/sys/netinet/in_gif.c,v retrieving revision 1.45 diff -d -p -u -r1.45 in_gif.c --- sys/netinet/in_gif.c 26 Jun 2005 10:39:21 -0000 1.45 +++ sys/netinet/in_gif.c 22 Nov 2005 13:42:52 -0000 @@ -197,7 +197,7 @@ in_gif_output(struct ifnet *ifp, int fam return ENOBUFS; bcopy(&iphdr, mtod(m, struct ip *), sizeof(struct ip)); - if (sc->gif_route_expire - time.tv_sec <= 0 || + if (sc->gif_route_expire - time_second <= 0 || dst->sin_family != sin_dst->sin_family || !in_hosteq(dst->sin_addr, sin_dst->sin_addr)) { /* cache route doesn't match */ @@ -224,7 +224,7 @@ in_gif_output(struct ifnet *ifp, int fam return ENETUNREACH; /*XXX*/ } - sc->gif_route_expire = time.tv_sec + GIF_ROUTE_TTL; + sc->gif_route_expire = time_second + GIF_ROUTE_TTL; } error = ip_output(m, NULL, &sc->gif_ro, 0, NULL, NULL); Index: sys/netinet/ip_flow.c =================================================================== RCS file: /cvsroot/src/sys/netinet/ip_flow.c,v retrieving revision 1.30 diff -d -p -u -r1.30 ip_flow.c --- sys/netinet/ip_flow.c 17 Oct 2005 19:51:24 -0000 1.30 +++ sys/netinet/ip_flow.c 22 Nov 2005 13:42:53 -0000 @@ -406,7 +406,7 @@ ipflow_create(const struct route *ro, st ipf->ipf_src = ip->ip_src; ipf->ipf_tos = ip->ip_tos; PRT_SLOW_ARM(ipf->ipf_timer, IPFLOW_TIMER); - ipf->ipf_start = time.tv_sec; + ipf->ipf_start = time_uptime; /* * Insert into the approriate bucket of the flow table. */ Index: sys/netinet/ip_id.c =================================================================== RCS file: /cvsroot/src/sys/netinet/ip_id.c,v retrieving revision 1.8 diff -d -p -u -r1.8 ip_id.c --- sys/netinet/ip_id.c 23 Mar 2004 05:31:54 -0000 1.8 +++ sys/netinet/ip_id.c 22 Nov 2005 13:42:54 -0000 @@ -56,9 +56,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip_id.c,v 1. #include "opt_inet.h" -#include #include -#include #include #include @@ -163,7 +161,7 @@ ip_initid(void) ru_g = pmod(RU_GEN, j, RU_N); ru_counter = 0; - ru_reseed = time.tv_sec + RU_OUT; + ru_reseed = time_second + RU_OUT; ru_msb = ru_msb == 0x8000 ? 0 : 0x8000; } @@ -172,7 +170,7 @@ ip_randomid(void) { int i, n; - if (ru_counter >= RU_MAX || time.tv_sec > ru_reseed) + if (ru_counter >= RU_MAX || time_second > ru_reseed) ip_initid(); #if 0 Index: sys/netinet/ip_input.c =================================================================== RCS file: /cvsroot/src/sys/netinet/ip_input.c,v retrieving revision 1.221 diff -d -p -u -r1.221 ip_input.c --- sys/netinet/ip_input.c 1 Nov 2005 21:21:09 -0000 1.221 +++ sys/netinet/ip_input.c 22 Nov 2005 13:42:57 -0000 @@ -414,7 +414,7 @@ ip_init(void) for (i = 0; i < IPREASS_NHASH; i++) LIST_INIT(&ipq[i]); - ip_id = time.tv_sec & 0xfffff; + ip_id = time_second & 0xfffff; ipintrq.ifq_maxlen = ipqmaxlen; ip_nmbclusters_changed(); Index: sys/netinet/tcp_input.c =================================================================== RCS file: /cvsroot/src/sys/netinet/tcp_input.c,v retrieving revision 1.237 diff -d -p -u -r1.237 tcp_input.c --- sys/netinet/tcp_input.c 15 Nov 2005 18:39:46 -0000 1.237 +++ sys/netinet/tcp_input.c 22 Nov 2005 13:43:05 -0000 @@ -967,7 +967,6 @@ tcp_input(struct mbuf *m, ...) #ifdef TCP_DEBUG short ostate = 0; #endif - int iss = 0; u_long tiwin; struct tcp_opt_info opti; int off, iphlen; @@ -2022,7 +2021,6 @@ after_listen: if (tiflags & TH_SYN && tp->t_state == TCPS_TIME_WAIT && SEQ_GT(th->th_seq, tp->rcv_nxt)) { - iss = tcp_new_iss(tp, tp->snd_nxt); tp = tcp_close(tp); TCP_FIELDS_TO_NET(th); goto findpcb; Index: sys/netinet6/icmp6.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/icmp6.c,v retrieving revision 1.111 diff -d -p -u -r1.111 icmp6.c --- sys/netinet6/icmp6.c 19 Oct 2005 20:42:54 -0000 1.111 +++ sys/netinet6/icmp6.c 22 Nov 2005 13:43:11 -0000 @@ -1845,8 +1845,9 @@ ni6_store_addrs(ni6, nni6, ifp0, resid) ltime = ND6_INFINITE_LIFETIME; else { if (ifa6->ia6_lifetime.ia6t_expire > - time.tv_sec) - ltime = ifa6->ia6_lifetime.ia6t_expire - time.tv_sec; + time_second) + ltime = ifa6->ia6_lifetime.ia6t_expire - + time_second; else ltime = 0; } Index: sys/netinet6/in6.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/in6.c,v retrieving revision 1.93 diff -d -p -u -r1.93 in6.c --- sys/netinet6/in6.c 29 May 2005 21:43:51 -0000 1.93 +++ sys/netinet6/in6.c 22 Nov 2005 13:43:14 -0000 @@ -516,11 +516,11 @@ in6_control(so, cmd, data, ifp, p) /* sanity for overflow - beware unsigned */ lt = &ifr->ifr_ifru.ifru_lifetime; if (lt->ia6t_vltime != ND6_INFINITE_LIFETIME - && lt->ia6t_vltime + time.tv_sec < time.tv_sec) { + && lt->ia6t_vltime + time_second < time_second) { return EINVAL; } if (lt->ia6t_pltime != ND6_INFINITE_LIFETIME - && lt->ia6t_pltime + time.tv_sec < time.tv_sec) { + && lt->ia6t_pltime + time_second < time_second) { return EINVAL; } break; @@ -614,12 +614,12 @@ in6_control(so, cmd, data, ifp, p) /* for sanity */ if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) { ia->ia6_lifetime.ia6t_expire = - time.tv_sec + ia->ia6_lifetime.ia6t_vltime; + time_second + ia->ia6_lifetime.ia6t_vltime; } else ia->ia6_lifetime.ia6t_expire = 0; if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) { ia->ia6_lifetime.ia6t_preferred = - time.tv_sec + ia->ia6_lifetime.ia6t_pltime; + time_second + ia->ia6_lifetime.ia6t_pltime; } else ia->ia6_lifetime.ia6t_preferred = 0; break; @@ -933,7 +933,7 @@ in6_update_ifa(ifp, ifra, ia) ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; ia->ia_addr.sin6_family = AF_INET6; ia->ia_addr.sin6_len = sizeof(ia->ia_addr); - ia->ia6_createtime = ia->ia6_updatetime = time.tv_sec; + ia->ia6_createtime = ia->ia6_updatetime = time_second; if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) { /* * XXX: some functions expect that ifa_dstaddr is not @@ -1008,12 +1008,12 @@ in6_update_ifa(ifp, ifra, ia) ia->ia6_lifetime = ifra->ifra_lifetime; if (ia->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) { ia->ia6_lifetime.ia6t_expire = - time.tv_sec + ia->ia6_lifetime.ia6t_vltime; + time_second + ia->ia6_lifetime.ia6t_vltime; } else ia->ia6_lifetime.ia6t_expire = 0; if (ia->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) { ia->ia6_lifetime.ia6t_preferred = - time.tv_sec + ia->ia6_lifetime.ia6t_pltime; + time_second + ia->ia6_lifetime.ia6t_pltime; } else ia->ia6_lifetime.ia6t_preferred = 0; @@ -1031,7 +1031,7 @@ in6_update_ifa(ifp, ifra, ia) */ if ((ifra->ifra_flags & IN6_IFF_DEPRECATED) != 0) { ia->ia6_lifetime.ia6t_pltime = 0; - ia->ia6_lifetime.ia6t_preferred = time.tv_sec; + ia->ia6_lifetime.ia6t_preferred = time_second; } /* * Make the address tentative before joining multicast addresses, Index: sys/netinet6/in6.h =================================================================== RCS file: /cvsroot/src/sys/netinet6/in6.h,v retrieving revision 1.47 diff -d -p -u -r1.47 in6.h --- sys/netinet6/in6.h 28 Aug 2005 21:01:53 -0000 1.47 +++ sys/netinet6/in6.h 22 Nov 2005 13:43:18 -0000 @@ -357,11 +357,11 @@ extern const struct in6_addr in6addr_lin #define IFA6_IS_DEPRECATED(a) \ ((a)->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME && \ - (u_int32_t)((time.tv_sec - (a)->ia6_updatetime)) > \ + (u_int32_t)((time_second - (a)->ia6_updatetime)) > \ (a)->ia6_lifetime.ia6t_pltime) #define IFA6_IS_INVALID(a) \ ((a)->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME && \ - (u_int32_t)((time.tv_sec - (a)->ia6_updatetime)) > \ + (u_int32_t)((time_second - (a)->ia6_updatetime)) > \ (a)->ia6_lifetime.ia6t_vltime) #endif Index: sys/netinet6/in6_gif.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/in6_gif.c,v retrieving revision 1.43 diff -d -p -u -r1.43 in6_gif.c --- sys/netinet6/in6_gif.c 26 Jun 2005 10:39:21 -0000 1.43 +++ sys/netinet6/in6_gif.c 22 Nov 2005 13:43:19 -0000 @@ -183,7 +183,7 @@ in6_gif_output(ifp, family, m) ip6->ip6_flow &= ~ntohl(0xff00000); ip6->ip6_flow |= htonl((u_int32_t)otos << 20); - if (sc->gif_route_expire - time.tv_sec <= 0 || + if (sc->gif_route_expire - time_second <= 0 || dst->sin6_family != sin6_dst->sin6_family || !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &sin6_dst->sin6_addr)) { /* cache route doesn't match */ @@ -210,7 +210,7 @@ in6_gif_output(ifp, family, m) return ENETUNREACH; /* XXX */ } - sc->gif_route_expire = time.tv_sec + GIF_ROUTE_TTL; + sc->gif_route_expire = time_second + GIF_ROUTE_TTL; } #ifdef IPV6_MINMTU Index: sys/netinet6/ip6_forward.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/ip6_forward.c,v retrieving revision 1.45 diff -d -p -u -r1.45 ip6_forward.c --- sys/netinet6/ip6_forward.c 29 May 2005 21:43:51 -0000 1.45 +++ sys/netinet6/ip6_forward.c 22 Nov 2005 13:43:20 -0000 @@ -131,8 +131,8 @@ ip6_forward(m, srcrt) IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) { ip6stat.ip6s_cantforward++; /* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */ - if (ip6_log_time + ip6_log_interval < time.tv_sec) { - ip6_log_time = time.tv_sec; + if (ip6_log_time + ip6_log_interval < time_second) { + ip6_log_time = time_second; log(LOG_DEBUG, "cannot forward " "from %s to %s nxt %d received on %s\n", @@ -400,8 +400,8 @@ ip6_forward(m, srcrt) ip6stat.ip6s_badscope++; in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard); - if (ip6_log_time + ip6_log_interval < time.tv_sec) { - ip6_log_time = time.tv_sec; + if (ip6_log_time + ip6_log_interval < time_second) { + ip6_log_time = time_second; log(LOG_DEBUG, "cannot forward " "src %s, dst %s, nxt %d, rcvif %s, outif %s\n", Index: sys/netinet6/ip6_id.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/ip6_id.c,v retrieving revision 1.13 diff -d -p -u -r1.13 ip6_id.c --- sys/netinet6/ip6_id.c 23 Mar 2004 05:31:54 -0000 1.13 +++ sys/netinet6/ip6_id.c 22 Nov 2005 13:43:22 -0000 @@ -84,9 +84,7 @@ #include __KERNEL_RCSID(0, "$NetBSD: ip6_id.c,v 1.13 2004/03/23 05:31:54 itojun Exp $"); -#include #include -#include #include #include @@ -211,7 +209,7 @@ initid(struct randomtab *p) p->ru_g = pmod(p->ru_gen, j, p->ru_n); p->ru_counter = 0; - p->ru_reseed = time.tv_sec + p->ru_out; + p->ru_reseed = time_second + p->ru_out; p->ru_msb = p->ru_msb ? 0 : (1U << (p->ru_bits - 1)); } @@ -220,7 +218,7 @@ randomid(struct randomtab *p) { int i, n; - if (p->ru_counter >= p->ru_max || time.tv_sec > p->ru_reseed) + if (p->ru_counter >= p->ru_max || time_second > p->ru_reseed) initid(p); /* Skip a random number of ids */ Index: sys/netinet6/ip6_mroute.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/ip6_mroute.c,v retrieving revision 1.67 diff -d -p -u -r1.67 ip6_mroute.c --- sys/netinet6/ip6_mroute.c 21 Oct 2005 18:00:45 -0000 1.67 +++ sys/netinet6/ip6_mroute.c 22 Nov 2005 13:43:24 -0000 @@ -1083,8 +1083,8 @@ ip6_mforward(ip6, ifp, m) */ if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) { ip6stat.ip6s_cantforward++; - if (ip6_log_time + ip6_log_interval < time.tv_sec) { - ip6_log_time = time.tv_sec; + if (ip6_log_time + ip6_log_interval < time_second) { + ip6_log_time = time_second; log(LOG_DEBUG, "cannot forward " "from %s to %s nxt %d received on %s\n", Index: sys/netinet6/ipsec.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/ipsec.c,v retrieving revision 1.104 diff -d -p -u -r1.104 ipsec.c --- sys/netinet6/ipsec.c 9 Sep 2005 15:38:05 -0000 1.104 +++ sys/netinet6/ipsec.c 22 Nov 2005 13:43:30 -0000 @@ -182,6 +182,7 @@ ipsec_checkpcbcache(m, pcbsp, dir) int dir; { struct secpolicyindex spidx; + struct bintime bt; switch (dir) { case IPSEC_DIR_INBOUND: @@ -232,7 +233,8 @@ ipsec_checkpcbcache(m, pcbsp, dir) */ } - pcbsp->sp_cache[dir].cachesp->lastused = mono_time.tv_sec; + getbinuptime(&bt); + pcbsp->sp_cache[dir].cachesp->lastused = bt.sec; pcbsp->sp_cache[dir].cachesp->refcnt++; KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP ipsec_checkpcbcache cause refcnt++:%d SP:%p\n", Index: sys/netinet6/nd6.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/nd6.c,v retrieving revision 1.94 diff -d -p -u -r1.94 nd6.c --- sys/netinet6/nd6.c 29 May 2005 21:43:51 -0000 1.94 +++ sys/netinet6/nd6.c 22 Nov 2005 13:43:34 -0000 @@ -393,7 +393,7 @@ nd6_llinfo_settimer(ln, xtick) ln->ln_ntick = 0; callout_stop(&ln->ln_timer_ch); } else { - ln->ln_expire = time.tv_sec + xtick / hz; + ln->ln_expire = time_second + xtick / hz; if (xtick > INT_MAX) { ln->ln_ntick = xtick - INT_MAX; callout_reset(&ln->ln_timer_ch, INT_MAX, @@ -538,7 +538,7 @@ nd6_timer(ignored_arg) /* expire default router list */ dr = TAILQ_FIRST(&nd_defrouter); while (dr) { - if (dr->expire && dr->expire < time.tv_sec) { + if (dr->expire && dr->expire < time_second) { struct nd_defrouter *t; t = TAILQ_NEXT(dr, dr_entry); defrtrlist_del(dr); @@ -580,7 +580,7 @@ nd6_timer(ignored_arg) * prefix is not necessary. */ if (pr->ndpr_vltime != ND6_INFINITE_LIFETIME && - time.tv_sec - pr->ndpr_lastupdate > pr->ndpr_vltime) { + time_second - pr->ndpr_lastupdate > pr->ndpr_vltime) { struct nd_prefix *t; t = pr->ndpr_next; @@ -885,9 +885,9 @@ nd6_free(rt, gc) * XXX: the check for ln_state would be redundant, * but we intentionally keep it just in case. */ - if (dr->expire > time.tv_sec) + if (dr->expire > time_second) nd6_llinfo_settimer(ln, - (dr->expire - time.tv_sec) * hz); + (dr->expire - time_second) * hz); else nd6_llinfo_settimer(ln, (long)nd6_gctimer * hz); splx(s); Index: sys/netinet6/nd6_rtr.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/nd6_rtr.c,v retrieving revision 1.52 diff -d -p -u -r1.52 nd6_rtr.c --- sys/netinet6/nd6_rtr.c 29 May 2005 21:43:51 -0000 1.52 +++ sys/netinet6/nd6_rtr.c 22 Nov 2005 13:43:36 -0000 @@ -246,7 +246,7 @@ nd6_ra_input(m, off, icmp6len) drtr.rtaddr = saddr6; drtr.flags = nd_ra->nd_ra_flags_reserved; drtr.rtlifetime = ntohs(nd_ra->nd_ra_router_lifetime); - drtr.expire = time.tv_sec + drtr.rtlifetime; + drtr.expire = time_second + drtr.rtlifetime; drtr.ifp = ifp; /* unspecified or not? (RFC 2461 6.3.4) */ if (advreachable) { @@ -330,7 +330,7 @@ nd6_ra_input(m, off, icmp6len) pr.ndpr_plen = pi->nd_opt_pi_prefix_len; pr.ndpr_vltime = ntohl(pi->nd_opt_pi_valid_time); pr.ndpr_pltime = ntohl(pi->nd_opt_pi_preferred_time); - pr.ndpr_lastupdate = time.tv_sec; + pr.ndpr_lastupdate = time_second; if (in6_init_prefix_ltimes(&pr)) continue; /* prefix lifetime init failed */ @@ -1162,7 +1162,7 @@ prelist_update(new, dr, m) lt6_tmp = ifa6->ia6_lifetime; if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME) storedlifetime = ND6_INFINITE_LIFETIME; - else if (time.tv_sec - ifa6->ia6_updatetime > + else if (time_second - ifa6->ia6_updatetime > lt6_tmp.ia6t_vltime) { /* * The case of "invalid" address. We should usually @@ -1171,7 +1171,7 @@ prelist_update(new, dr, m) storedlifetime = 0; } else storedlifetime = lt6_tmp.ia6t_vltime - - (time.tv_sec - ifa6->ia6_updatetime); + (time_second - ifa6->ia6_updatetime); if (TWOHOUR < new->ndpr_vltime || storedlifetime < new->ndpr_vltime) { lt6_tmp.ia6t_vltime = new->ndpr_vltime; @@ -1202,7 +1202,7 @@ prelist_update(new, dr, m) in6_init_address_ltimes(pr, <6_tmp); ifa6->ia6_lifetime = lt6_tmp; - ifa6->ia6_updatetime = time.tv_sec; + ifa6->ia6_updatetime = time_second; } if (ia6_match == NULL && new->ndpr_vltime) { /* @@ -1752,11 +1752,11 @@ in6_init_prefix_ltimes(struct nd_prefix if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME) ndpr->ndpr_preferred = 0; else - ndpr->ndpr_preferred = time.tv_sec + ndpr->ndpr_pltime; + ndpr->ndpr_preferred = time_second + ndpr->ndpr_pltime; if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME) ndpr->ndpr_expire = 0; else - ndpr->ndpr_expire = time.tv_sec + ndpr->ndpr_vltime; + ndpr->ndpr_expire = time_second + ndpr->ndpr_vltime; return 0; } @@ -1770,7 +1770,7 @@ in6_init_address_ltimes(struct nd_prefix if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME) lt6->ia6t_expire = 0; else { - lt6->ia6t_expire = time.tv_sec; + lt6->ia6t_expire = time_second; lt6->ia6t_expire += lt6->ia6t_vltime; } @@ -1778,7 +1778,7 @@ in6_init_address_ltimes(struct nd_prefix if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME) lt6->ia6t_preferred = 0; else { - lt6->ia6t_preferred = time.tv_sec; + lt6->ia6t_preferred = time_second; lt6->ia6t_preferred += lt6->ia6t_pltime; } } Index: sys/netipsec/ipsec_osdep.h =================================================================== RCS file: /cvsroot/src/sys/netipsec/ipsec_osdep.h,v retrieving revision 1.13 diff -d -p -u -r1.13 ipsec_osdep.h --- sys/netipsec/ipsec_osdep.h 18 Aug 2005 00:30:59 -0000 1.13 +++ sys/netipsec/ipsec_osdep.h 22 Nov 2005 13:43:37 -0000 @@ -189,9 +189,10 @@ if_handoff(struct ifqueue *ifq, struct m /* * 7. Elapsed Time: time_second as time in seconds. * Original FreeBSD fast-ipsec code references a FreeBSD kernel global, - * time_second(). NetBSD: kludge #define to use time_mono_time.tv_sec. + * time_second(). + * (Non-timecounter) NetBSD: kludge #define to use time_mono_time.tv_sec. */ -#ifdef __NetBSD__ +#if defined(__NetBSD__) && !defined(__HAVE_TIMECOUNTER) #include #define time_second mono_time.tv_sec #endif /* __NetBSD__ */ Index: sys/netiso/iso_snpac.c =================================================================== RCS file: /cvsroot/src/sys/netiso/iso_snpac.c,v retrieving revision 1.33 diff -d -p -u -r1.33 iso_snpac.c --- sys/netiso/iso_snpac.c 31 May 2005 01:37:06 -0000 1.33 +++ sys/netiso/iso_snpac.c 22 Nov 2005 13:43:38 -0000 @@ -473,7 +473,7 @@ add: } if ((lc = (struct llinfo_llc *) rt->rt_llinfo) == 0) panic("snpac_rtrequest"); - rt->rt_rmx.rmx_expire = ht + time.tv_sec; + rt->rt_rmx.rmx_expire = ht + time_second; lc->lc_flags = SNPA_VALID | type; if ((type & SNPA_IS) && !(iso_systype & SNPA_IS)) snpac_logdefis(rt); @@ -624,7 +624,8 @@ snpac_age(void *v) nlc = lc->lc_list.le_next; if (lc->lc_flags & SNPA_VALID) { rt = lc->lc_rt; - if (rt->rt_rmx.rmx_expire && rt->rt_rmx.rmx_expire < time.tv_sec) + if (rt->rt_rmx.rmx_expire && + rt->rt_rmx.rmx_expire < time_second) snpac_free(lc); } } Index: sys/netiso/tp_input.c =================================================================== RCS file: /cvsroot/src/sys/netiso/tp_input.c,v retrieving revision 1.22 diff -d -p -u -r1.22 tp_input.c --- sys/netiso/tp_input.c 29 May 2005 21:27:45 -0000 1.22 +++ sys/netiso/tp_input.c 22 Nov 2005 13:43:42 -0000 @@ -1443,7 +1443,7 @@ again: #ifdef ARGO_DEBUG if (argo_debug[D_DROP]) { - if (time.tv_usec & 0x4 && + if (time_second & 0x4 && hdr->tpdu_DTseq & 0x1) { IncStat(ts_ydebug); goto discard; Index: sys/netiso/tp_iso.c =================================================================== RCS file: /cvsroot/src/sys/netiso/tp_iso.c,v retrieving revision 1.19 diff -d -p -u -r1.19 tp_iso.c --- sys/netiso/tp_iso.c 26 Feb 2005 22:39:49 -0000 1.19 +++ sys/netiso/tp_iso.c 22 Nov 2005 13:43:43 -0000 @@ -548,7 +548,10 @@ tpclnp_input(struct mbuf *m, ...) #ifdef ARGO_DEBUG if (argo_debug[D_QUENCH]) {{ - if (time.tv_usec & 0x4 && time.tv_usec & 0x40) { + struct timeval now; + + getmicrotime(&now); + if (now.tv_usec & 0x4 && now.tv_usec & 0x40) { printf("tpclnp_input: FAKING %s\n", tp_stat.ts_pkt_rcvd & 0x1 ? "QUENCH" : "QUENCH2"); if (tp_stat.ts_pkt_rcvd & 0x1) Index: sys/netiso/tp_meas.c =================================================================== RCS file: /cvsroot/src/sys/netiso/tp_meas.c,v retrieving revision 1.11 diff -d -p -u -r1.11 tp_meas.c --- sys/netiso/tp_meas.c 19 Apr 2004 05:16:46 -0000 1.11 +++ sys/netiso/tp_meas.c 22 Nov 2005 13:43:43 -0000 @@ -71,8 +71,6 @@ __KERNEL_RCSID(0, "$NetBSD: tp_meas.c,v #include #include -extern struct timeval time; - #ifdef TP_PERF_MEAS int tp_Measn = 0; struct tp_Meas tp_Meas[TPMEASN]; @@ -112,8 +110,7 @@ Tpmeas(u_int ref, u_int kind, struct tim if (kind == TPtime_from_ll) bcopy((caddr_t) timev, (caddr_t) & tpm->tpm_time, sizeof(struct timeval)); else - bcopy((caddr_t) & time, - (caddr_t) & tpm->tpm_time, sizeof(struct timeval)); + getmicrotime(& tpm->tpm_time); tpm->tpm_seq = seq; tpm->tpm_window = win; tpm->tpm_size = size; Index: sys/netiso/tp_pcb.c =================================================================== RCS file: /cvsroot/src/sys/netiso/tp_pcb.c,v retrieving revision 1.26 diff -d -p -u -r1.26 tp_pcb.c --- sys/netiso/tp_pcb.c 19 Apr 2004 05:16:46 -0000 1.26 +++ sys/netiso/tp_pcb.c 22 Nov 2005 13:43:44 -0000 @@ -372,13 +372,15 @@ tp_soisdisconnecting(struct socket *so) if (DOPERF(sototpcb(so))) { struct tp_pcb *tpcb = sototpcb(so); u_int fsufx, lsufx; + struct timeval now; bcopy((caddr_t) tpcb->tp_fsuffix, (caddr_t) &fsufx, sizeof(u_int)); bcopy((caddr_t) tpcb->tp_lsuffix, (caddr_t) &lsufx, sizeof(u_int)); - tpmeas(tpcb->tp_lref, TPtime_close, &time, fsufx, lsufx, + getmicrotime(&now); + tpmeas(tpcb->tp_lref, TPtime_close, &now, fsufx, lsufx, tpcb->tp_fref); tpcb->tp_perf_on = 0; /* turn perf off */ } @@ -420,6 +422,7 @@ tp_soisdisconnected(struct tp_pcb *tpcb) if (DOPERF(tpcb)) { struct tp_pcb *ttpcb = sototpcb(so); u_int fsufx, lsufx; + struct timeval now; /* CHOKE */ bcopy((caddr_t) ttpcb->tp_fsuffix, (caddr_t) &fsufx, @@ -427,8 +430,9 @@ tp_soisdisconnected(struct tp_pcb *tpcb) bcopy((caddr_t) ttpcb->tp_lsuffix, (caddr_t) &lsufx, sizeof(u_int)); + getmicrotime(&now); tpmeas(ttpcb->tp_lref, TPtime_close, - &time, &lsufx, &fsufx, ttpcb->tp_fref); + &now, &lsufx, &fsufx, ttpcb->tp_fref); tpcb->tp_perf_on = 0; /* turn perf off */ } #endif Index: sys/netiso/tp_usrreq.c =================================================================== RCS file: /cvsroot/src/sys/netiso/tp_usrreq.c,v retrieving revision 1.26 diff -d -p -u -r1.26 tp_usrreq.c --- sys/netiso/tp_usrreq.c 29 May 2005 21:27:45 -0000 1.26 +++ sys/netiso/tp_usrreq.c 22 Nov 2005 13:43:46 -0000 @@ -527,12 +527,15 @@ tp_usrreq(struct socket *so, int req, st #ifdef TP_PERF_MEAS if (DOPERF(tpcb)) { u_int lsufx, fsufx; + struct timeval now; + lsufx = *(u_short *) (tpcb->tp_lsuffix); fsufx = *(u_short *) (tpcb->tp_fsuffix); + getmicrotime(&now); tpmeas(tpcb->tp_lref, TPtime_open | (tpcb->tp_xtd_format << 4), - &time, lsufx, fsufx, tpcb->tp_fref); + &now, lsufx, fsufx, tpcb->tp_fref); } #endif break; @@ -557,9 +560,12 @@ tp_usrreq(struct socket *so, int req, st #ifdef TP_PERF_MEAS if (DOPERF(tpcb)) { u_int lsufx, fsufx; + struct timeval now; + lsufx = *(u_short *) (tpcb->tp_lsuffix); fsufx = *(u_short *) (tpcb->tp_fsuffix); + getmicrotime(&now); tpmeas(tpcb->tp_lref, TPtime_open, &time, lsufx, fsufx, tpcb->tp_fref); } Index: sys/netkey/key.c =================================================================== RCS file: /cvsroot/src/sys/netkey/key.c,v retrieving revision 1.136 diff -d -p -u -r1.136 key.c --- sys/netkey/key.c 3 Oct 2005 13:14:38 -0000 1.136 +++ sys/netkey/key.c 22 Nov 2005 13:43:57 -0000 @@ -536,7 +536,7 @@ found: KEY_CHKSPDIR(sp->dir, dir, "key_allocsp"); /* found a SPD entry */ - sp->lastused = time.tv_sec; + sp->lastused = time_second; sp->refcnt++; splx(s); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, @@ -1851,8 +1851,8 @@ key_spdadd(so, m, mhp) } } - newsp->created = time.tv_sec; - newsp->lastused = time.tv_sec; + newsp->created = time_second; + newsp->lastused = time_second; newsp->lifetime = lft ? lft->sadb_lifetime_addtime : 0; newsp->validtime = lft ? lft->sadb_lifetime_usetime : 0; @@ -1866,7 +1866,7 @@ key_spdadd(so, m, mhp) struct secspacq *spacq; if ((spacq = key_getspacq(&spidx)) != NULL) { /* reset counter in order to deletion by timehandler. */ - spacq->created = time.tv_sec; + spacq->created = time_second; spacq->count = 0; } } @@ -2916,7 +2916,7 @@ key_newsav(m, mhp, sah, errp) } /* reset created */ - newsav->created = time.tv_sec; + newsav->created = time_second; newsav->pid = mhp->msg->sadb_msg_pid; @@ -3226,7 +3226,7 @@ key_setsaval(sav, m, mhp) } /* reset created */ - sav->created = time.tv_sec; + sav->created = time_second; /* make lifetime for CURRENT */ KMALLOC(sav->lft_c, struct sadb_lifetime *, @@ -3242,7 +3242,7 @@ key_setsaval(sav, m, mhp) sav->lft_c->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT; sav->lft_c->sadb_lifetime_allocations = 0; sav->lft_c->sadb_lifetime_bytes = 0; - sav->lft_c->sadb_lifetime_addtime = time.tv_sec; + sav->lft_c->sadb_lifetime_addtime = time_second; sav->lft_c->sadb_lifetime_usetime = 0; /* lifetimes for HARD and SOFT */ @@ -4653,7 +4653,7 @@ key_timehandler(arg) int s; struct timeval tv; - tv = time; + getmicrotime(&tv); s = splsoftnet(); /*called from softclock()*/ @@ -5112,7 +5112,7 @@ key_getspi(so, m, mhp) struct secacq *acq; if ((acq = key_getacqbyseq(mhp->msg->sadb_msg_seq)) != NULL) { /* reset counter in order to deletion by timehandler. */ - acq->created = time.tv_sec; + acq->created = time_second; acq->count = 0; } } @@ -6622,7 +6622,7 @@ key_newacq(saidx) /* copy secindex */ bcopy(saidx, &newacq->saidx, sizeof(newacq->saidx)); newacq->seq = (acq_seq == ~0 ? 1 : ++acq_seq); - newacq->created = time.tv_sec; + newacq->created = time_second; newacq->count = 1; return newacq; @@ -6676,7 +6676,7 @@ key_newspacq(spidx) /* copy secindex */ bcopy(spidx, &acq->spidx, sizeof(acq->spidx)); - acq->created = time.tv_sec; + acq->created = time_second; acq->count = 0; return acq; @@ -6756,7 +6756,7 @@ key_acquire2(so, m, mhp) } /* reset acq counter in order to deletion by timehander. */ - acq->created = time.tv_sec; + acq->created = time_second; acq->count = 0; #endif m_freem(m); @@ -8199,7 +8199,7 @@ key_sa_recordxfer(sav, m) * <-----> SOFT */ { - sav->lft_c->sadb_lifetime_usetime = time.tv_sec; + sav->lft_c->sadb_lifetime_usetime = time_second; /* XXX check for expires? */ } Index: sys/netns/ns_error.c =================================================================== RCS file: /cvsroot/src/sys/netns/ns_error.c,v retrieving revision 1.17 diff -d -p -u -r1.17 ns_error.c --- sys/netns/ns_error.c 26 Feb 2005 22:39:50 -0000 1.17 +++ sys/netns/ns_error.c 22 Nov 2005 13:43:57 -0000 @@ -300,11 +300,10 @@ freeit: u_int32_t nstime(void) { - int s = splclock(); + struct timeval now; u_int32_t t; - t = (time.tv_sec % (24*60*60)) * 1000 + time.tv_usec / 1000; - splx(s); + t = (now.tv_sec % (24*60*60)) * 1000 + now.tv_usec / 1000; return (htonl(t)); } #endif Index: sys/netns/ns_input.c =================================================================== RCS file: /cvsroot/src/sys/netns/ns_input.c,v retrieving revision 1.22 diff -d -p -u -r1.22 ns_input.c --- sys/netns/ns_input.c 26 Feb 2005 22:39:50 -0000 1.22 +++ sys/netns/ns_input.c 22 Nov 2005 13:43:58 -0000 @@ -88,6 +88,7 @@ long ns_pexseq; void ns_init(void) { + struct timeval now; ns_broadhost = * (union ns_host *) allones; ns_broadnet = * (union ns_net *) allones; @@ -95,7 +96,8 @@ ns_init(void) nsrawpcb.nsp_next = nsrawpcb.nsp_prev = &nsrawpcb; nsintrq.ifq_maxlen = nsqmaxlen; TAILQ_INIT(&ns_ifaddr); - ns_pexseq = time.tv_usec; + getmicrotime(&now); + ns_pexseq = now.tv_usec; ns_netmask.sns_len = 6; ns_netmask.sns_addr.x_net = ns_broadnet; ns_hostmask.sns_len = 12; Index: sys/netsmb/smb_trantcp.c =================================================================== RCS file: /cvsroot/src/sys/netsmb/smb_trantcp.c,v retrieving revision 1.18 diff -d -p -u -r1.18 smb_trantcp.c --- sys/netsmb/smb_trantcp.c 26 Feb 2005 22:39:50 -0000 1.18 +++ sys/netsmb/smb_trantcp.c 22 Nov 2005 13:43:58 -0000 @@ -163,10 +163,7 @@ nbssn_rselect(struct nbpcb *nbp, const s atv = *tv; if (itimerfix(&atv)) return (EINVAL); - s = splclock(); - timeradd(&atv, &time, &atv); - splx(s); - timo = hzto(&atv); + timo = tvtohz(&atv); if (timo <= 0) return (EWOULDBLOCK); } else Index: sys/nfs/nfs.h =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs.h,v retrieving revision 1.51 diff -d -p -u -r1.51 nfs.h --- sys/nfs/nfs.h 25 Sep 2005 21:57:40 -0000 1.51 +++ sys/nfs/nfs.h 22 Nov 2005 13:43:59 -0000 @@ -160,9 +160,9 @@ extern int nfs_niothreads; #define NFS_ATTRTIMEO(nmp, np) \ ((nmp->nm_flag & NFSMNT_NOAC) ? 0 : \ ((((np)->n_flag & NMODIFIED) || \ - (time.tv_sec - (np)->n_mtime.tv_sec) / 10 < NFS_MINATTRTIMO) ? NFS_MINATTRTIMO : \ - ((time.tv_sec - (np)->n_mtime.tv_sec) / 10 > NFS_MAXATTRTIMO ? NFS_MAXATTRTIMO : \ - (time.tv_sec - (np)->n_mtime.tv_sec) / 10))) + (time_second - (np)->n_mtime.tv_sec) / 10 < NFS_MINATTRTIMO) ? NFS_MINATTRTIMO : \ + ((time_second - (np)->n_mtime.tv_sec) / 10 > NFS_MAXATTRTIMO ? NFS_MAXATTRTIMO : \ + (time_second - (np)->n_mtime.tv_sec) / 10))) /* * Export arguments for local filesystem mount calls. Index: sys/nfs/nfs_nqlease.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_nqlease.c,v retrieving revision 1.56 diff -d -p -u -r1.56 nfs_nqlease.c --- sys/nfs/nfs_nqlease.c 22 May 2004 22:52:15 -0000 1.56 +++ sys/nfs/nfs_nqlease.c 22 Nov 2005 13:44:01 -0000 @@ -374,7 +374,7 @@ nqsrv_instimeq(lp, duration) struct nqlease *tlp; time_t newexpiry; - newexpiry = time.tv_sec + duration + nqsrv_clockskew; + newexpiry = time_second + duration + nqsrv_clockskew; if (lp->lc_expiry == newexpiry) return; if (CIRCLEQ_NEXT(lp, lc_timer) != 0) @@ -586,7 +586,7 @@ nqsrv_waitfor_expiry(lp) int len, ok; tryagain: - if (time.tv_sec > lp->lc_expiry) + if (time_second > lp->lc_expiry) return; lph = &lp->lc_host; lphnext = lp->lc_morehosts; @@ -632,7 +632,7 @@ nqnfs_serverd() for (lp = CIRCLEQ_FIRST(&nqtimerhead); lp != (void *)&nqtimerhead; lp = nextlp) { - if (lp->lc_expiry >= time.tv_sec) + if (lp->lc_expiry >= time_second) break; nextlp = CIRCLEQ_NEXT(lp, lc_timer); if (lp->lc_flag & LC_EXPIREDWANTED) { @@ -870,12 +870,12 @@ nqnfs_getlease(vp, rwflag, cred, p) nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(rwflag); *tl = txdr_unsigned(nmp->nm_leaseterm); - reqtime = time.tv_sec; + reqtime = time_second; nfsm_request(np, NQNFSPROC_GETLEASE, p, cred); nfsm_dissect(tl, u_int32_t *, 4 * NFSX_UNSIGNED); cachable = fxdr_unsigned(int, *tl++); reqtime += fxdr_unsigned(int, *tl++); - if (reqtime > time.tv_sec) { + if (reqtime > time_second) { frev = fxdr_hyper(tl); nqnfs_clientlease(nmp, np, rwflag, cachable, reqtime, frev); nfsm_loadattr(vp, (struct vattr *)0, 0); @@ -1093,7 +1093,7 @@ nqnfs_clientd(nmp, cred, ncd, flag, argp while (np != (void *)&nmp->nm_timerhead && (nmp->nm_iflag & NFSMNT_DISMINPROG) == 0) { vp = NFSTOV(np); - if (np->n_expiry < time.tv_sec) { + if (np->n_expiry < time_second) { if (vget(vp, LK_EXCLUSIVE) == 0) { nmp->nm_inprog = vp; CIRCLEQ_REMOVE(&nmp->nm_timerhead, np, n_timer); @@ -1117,7 +1117,7 @@ nqnfs_clientd(nmp, cred, ncd, flag, argp vput(vp); nmp->nm_inprog = NULLVP; } - } else if ((np->n_expiry - NQ_RENEWAL) < time.tv_sec) { + } else if ((np->n_expiry - NQ_RENEWAL) < time_second) { if ((np->n_flag & (NQNFSWRITE | NQNFSNONCACHE)) == NQNFSWRITE && !LIST_EMPTY(&vp->v_dirtyblkhd) && Index: sys/nfs/nfs_serv.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_serv.c,v retrieving revision 1.98 diff -d -p -u -r1.98 nfs_serv.c --- sys/nfs/nfs_serv.c 6 Oct 2005 10:23:01 -0000 1.98 +++ sys/nfs/nfs_serv.c 22 Nov 2005 13:44:08 -0000 @@ -1002,6 +1002,7 @@ nfsrv_writegather(ndp, slp, procp, mrq) struct proc *procp; struct mbuf **mrq; { + struct timeval now; struct iovec *ivp; struct mbuf *mp; struct nfsrv_descript *wp, *nfsd, *owp, *swp; @@ -1035,7 +1036,8 @@ nfsrv_writegather(ndp, slp, procp, mrq) LIST_INIT(&nfsd->nd_coalesce); nfsd->nd_mreq = NULL; nfsd->nd_stable = NFSV3WRITE_FILESYNC; - cur_usec = (u_quad_t)time.tv_sec * 1000000 + (u_quad_t)time.tv_usec; + getmicrotime(&now); + cur_usec = (u_quad_t)now.tv_sec * 1000000 + (u_quad_t)now.tv_usec; nfsd->nd_time = cur_usec + nfsrvw_procrastinate; /* @@ -1147,7 +1149,8 @@ nfsmout: * and generate the associated reply mbuf list(s). */ loop1: - cur_usec = (u_quad_t)time.tv_sec * 1000000 + (u_quad_t)time.tv_usec; + getmicrotime(&now); + cur_usec = (u_quad_t)now.tv_sec * 1000000 + (u_quad_t)now.tv_usec; s = splsoftclock(); for (nfsd = LIST_FIRST(&slp->ns_tq); nfsd; nfsd = owp) { owp = LIST_NEXT(nfsd, nd_tq); Index: sys/nfs/nfs_socket.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_socket.c,v retrieving revision 1.118 diff -d -p -u -r1.118 nfs_socket.c --- sys/nfs/nfs_socket.c 21 Nov 2005 09:39:02 -0000 1.118 +++ sys/nfs/nfs_socket.c 22 Nov 2005 13:44:11 -0000 @@ -886,7 +886,7 @@ nfsmout: rt->srtt = nmp->nm_srtt[proct[rep->r_procnum] - 1]; rt->sdrtt = nmp->nm_sdrtt[proct[rep->r_procnum] - 1]; rt->fsid = nmp->nm_mountp->mnt_stat.f_fsidx; - rt->tstamp = time; + getmicrotime(&rt->tstamp); if (rep->r_flags & R_TIMING) rt->rtt = rep->r_rtt; else @@ -1124,7 +1124,7 @@ tryagain: TAILQ_INSERT_TAIL(&nfs_reqq, rep, r_chain); /* Get send time for nqnfs */ - reqtime = time.tv_sec; + reqtime = time_second; /* * If backing off another request or avoiding congestion, don't @@ -1361,8 +1361,8 @@ tryagain: break; m_freem(mrep); error = 0; - waituntil = time.tv_sec + trylater_delay; - while (time.tv_sec < waituntil) + waituntil = time_second + trylater_delay; + while (time_second < waituntil) (void) tsleep((caddr_t)&lbolt, PSOCK, "nqnfstry", 0); trylater_delay *= NFS_TRYLATERDELMUL; @@ -1417,7 +1417,7 @@ tryagain: nfsm_dissect(tl, u_int32_t *, 4*NFSX_UNSIGNED); cachable = fxdr_unsigned(int, *tl++); reqtime += fxdr_unsigned(int, *tl++); - if (reqtime > time.tv_sec) { + if (reqtime > time_second) { frev = fxdr_hyper(tl); nqnfs_clientlease(nmp, np, nqlflag, cachable, reqtime, frev); @@ -1615,6 +1615,7 @@ nfs_timer(arg) int timeo; int s, error; #ifdef NFSSERVER + struct timeval tv; struct nfssvc_sock *slp; static long lasttime = 0; u_quad_t cur_usec; @@ -1718,8 +1719,8 @@ nfs_timer(arg) /* * Call the nqnfs server timer once a second to handle leases. */ - if (lasttime != time.tv_sec) { - lasttime = time.tv_sec; + if (lasttime != time_second) { + lasttime = time_second; nqnfs_serverd(); } @@ -1727,7 +1728,8 @@ nfs_timer(arg) * Scan the write gathering queues for writes that need to be * completed now. */ - cur_usec = (u_quad_t)time.tv_sec * 1000000 + (u_quad_t)time.tv_usec; + getmicrotime(&tv); + cur_usec = (u_quad_t)tv.tv_sec * 1000000 + (u_quad_t)tv.tv_usec; TAILQ_FOREACH(slp, &nfssvc_sockhead, ns_chain) { if (LIST_FIRST(&slp->ns_tq) && LIST_FIRST(&slp->ns_tq)->nd_time <= cur_usec) @@ -2112,7 +2114,7 @@ nfs_getreq(nd, nfsd, has_header) tvout.tv_sec = fxdr_unsigned(long, tvout.tv_sec); tvout.tv_usec = fxdr_unsigned(long, tvout.tv_usec); - if (nuidp->nu_expire < time.tv_sec || + if (nuidp->nu_expire < time_second || nuidp->nu_timestamp.tv_sec > tvout.tv_sec || (nuidp->nu_timestamp.tv_sec == tvout.tv_sec && nuidp->nu_timestamp.tv_usec > tvout.tv_usec)) { Index: sys/nfs/nfs_subs.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_subs.c,v retrieving revision 1.154 diff -d -p -u -r1.154 nfs_subs.c --- sys/nfs/nfs_subs.c 22 Nov 2005 04:44:29 -0000 1.154 +++ sys/nfs/nfs_subs.c 22 Nov 2005 13:44:16 -0000 @@ -1839,7 +1839,7 @@ nfs_loadattrcache(vpp, fp, vaper, flags) } } } - np->n_attrstamp = mono_time.tv_sec; + np->n_attrstamp = time_second; if (vaper != NULL) { memcpy((caddr_t)vaper, (caddr_t)vap, sizeof(*vap)); if (np->n_flag & NCHG) { @@ -1867,7 +1867,7 @@ nfs_getattrcache(vp, vaper) struct vattr *vap; if (np->n_attrstamp == 0 || - (mono_time.tv_sec - np->n_attrstamp) >= NFS_ATTRTIMEO(nmp, np)) { + (time_second - np->n_attrstamp) >= NFS_ATTRTIMEO(nmp, np)) { nfsstats.attrcache_misses++; return (ENOENT); } @@ -1934,7 +1934,7 @@ nfs_check_wccdata(struct nfsnode *np, co if (docheck) { struct vnode *vp = NFSTOV(np); struct nfsmount *nmp; - long now = mono_time.tv_sec; + long now = time_second; #if defined(DEBUG) const char *reason = NULL; /* XXX: gcc */ #endif Index: sys/nfs/nfs_syscalls.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_syscalls.c,v retrieving revision 1.82 diff -d -p -u -r1.82 nfs_syscalls.c --- sys/nfs/nfs_syscalls.c 23 Sep 2005 12:10:33 -0000 1.82 +++ sys/nfs/nfs_syscalls.c 22 Nov 2005 13:44:18 -0000 @@ -330,7 +330,7 @@ sys_nfssvc(l, v, retval) nuidp->nu_cr.cr_ngroups = NGROUPS; nuidp->nu_cr.cr_ref = 1; nuidp->nu_timestamp = nsd->nsd_timestamp; - nuidp->nu_expire = time.tv_sec + nsd->nsd_ttl; + nuidp->nu_expire = time_second + nsd->nsd_ttl; /* * and save the session key in nu_key. */ @@ -518,16 +518,16 @@ nfssvc_nfsd(nsd, argp, l) caddr_t argp; struct lwp *l; { + struct timeval tv; struct mbuf *m; - int siz; struct nfssvc_sock *slp; struct socket *so; int *solockp; struct nfsd *nfsd = nsd->nsd_nfsd; struct nfsrv_descript *nd = NULL; struct mbuf *mreq; - int error = 0, cacherep, s, sotype, writes_todo; u_quad_t cur_usec; + int error = 0, cacherep, s, siz, sotype, writes_todo; struct proc *p = l->l_proc; #ifndef nolint @@ -605,8 +605,9 @@ nfssvc_nfsd(nsd, argp, l) nfs_sndunlock(&slp->ns_solock); } error = nfsrv_dorec(slp, nfsd, &nd); - cur_usec = (u_quad_t)time.tv_sec * 1000000 + - (u_quad_t)time.tv_usec; + getmicrotime(&tv); + cur_usec = (u_quad_t)tv.tv_sec * 1000000 + + (u_quad_t)tv.tv_usec; if (error && LIST_FIRST(&slp->ns_tq) && LIST_FIRST(&slp->ns_tq)->nd_time <= cur_usec) { @@ -639,7 +640,7 @@ nfssvc_nfsd(nsd, argp, l) else solockp = (int *)0; if (nd) { - nd->nd_starttime = time; + getmicrotime(&nd->nd_starttime); if (nd->nd_nam2) nd->nd_nam = nd->nd_nam2; else @@ -670,10 +671,10 @@ nfssvc_nfsd(nsd, argp, l) * Check for just starting up for NQNFS and send * fake "try again later" replies to the NQNFS clients. */ - if (notstarted && nqnfsstarttime <= time.tv_sec) { + if (notstarted && nqnfsstarttime <= time_second) { if (modify_flag) { nqnfsstarttime = - time.tv_sec + nqsrv_writeslack; + time_second + nqsrv_writeslack; modify_flag = 0; } else notstarted = 0; @@ -832,8 +833,9 @@ nfssvc_nfsd(nsd, argp, l) * Check to see if there are outstanding writes that * need to be serviced. */ - cur_usec = (u_quad_t)time.tv_sec * 1000000 + - (u_quad_t)time.tv_usec; + getmicrotime(&tv); + cur_usec = (u_quad_t)tv.tv_sec * 1000000 + + (u_quad_t)tv.tv_usec; s = splsoftclock(); if (LIST_FIRST(&slp->ns_tq) && LIST_FIRST(&slp->ns_tq)->nd_time <= cur_usec) { @@ -1023,6 +1025,7 @@ nfsd_rt(sotype, nd, cacherep) struct nfsrv_descript *nd; int cacherep; { + struct timeval tv; struct drt *rt; rt = &nfsdrt.drt[nfsdrt.pos]; @@ -1043,9 +1046,10 @@ nfsd_rt(sotype, nd, cacherep) rt->ipadr = mtod(nd->nd_nam, struct sockaddr_in *)->sin_addr.s_addr; else rt->ipadr = INADDR_ANY; - rt->resptime = ((time.tv_sec - nd->nd_starttime.tv_sec) * 1000000) + - (time.tv_usec - nd->nd_starttime.tv_usec); - rt->tstamp = time; + getmicrotime(&tv); + rt->resptime = ((tv.tv_sec - nd->nd_starttime.tv_sec) * 1000000) + + (tv.tv_usec - nd->nd_starttime.tv_usec); + rt->tstamp = tv; nfsdrt.pos = (nfsdrt.pos + 1) % NFSRTTLOGSIZ; } #endif /* NFSSERVER */ @@ -1271,9 +1275,9 @@ nfs_getnickauth(nmp, cred, auth_str, aut char *verf_str; int verf_len; { + struct timeval ktvin, ktvout, tv; struct nfsuid *nuidp; u_int32_t *nickp, *verfp; - struct timeval ktvin, ktvout; #ifdef DIAGNOSTIC if (verf_len < (4 * NFSX_UNSIGNED)) @@ -1283,7 +1287,7 @@ nfs_getnickauth(nmp, cred, auth_str, aut if (nuidp->nu_cr.cr_uid == cred->cr_uid) break; } - if (!nuidp || nuidp->nu_expire < time.tv_sec) + if (!nuidp || nuidp->nu_expire < time_second) return (EACCES); /* @@ -1303,10 +1307,11 @@ nfs_getnickauth(nmp, cred, auth_str, aut */ verfp = (u_int32_t *)verf_str; *verfp++ = txdr_unsigned(RPCAKN_NICKNAME); - if (time.tv_sec > nuidp->nu_timestamp.tv_sec || - (time.tv_sec == nuidp->nu_timestamp.tv_sec && - time.tv_usec > nuidp->nu_timestamp.tv_usec)) - nuidp->nu_timestamp = time; + getmicrotime(&tv); + if (tv.tv_sec > nuidp->nu_timestamp.tv_sec || + (tv.tv_sec == nuidp->nu_timestamp.tv_sec && + tv.tv_usec > nuidp->nu_timestamp.tv_usec)) + nuidp->nu_timestamp = tv; else nuidp->nu_timestamp.tv_usec++; ktvin.tv_sec = txdr_unsigned(nuidp->nu_timestamp.tv_sec); @@ -1362,7 +1367,7 @@ nfs_savenickauth(nmp, cred, len, key, md #endif ktvout.tv_sec = fxdr_unsigned(long, ktvout.tv_sec); ktvout.tv_usec = fxdr_unsigned(long, ktvout.tv_usec); - deltasec = time.tv_sec - ktvout.tv_sec; + deltasec = time_second - ktvout.tv_sec; if (deltasec < 0) deltasec = -deltasec; /* @@ -1382,7 +1387,7 @@ nfs_savenickauth(nmp, cred, len, key, md } nuidp->nu_flag = 0; nuidp->nu_cr.cr_uid = cred->cr_uid; - nuidp->nu_expire = time.tv_sec + NFS_KERBTTL; + nuidp->nu_expire = time_second + NFS_KERBTTL; nuidp->nu_timestamp = ktvout; nuidp->nu_nickname = nick; memcpy(nuidp->nu_key, key, sizeof (NFSKERBKEY_T)); Index: sys/nfs/nfs_vfsops.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_vfsops.c,v retrieving revision 1.150 diff -d -p -u -r1.150 nfs_vfsops.c --- sys/nfs/nfs_vfsops.c 23 Sep 2005 12:10:33 -0000 1.150 +++ sys/nfs/nfs_vfsops.c 22 Nov 2005 13:44:21 -0000 @@ -58,6 +58,7 @@ __KERNEL_RCSID(0, "$NetBSD: nfs_vfsops.c #include #include #include +#include #include #include @@ -299,6 +300,9 @@ nfs_fsinfo(nmp, vp, cred, p) int nfs_mountroot() { +#ifdef __HAVE_TIMECOUNTER + struct timespec ts; +#endif struct nfs_diskless *nd; struct vattr attr; struct mount *mp; @@ -315,11 +319,18 @@ nfs_mountroot() /* * XXX time must be non-zero when we init the interface or else * the arp code will wedge. [Fixed now in if_ether.c] - * However, the NFS attribute cache gives false "hits" when - * time.tv_sec < NFS_ATTRTIMEO(nmp, np) so keep this in for now. + * However, the NFS attribute cache gives false "hits" when the + * current time < NFS_ATTRTIMEO(nmp, np) so keep this in for now. */ - if (time.tv_sec < NFS_MAXATTRTIMO) + if (time_second < NFS_MAXATTRTIMO) { +#ifdef __HAVE_TIMECOUNTER + ts.tv_sec = NFS_MAXATTRTIMO; + ts.tv_nsec = 0; + tc_setclock(&ts); +#else /* !__HAVE_TIMECOUNTER */ time.tv_sec = NFS_MAXATTRTIMO; +#endif /* !__HAVE_TIMECOUNTER */ + } /* * Call nfs_boot_init() to fill in the nfs_diskless struct. Index: sys/nfs/nfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_vnops.c,v retrieving revision 1.229 diff -d -p -u -r1.229 nfs_vnops.c --- sys/nfs/nfs_vnops.c 5 Nov 2005 19:21:14 -0000 1.229 +++ sys/nfs/nfs_vnops.c 22 Nov 2005 13:44:24 -0000 @@ -326,7 +326,7 @@ nfs_access(v) struct nfsmount *nmp = VFSTONFS(vp->v_mount); cachevalid = (np->n_accstamp != -1 && - (mono_time.tv_sec - np->n_accstamp) < NFS_ATTRTIMEO(nmp, np) && + (time_uptime - np->n_accstamp) < NFS_ATTRTIMEO(nmp, np) && np->n_accuid == ap->a_cred->cr_uid); /* @@ -420,7 +420,7 @@ nfs_access(v) else if ((np->n_accmode & ap->a_mode) == ap->a_mode) np->n_accmode = ap->a_mode; } else { - np->n_accstamp = mono_time.tv_sec; + np->n_accstamp = time_uptime; np->n_accuid = ap->a_cred->cr_uid; np->n_accmode = ap->a_mode; np->n_accerror = error; @@ -1770,7 +1770,9 @@ again: goto again; } } else if (v3 && (fmode & O_EXCL)) { - struct timeval tm = time; + struct timespec ts; + + getnanotime(&ts); /* * make sure that we'll update timestamps as @@ -1780,14 +1782,10 @@ again: * XXX it's better to use TOSERVER always. */ - if (vap->va_atime.tv_sec == VNOVAL) { - vap->va_atime.tv_sec = tm.tv_sec; - vap->va_atime.tv_nsec = tm.tv_usec * 1000; - } - if (vap->va_mtime.tv_sec == VNOVAL) { - vap->va_mtime.tv_sec = tm.tv_sec; - vap->va_mtime.tv_nsec = tm.tv_usec * 1000; - } + if (vap->va_atime.tv_sec == VNOVAL) + vap->va_atime = ts; + if (vap->va_mtime.tv_sec == VNOVAL) + vap->va_mtime = ts; error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_proc); } @@ -3521,8 +3519,7 @@ nfsspec_read(v) * Set access flag. */ np->n_flag |= NACC; - np->n_atim.tv_sec = time.tv_sec; - np->n_atim.tv_nsec = time.tv_usec * 1000; + getnanotime(&np->n_atim); return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap)); } @@ -3545,8 +3542,7 @@ nfsspec_write(v) * Set update flag. */ np->n_flag |= NUPD; - np->n_mtim.tv_sec = time.tv_sec; - np->n_mtim.tv_nsec = time.tv_usec * 1000; + getnanotime(&np->n_mtim); return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap)); } @@ -3603,8 +3599,7 @@ nfsfifo_read(v) * Set access flag. */ np->n_flag |= NACC; - np->n_atim.tv_sec = time.tv_sec; - np->n_atim.tv_nsec = time.tv_usec * 1000; + getnanotime(&np->n_atim); return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap)); } @@ -3627,8 +3622,7 @@ nfsfifo_write(v) * Set update flag. */ np->n_flag |= NUPD; - np->n_mtim.tv_sec = time.tv_sec; - np->n_mtim.tv_nsec = time.tv_usec * 1000; + getnanotime(&np->n_mtim); return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap)); } @@ -3652,14 +3646,13 @@ nfsfifo_close(v) struct vattr vattr; if (np->n_flag & (NACC | NUPD)) { - if (np->n_flag & NACC) { - np->n_atim.tv_sec = time.tv_sec; - np->n_atim.tv_nsec = time.tv_usec * 1000; - } - if (np->n_flag & NUPD) { - np->n_mtim.tv_sec = time.tv_sec; - np->n_mtim.tv_nsec = time.tv_usec * 1000; - } + struct timespec ts; + + getnanotime(&ts); + if (np->n_flag & NACC) + np->n_atim = ts; + if (np->n_flag & NUPD) + np->n_mtim = ts; np->n_flag |= NCHG; if (vp->v_usecount == 1 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { Index: sys/nfs/nfsm_subs.h =================================================================== RCS file: /cvsroot/src/sys/nfs/nfsm_subs.h,v retrieving revision 1.43 diff -d -p -u -r1.43 nfsm_subs.h --- sys/nfs/nfsm_subs.h 31 Oct 2005 14:21:35 -0000 1.43 +++ sys/nfs/nfsm_subs.h 22 Nov 2005 13:44:26 -0000 @@ -327,7 +327,7 @@ *tl = nfs_false; \ } \ if ((a)->va_atime.tv_sec != VNOVAL) { \ - if ((a)->va_atime.tv_sec != time.tv_sec) { \ + if ((a)->va_atime.tv_sec != time_second) { \ nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \ *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \ txdr_nfsv3time(&(a)->va_atime, tl); \ @@ -340,7 +340,7 @@ *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); \ } \ if ((a)->va_mtime.tv_sec != VNOVAL) { \ - if ((a)->va_mtime.tv_sec != time.tv_sec) { \ + if ((a)->va_mtime.tv_sec != time_second) { \ nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \ *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \ txdr_nfsv3time(&(a)->va_mtime, tl); \ @@ -514,8 +514,6 @@ #define nfsm_srvsattr(a) \ { \ - const struct timespec *ts = NULL; \ - struct timespec tsb; \ nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ if (*tl == nfs_true) { \ nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ @@ -543,8 +541,7 @@ fxdr_nfsv3time(tl, &(a)->va_atime); \ break; \ case NFSV3SATTRTIME_TOSERVER: \ - ts = nanotime(&tsb); \ - (a)->va_atime = *ts; \ + getnanotime(&(a)->va_atime); \ (a)->va_vaflags |= VA_UTIMES_NULL; \ break; \ }; \ @@ -556,8 +553,7 @@ (a)->va_vaflags &= ~VA_UTIMES_NULL; \ break; \ case NFSV3SATTRTIME_TOSERVER: \ - ts = ts ? ts : nanotime(&tsb); \ - (a)->va_mtime = *ts; \ + getnanotime(&(a)->va_mtime); \ (a)->va_vaflags |= VA_UTIMES_NULL; \ break; \ }; } Index: sys/nfs/nqnfs.h =================================================================== RCS file: /cvsroot/src/sys/nfs/nqnfs.h,v retrieving revision 1.16 diff -d -p -u -r1.16 nqnfs.h --- sys/nfs/nqnfs.h 21 Apr 2004 02:22:49 -0000 1.16 +++ sys/nfs/nqnfs.h 22 Nov 2005 13:44:26 -0000 @@ -159,20 +159,20 @@ struct nqm { * Client side macros that check for a valid lease. */ #define NQNFS_CKINVALID(v, n, f) \ - ((time.tv_sec > (n)->n_expiry && \ + ((time_second > (n)->n_expiry && \ VFSTONFS((v)->v_mount)->nm_timeouts < VFSTONFS((v)->v_mount)->nm_deadthresh) \ || ((f) == ND_WRITE && ((n)->n_flag & NQNFSWRITE) == 0)) #define NQNFS_CKCACHABLE(v, f) \ - ((time.tv_sec <= VTONFS(v)->n_expiry || \ + ((time_second <= VTONFS(v)->n_expiry || \ VFSTONFS((v)->v_mount)->nm_timeouts >= VFSTONFS((v)->v_mount)->nm_deadthresh) \ && (VTONFS(v)->n_flag & NQNFSNONCACHE) == 0 && \ ((f) == ND_READ || (VTONFS(v)->n_flag & NQNFSWRITE))) #define NQNFS_NEEDLEASE(n, p) \ - (time.tv_sec > (n)->n_expiry ? \ + (time_second > (n)->n_expiry ? \ (((n)->n_flag & NQNFSEVICTED) ? 0 : nqnfs_piggy[p]) : \ - (((time.tv_sec + NQ_RENEWAL) > (n)->n_expiry && \ + (((time_second + NQ_RENEWAL) > (n)->n_expiry && \ nqnfs_piggy[p]) ? \ (((n)->n_flag & NQNFSWRITE) ? \ ND_WRITE : nqnfs_piggy[p]) : 0)) Index: sys/opencrypto/crypto.c =================================================================== RCS file: /cvsroot/src/sys/opencrypto/crypto.c,v retrieving revision 1.10 diff -d -p -u -r1.10 crypto.c --- sys/opencrypto/crypto.c 26 Feb 2005 22:39:52 -0000 1.10 +++ sys/opencrypto/crypto.c 22 Nov 2005 13:44:28 -0000 @@ -50,16 +50,6 @@ __KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1 softintr_establish(IPL_SOFTNET, (void (*)(void*))fn, NULL) #define unregister_swi(lvl, fn) softintr_disestablish(softintr_cookie) #define setsoftcrypto(x) softintr_schedule(x) - -static void nanouptime(struct timespec *); -static void -nanouptime(struct timespec *tp) -{ - struct timeval tv; - microtime(&tv); - TIMEVAL_TO_TIMESPEC(&tv, tp); -} - #endif #define SESID2HID(sid) (((sid) >> 32) & 0xffffffff) Index: sys/sys/kernel.h =================================================================== RCS file: /cvsroot/src/sys/sys/kernel.h,v retrieving revision 1.22 diff -d -p -u -r1.22 kernel.h --- sys/sys/kernel.h 2 Oct 2003 12:14:00 -0000 1.22 +++ sys/sys/kernel.h 22 Nov 2005 13:44:28 -0000 @@ -48,24 +48,9 @@ extern int hostnamelen; extern char domainname[MAXHOSTNAMELEN]; extern int domainnamelen; -extern volatile struct timeval mono_time; -extern struct timeval boottime; -extern volatile struct timeval time; - -extern int rtc_offset; /* offset of rtc from UTC in minutes */ - extern int cold; /* still working on startup */ -extern int tick; /* usec per tick (1000000 / hz) */ -extern int hardclock_ticks; /* # of hardclock ticks */ -extern int tickfix; /* periodic tick adj. tick not integral */ -extern int tickfixinterval; /* interval at which to apply adjustment */ -extern int tickadj; /* "standard" clock skew, us./tick */ -extern int hz; /* system clock's frequency */ -extern int stathz; /* statistics clock's frequency */ -extern int profhz; /* profiling clock's frequency */ -extern int lbolt; /* once a second sleep address */ - extern int profsrc; /* profiling source */ +extern int security_curtain; #define PROFSRC_CLOCK 0 Index: sys/sys/sysctl.h =================================================================== RCS file: /cvsroot/src/sys/sys/sysctl.h,v retrieving revision 1.141 diff -d -p -u -r1.141 sysctl.h --- sys/sys/sysctl.h 7 Sep 2005 16:26:16 -0000 1.141 +++ sys/sys/sysctl.h 22 Nov 2005 13:44:31 -0000 @@ -1,3 +1,4 @@ +/* XXX kardel add KERN_TIMECOUNTER? */ /* $NetBSD: sysctl.h,v 1.141 2005/09/07 16:26:16 elad Exp $ */ /* @@ -909,9 +910,6 @@ struct kinfo_file { { "curtain", CTLTYPE_INT }, \ } -/* XXX this should not be here */ -extern int security_curtain; - #ifdef _KERNEL #if defined(_KERNEL_OPT) Index: sys/sys/systm.h =================================================================== RCS file: /cvsroot/src/sys/sys/systm.h,v retrieving revision 1.181 diff -d -p -u -r1.181 systm.h --- sys/sys/systm.h 23 Oct 2005 00:09:14 -0000 1.181 +++ sys/sys/systm.h 22 Nov 2005 13:44:32 -0000 @@ -267,19 +267,25 @@ int fuswintr(const void *); long fuword(const void *); long fuiword(const void *); -int hzto(struct timeval *); - void hardclock(struct clockframe *); void softclock(void *); void statclock(struct clockframe *); + #ifdef NTP +void ntp_init(void); +#ifndef __HAVE_TIMECOUNTER void hardupdate(long offset); +#endif /* !__HAVE_TIMECOUNTER */ #ifdef PPS_SYNC -void hardpps(struct timeval *, long); -extern void *pps_kc_hardpps_source; -extern int pps_kc_hardpps_mode; -#endif -#endif +#ifdef __HAVE_TIMECOUNTER +void hardpps(struct timespec *, long); +#else /* !__HAVE_TIMECOUNTER */ +void hardpps(long offset); +extern void *pps_kc_hardpps_source; +extern int pps_kc_hardpps_mode; +#endif /* !__HAVE_TIMECOUNTER */ +#endif /* PPS_SYNC */ +#endif /* NTP */ void initclocks(void); void inittodr(time_t); Index: sys/sys/time.h =================================================================== RCS file: /cvsroot/src/sys/sys/time.h,v retrieving revision 1.51 diff -d -p -u -r1.51 time.h --- sys/sys/time.h 23 Oct 2005 00:09:14 -0000 1.51 +++ sys/sys/time.h 22 Nov 2005 13:44:32 -0000 @@ -36,11 +36,6 @@ #include #include -#ifdef _KERNEL -#include -#include -#include -#endif /* * Structure returned by gettimeofday(2) system call, @@ -103,6 +98,98 @@ struct timezone { } \ } while (/* CONSTCOND */ 0) +#ifdef _NETBSD_SOURCE +struct bintime { + time_t sec; + uint64_t frac; +}; + +static __inline void +bintime_addx(struct bintime *bt, uint64_t x) +{ + uint64_t u; + + u = bt->frac; + bt->frac += x; + if (u > bt->frac) + bt->sec++; +} + +static __inline void +bintime_add(struct bintime *bt, const struct bintime *bt2) +{ + uint64_t u; + + u = bt->frac; + bt->frac += bt2->frac; + if (u > bt->frac) + bt->sec++; + bt->sec += bt2->sec; +} + +static __inline void +bintime_sub(struct bintime *bt, const struct bintime *bt2) +{ + uint64_t u; + + u = bt->frac; + bt->frac -= bt2->frac; + if (u < bt->frac) + bt->sec--; + bt->sec -= bt2->sec; +} + +/*- + * Background information: + * + * When converting between timestamps on parallel timescales of differing + * resolutions it is historical and scientific practice to round down rather + * than doing 4/5 rounding. + * + * The date changes at midnight, not at noon. + * + * Even at 15:59:59.999999999 it's not four'o'clock. + * + * time_second ticks after N.999999999 not after N.4999999999 + */ + +static __inline void +bintime2timespec(const struct bintime *bt, struct timespec *ts) +{ + + ts->tv_sec = bt->sec; + ts->tv_nsec = + (long)(((uint64_t)1000000000 * (uint32_t)(bt->frac >> 32)) >> 32); +} + +static __inline void +timespec2bintime(const struct timespec *ts, struct bintime *bt) +{ + + bt->sec = ts->tv_sec; + /* 18446744073 = int(2^64 / 1000000000) */ + bt->frac = ts->tv_nsec * (uint64_t)18446744073LL; +} + +static __inline void +bintime2timeval(const struct bintime *bt, struct timeval *tv) +{ + + tv->tv_sec = bt->sec; + tv->tv_usec = + (long)(((uint64_t)1000000 * (uint32_t)(bt->frac >> 32)) >> 32); +} + +static __inline void +timeval2bintime(const struct timeval *tv, struct bintime *bt) +{ + + bt->sec = tv->tv_sec; + /* 18446744073709 = int(2^64 / 1000000) */ + bt->frac = tv->tv_usec * (uint64_t)18446744073709LL; +} +#endif /* __BSD_VISIBLE */ + /* Operations on timespecs. */ #define timespecclear(tsp) (tsp)->tv_sec = (tsp)->tv_nsec = 0 #define timespecisset(tsp) ((tsp)->tv_sec || (tsp)->tv_nsec) @@ -171,64 +258,8 @@ struct clockinfo { #define TIMER_ABSTIME 0x1 /* absolute timer */ #ifdef _KERNEL -/* - * Structure used to manage timers in a process. - */ -struct ptimer { - union { - struct callout pt_ch; - struct { - LIST_ENTRY(ptimer) pt_list; - int pt_active; - } pt_nonreal; - } pt_data; - struct sigevent pt_ev; - struct itimerval pt_time; - struct ksiginfo pt_info; - int pt_overruns; /* Overruns currently accumulating */ - int pt_poverruns; /* Overruns associated w/ a delivery */ - int pt_type; - int pt_entry; - struct proc *pt_proc; -}; - -#define pt_ch pt_data.pt_ch -#define pt_list pt_data.pt_nonreal.pt_list -#define pt_active pt_data.pt_nonreal.pt_active - -#define TIMER_MAX 32 /* See ptimers->pts_fired if you enlarge this */ -#define TIMERS_ALL 0 -#define TIMERS_POSIX 1 - -LIST_HEAD(ptlist, ptimer); - -struct ptimers { - struct ptlist pts_virtual; - struct ptlist pts_prof; - struct ptimer *pts_timers[TIMER_MAX]; - int pts_fired; -}; - -int itimerfix(struct timeval *tv); -int itimerdecr(struct ptimer *, int); -void itimerfire(struct ptimer *); -void microtime(struct timeval *); -struct timespec *nanotime(struct timespec *); -int settime(struct timeval *); -int ratecheck(struct timeval *, const struct timeval *); -int ppsratecheck(struct timeval *, int *, int); -int settimeofday1(const struct timeval *, const struct timezone *, - struct proc *); -int adjtime1(const struct timeval *, struct timeval *, struct proc *); -int clock_settime1(clockid_t, const struct timespec *); -void timer_settime(struct ptimer *); -void timer_gettime(struct ptimer *, struct itimerval *); -void timers_alloc(struct proc *); -void timers_free(struct proc *, int); -void realtimerexpire(void *); - +#include #else /* !_KERNEL */ - #ifndef _STANDALONE #if (_POSIX_C_SOURCE - 0) >= 200112L || \ (defined(_XOPEN_SOURCE) && defined(_XOPEN_SOURCE_EXTENDED)) || \ @@ -254,9 +285,6 @@ int settimeofday(const struct timeval * int utimes(const char *, const struct timeval [2]); __END_DECLS #endif /* _XOPEN_SOURCE || _NETBSD_SOURCE */ - #endif /* !_STANDALONE */ - #endif /* !_KERNEL */ - #endif /* !_SYS_TIME_H_ */ Index: sys/sys/timepps.h =================================================================== RCS file: /cvsroot/src/sys/sys/timepps.h,v retrieving revision 1.10 diff -d -p -u -r1.10 timepps.h --- sys/sys/timepps.h 19 Sep 2005 03:18:00 -0000 1.10 +++ sys/sys/timepps.h 22 Nov 2005 13:44:33 -0000 @@ -1,3 +1,5 @@ +/* XXX !__HAVE_TIMECOUNTER case */ +/* XXX kardel changes */ /* $NetBSD: timepps.h,v 1.10 2005/09/19 03:18:00 simonb Exp $ */ /* @@ -58,7 +60,6 @@ typedef union pps_timeu { unsigned long longpair[2]; } pps_timeu_t; - /* * timestamp information */ @@ -73,7 +74,6 @@ typedef struct { #define assert_timestamp assert_tu.tspec #define clear_timestamp clear_tu.tspec - /* * Parameter structure */ @@ -83,10 +83,10 @@ typedef struct { pps_timeu_t assert_off_tu; pps_timeu_t clear_off_tu; } pps_params_t; + #define assert_offset assert_off_tu.tspec #define clear_offset clear_off_tu.tspec - /* * Device/implementation parameters (mode, edge bits) */ @@ -104,7 +104,6 @@ typedef struct { #define PPS_ECHOASSERT 0x40 #define PPS_ECHOCLEAR 0x80 - /* * timestamp formats (tsformat, mode) */ @@ -118,6 +117,18 @@ typedef struct { #define PPS_KC_HARDPPS_PLL 1 #define PPS_KC_HARDPPS_FLL 2 +struct pps_fetch_args { + int tsformat; + pps_info_t pps_info_buf; + struct timespec timeout; +}; + +struct pps_kcbind_args { + int kernel_consumer; + int edge; + int tsformat; +}; + /* * IOCTL definitions */ @@ -126,10 +137,38 @@ typedef struct { #define PPS_IOC_SETPARAMS _IOW('1', 3, pps_params_t) #define PPS_IOC_GETPARAMS _IOR('1', 4, pps_params_t) #define PPS_IOC_GETCAP _IOR('1', 5, int) -#define PPS_IOC_FETCH _IOWR('1', 6, pps_info_t) -#define PPS_IOC_KCBIND _IOW('1', 7, int) +#define PPS_IOC_OFETCH _IOWR('1', 6, pps_info_t) /* XXX keep old? */ +#define PPS_IOC_OKCBIND _IOW('1', 7, int) /* XXX keep old? */ +#define PPS_IOC_FETCH _IOWR('1', 8, struct pps_fetch_args) +#define PPS_IOC_KCBIND _IOW('1', 9, struct pps_kcbind_args) -#ifndef _KERNEL +#ifdef _KERNEL + +struct pps_state { + /* Capture information. */ + struct timehands *capth; + unsigned capgen; + unsigned capcount; + + /* State information. */ + pps_params_t ppsparam; + pps_info_t ppsinfo; + int kcmode; + int ppscap; + struct timecounter *ppstc; + unsigned ppscount[3]; +}; + +void pps_capture(struct pps_state *pps); +void pps_event(struct pps_state *pps, int event); +void pps_init(struct pps_state *pps); +int pps_ioctl(unsigned long cmd, caddr_t data, struct pps_state *pps); +void hardpps(struct timespec *tsp, long nsec); + +extern void *pps_kc_hardpps_source; /* XXXX needed in timecounter world?? XXXX */ +extern int pps_kc_hardpps_mode; /* XXXX needed in timecounter world?? XXXX */ + +#else /* !_KERNEL */ #include #include @@ -150,70 +189,74 @@ static __inline int time_pps_kcbind(pps_ const int); static __inline int -time_pps_create(filedes, handle) - int filedes; - pps_handle_t *handle; +time_pps_create(int filedes, pps_handle_t *handle) { + int error; + *handle = -1; + error = ioctl(filedes, PPS_IOC_CREATE, 0); + if (error < 0) + return (-1); *handle = filedes; return (0); } static __inline int -time_pps_destroy(handle) - pps_handle_t handle; +time_pps_destroy(pps_handle_t handle) { - return (0); + return (ioctl(handle, PPS_IOC_DESTROY, 0)); } static __inline int -time_pps_setparams(handle, ppsparams) - pps_handle_t handle; - const pps_params_t *ppsparams; +time_pps_setparams(pps_handle_t handle, const pps_params_t *ppsparams) { return (ioctl(handle, PPS_IOC_SETPARAMS, __UNCONST(ppsparams))); } static __inline int -time_pps_getparams(handle, ppsparams) - pps_handle_t handle; - pps_params_t *ppsparams; +time_pps_getparams(pps_handle_t handle, pps_params_t *ppsparams) { return (ioctl(handle, PPS_IOC_GETPARAMS, ppsparams)); } static __inline int -time_pps_getcap(handle, mode) - pps_handle_t handle; - int *mode; +time_pps_getcap(pps_handle_t handle, int *mode) { return (ioctl(handle, PPS_IOC_GETCAP, mode)); } static __inline int -time_pps_fetch(handle, tsformat, ppsinfobuf, timeout) - pps_handle_t handle; - const int tsformat; - pps_info_t *ppsinfobuf; - const struct timespec *timeout; +time_pps_fetch(pps_handle_t handle, const int tsformat, pps_info_t *ppsinfobuf, + const struct timespec *timeout) { + int error; + struct pps_fetch_args arg; - return (ioctl(handle, PPS_IOC_FETCH, ppsinfobuf)); + arg.tsformat = tsformat; + if (timeout == NULL) { + arg.timeout.tv_sec = -1; + arg.timeout.tv_nsec = -1; + } else + arg.timeout = *timeout; + error = ioctl(handle, PPS_IOC_FETCH, &arg); + *ppsinfobuf = arg.pps_info_buf; + return (error); } static __inline int -time_pps_kcbind(handle, kernel_consumer, edge, tsformat) - pps_handle_t handle; - const int kernel_consumer; - const int edge; - const int tsformat; +time_pps_kcbind(pps_handle_t handle, const int kernel_consumer, const int edge, + const int tsformat) { + struct pps_kcbind_args arg; - return (ioctl(handle, PPS_IOC_KCBIND, __UNCONST(&edge))); + arg.kernel_consumer = kernel_consumer; + arg.edge = edge; + arg.tsformat = tsformat; + return (ioctl(handle, PPS_IOC_KCBIND, &arg)); } #endif /* !_KERNEL*/ #endif /* SYS_TIMEPPS_H_ */ Index: sys/sys/timetc.h =================================================================== RCS file: sys/sys/timetc.h diff -N sys/sys/timetc.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sys/timetc.h 22 Nov 2005 13:44:33 -0000 @@ -0,0 +1,78 @@ +/*- + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $FreeBSD: src/sys/sys/timetc.h,v 1.58 2003/08/16 08:23:52 phk Exp $ + */ + +#ifndef _SYS_TIMETC_H_ +#define _SYS_TIMETC_H_ + +#ifndef _KERNEL +#error "no user-serviceable parts inside" +#endif + +/*- + * `struct timecounter' is the interface between the hardware which implements + * a timecounter and the MI code which uses this to keep track of time. + * + * A timecounter is a binary counter which has two properties: + * * it runs at a fixed, known frequency. + * * it has sufficient bits to not roll over in less than approximately + * max(2 msec, 2/HZ seconds). (The value 2 here is really 1 + delta, + * for some indeterminate value of delta.) + */ + +struct timecounter; +typedef u_int timecounter_get_t(struct timecounter *); +typedef void timecounter_pps_t(struct timecounter *); + +struct timecounter { + timecounter_get_t *tc_get_timecount; + /* + * This function reads the counter. It is not required to + * mask any unimplemented bits out, as long as they are + * constant. + */ + timecounter_pps_t *tc_poll_pps; + /* + * This function is optional. It will be called whenever the + * timecounter is rewound, and is intended to check for PPS + * events. Normal hardware does not need it but timecounters + * which latch PPS in hardware (like sys/pci/xrpu.c) do. + */ + u_int tc_counter_mask; + /* This mask should mask off any unimplemented bits. */ + u_int64_t tc_frequency; + /* Frequency of the counter in Hz. */ + const char *tc_name; + /* Name of the timecounter. */ + int tc_quality; + /* + * Used to determine if this timecounter is better than + * another timecounter higher means better. Negative + * means "only use at explicit request". + */ + + void *tc_priv; + /* Pointer to the timecounter's private parts. */ + struct timecounter *tc_next; + /* Pointer to the next timecounter. */ +}; + +extern struct timecounter *timecounter; + +u_int64_t tc_getfrequency(void); +void tc_init(struct timecounter *tc); +void tc_setclock(struct timespec *ts); +void tc_ticktock(void); + +#ifdef SYSCTL_DECL +SYSCTL_DECL(_kern_timecounter); +#endif + +#endif /* !_SYS_TIMETC_H_ */ Index: sys/sys/timevar.h =================================================================== RCS file: /cvsroot/src/sys/sys/timevar.h,v retrieving revision 1.2 diff -d -p -u -r1.2 timevar.h --- sys/sys/timevar.h 24 Oct 2005 13:43:27 -0000 1.2 +++ sys/sys/timevar.h 22 Nov 2005 13:44:33 -0000 @@ -36,18 +36,182 @@ * POSSIBILITY OF SUCH DAMAGE. */ +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. 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. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)time.h 8.5 (Berkeley) 5/4/95 + */ + #ifndef _SYS_TIMEVAR_H_ #define _SYS_TIMEVAR_H_ +#include +#include +#include #include +/* + * Structure used to manage timers in a process. + */ +struct ptimer { + union { + struct callout pt_ch; + struct { + LIST_ENTRY(ptimer) pt_list; + int pt_active; + } pt_nonreal; + } pt_data; + struct sigevent pt_ev; + struct itimerval pt_time; + struct ksiginfo pt_info; + int pt_overruns; /* Overruns currently accumulating */ + int pt_poverruns; /* Overruns associated w/ a delivery */ + int pt_type; + int pt_entry; + struct proc *pt_proc; +}; + +#define pt_ch pt_data.pt_ch +#define pt_list pt_data.pt_nonreal.pt_list +#define pt_active pt_data.pt_nonreal.pt_active + +#define TIMER_MAX 32 /* See ptimers->pts_fired if you enlarge this */ +#define TIMERS_ALL 0 +#define TIMERS_POSIX 1 + +LIST_HEAD(ptlist, ptimer); + +struct ptimers { + struct ptlist pts_virtual; + struct ptlist pts_prof; + struct ptimer *pts_timers[TIMER_MAX]; + int pts_fired; +}; + +/* + * Functions for looking at our clock: [get]{bin,nano,micro}[up]time() + * + * Functions without the "get" prefix returns the best timestamp + * we can produce in the given format. + * + * "bin" == struct bintime == seconds + 64 bit fraction of seconds. + * "nano" == struct timespec == seconds + nanoseconds. + * "micro" == struct timeval == seconds + microseconds. + * + * Functions containing "up" returns time relative to boot and + * should be used for calculating time intervals. + * + * Functions without "up" returns GMT time. + * + * Functions with the "get" prefix returns a less precise result + * much faster than the functions without "get" prefix and should + * be used where a precision of 10 msec is acceptable or where + * performance is priority. (NB: "precision", _not_ "resolution" !) + * + */ + +#ifdef __HAVE_TIMECOUNTER +void binuptime(struct bintime *); +void nanouptime(struct timespec *); +void microuptime(struct timeval *); + +void bintime(struct bintime *); +void nanotime(struct timespec *); +void microtime(struct timeval *); + +void getbinuptime(struct bintime *); +void getnanouptime(struct timespec *); +void getmicrouptime(struct timeval *); + +void getbintime(struct bintime *); +void getnanotime(struct timespec *); +void getmicrotime(struct timeval *); +#else /* !__HAVE_TIMECOUNTER */ +void microtime(struct timeval *); +void nanotime(struct timespec *); + +/* timecounter compat functions */ +void getbinuptime(struct bintime *); +void getnanouptime(struct timespec *); +void getmicrouptime(struct timeval *); + +void getnanotime(struct timespec *); +void getmicrotime(struct timeval *); +#endif /* !__HAVE_TIMECOUNTER */ + +/* Other functions */ +int adjtime1(const struct timeval *, struct timeval *, struct proc *); +int clock_settime1(clockid_t, const struct timespec *); int dogetitimer(struct proc *, int, struct itimerval *); int dosetitimer(struct proc *, int, struct itimerval *); - -int timer_create1(timer_t *, clockid_t, struct sigevent *, copyin_t, - struct proc *); -int dotimer_settime(int, struct itimerspec *, struct itimerspec *, int, - struct proc *); int dotimer_gettime(int, struct proc *, struct itimerspec *); +int dotimer_settime(int, struct itimerspec *, struct itimerspec *, int, + struct proc *); +int hzto(struct timeval *); +void inittimecounter(void); +int itimerdecr(struct ptimer *, int); +void itimerfire(struct ptimer *); +int itimerfix(struct timeval *tv); +int ppsratecheck(struct timeval *, int *, int); +int ratecheck(struct timeval *, const struct timeval *); +void realtimerexpire(void *); +int settime(struct timeval *); +int settimeofday1(const struct timeval *, const struct timezone *, + struct proc *); +int timer_create1(timer_t *, clockid_t, struct sigevent *, copyin_t, + struct proc *); +void timer_gettime(struct ptimer *, struct itimerval *); +void timer_settime(struct ptimer *); +void timers_alloc(struct proc *); +void timers_free(struct proc *, int); +int tstohz(struct timespec *); +int tvtohz(struct timeval *); + +#ifdef __HAVE_TIMECOUNTER +/* XXXX following two (or three?) volatile?? XXXX */ +extern time_t time_second; /* current second in the epoch */ +extern time_t time_uptime; /* system uptime in seconds */ +#else /* !__HAVE_TIMECOUNTER */ +extern volatile struct timeval mono_time; +extern volatile struct timeval time; +#define time_second time.tv_sec +#define time_uptime mono_time.tv_sec +#endif /* !__HAVE_TIMECOUNTER */ +extern struct timeval boottime; /* system boot time */ +extern int rtc_offset; /* offset of rtc from UTC in minutes */ +extern int tick; /* usec per tick (1000000 / hz) */ +extern int hardclock_ticks; /* # of hardclock ticks */ +extern int tickfix; /* periodic tick adj. tick not integral */ +extern int tickfixinterval; /* interval at which to apply adjustment */ +extern int tickadj; /* "standard" clock skew, us./tick */ +extern int hz; /* system clock's frequency */ +extern int stathz; /* statistics clock's frequency */ +extern int profhz; /* profiling clock's frequency */ +extern int lbolt; /* once a second sleep address */ #endif /* !_SYS_TIMEVAR_H_ */ Index: sys/sys/timex.h =================================================================== RCS file: /cvsroot/src/sys/sys/timex.h,v retrieving revision 1.8 diff -d -p -u -r1.8 timex.h --- sys/sys/timex.h 3 Feb 2005 19:20:02 -0000 1.8 +++ sys/sys/timex.h 22 Nov 2005 13:44:35 -0000 @@ -1,5 +1,246 @@ /* $NetBSD: timex.h,v 1.8 2005/02/03 19:20:02 perry Exp $ */ +#ifdef __HAVE_TIMECOUNTER +/*- + *********************************************************************** + * * + * Copyright (c) David L. Mills 1993-2001 * + * * + * Permission to use, copy, modify, and distribute this software and * + * its documentation for any purpose and without fee is hereby * + * granted, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission * + * notice appear in supporting documentation, and that the name * + * University of Delaware not be used in advertising or publicity * + * pertaining to distribution of the software without specific, * + * written prior permission. The University of Delaware makes no * + * representations about the suitability this software for any * + * purpose. It is provided "as is" without express or implied * + * warranty. * + * * + **********************************************************************/ + +/* + * Modification history timex.h + * + * 16 Aug 00 David L. Mills + * API Version 4. Added MOD_TAI and tai member of ntptimeval + * structure. + * + * 17 Nov 98 David L. Mills + * Revised for nanosecond kernel and user interface. + * + * 26 Sep 94 David L. Mills + * Added defines for hybrid phase/frequency-lock loop. + * + * 19 Mar 94 David L. Mills + * Moved defines from kernel routines to header file and added new + * defines for PPS phase-lock loop. + * + * 20 Feb 94 David L. Mills + * Revised status codes and structures for external clock and PPS + * signal discipline. + * + * 28 Nov 93 David L. Mills + * Adjusted parameters to improve stability and increase poll + * interval. + * + * 17 Sep 93 David L. Mills + * Created file + * + * $FreeBSD: src/sys/sys/timex.h,v 1.18 2005/01/07 02:29:24 imp Exp $ + */ +/* + * This header file defines the Network Time Protocol (NTP) interfaces + * for user and daemon application programs. These are implemented using + * defined syscalls and data structures and require specific kernel + * support. + * + * The original precision time kernels developed from 1993 have an + * ultimate resolution of one microsecond; however, the most recent + * kernels have an ultimate resolution of one nanosecond. In these + * kernels, a ntp_adjtime() syscalls can be used to determine which + * resolution is in use and to select either one at any time. The + * resolution selected affects the scaling of certain fields in the + * ntp_gettime() and ntp_adjtime() syscalls, as described below. + * + * NAME + * ntp_gettime - NTP user application interface + * + * SYNOPSIS + * #include + * + * int ntp_gettime(struct ntptimeval *ntv); + * + * DESCRIPTION + * The time returned by ntp_gettime() is in a timespec structure, + * but may be in either microsecond (seconds and microseconds) or + * nanosecond (seconds and nanoseconds) format. The particular + * format in use is determined by the STA_NANO bit of the status + * word returned by the ntp_adjtime() syscall. + * + * NAME + * ntp_adjtime - NTP daemon application interface + * + * SYNOPSIS + * #include + * #include + * + * int syscall(SYS_ntp_adjtime, tptr); + * int SYS_ntp_adjtime; + * struct timex *tptr; + * + * DESCRIPTION + * Certain fields of the timex structure are interpreted in either + * microseconds or nanoseconds according to the state of the + * 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 +#endif /* MSDOS */ + +/* + * The following defines establish the performance envelope of the + * kernel discipline loop. Phase or frequency errors greater than + * NAXPHASE or MAXFREQ are clamped to these maxima. For update intervals + * less than MINSEC, the loop always operates in PLL mode; while, for + * update intervals greater than MAXSEC, the loop always operates in FLL + * mode. Between these two limits the operating mode is selected by the + * STA_FLL bit in the status word. + */ +#define MAXPHASE 500000000L /* max phase error (ns) */ +#define MAXFREQ 500000L /* max freq error (ns/s) */ +#define MINSEC 256 /* min FLL update interval (s) */ +#define MAXSEC 2048 /* max PLL update interval (s) */ +#define NANOSECOND 1000000000L /* nanoseconds in one second */ +#define SCALE_PPM (65536 / 1000) /* crude ns/s to scaled PPM */ +#define MAXTC 10 /* max time constant */ + +/* + * The following defines and structures define the user interface for + * the ntp_gettime() and ntp_adjtime() syscalls. + * + * Control mode codes (timex.modes) + */ +#define MOD_OFFSET 0x0001 /* set time offset */ +#define MOD_FREQUENCY 0x0002 /* set frequency offset */ +#define MOD_MAXERROR 0x0004 /* set maximum time error */ +#define MOD_ESTERROR 0x0008 /* set estimated time error */ +#define MOD_STATUS 0x0010 /* set clock status bits */ +#define MOD_TIMECONST 0x0020 /* set PLL time constant */ +#define MOD_PPSMAX 0x0040 /* set PPS maximum averaging time */ +#define MOD_TAI 0x0080 /* set TAI offset */ +#define MOD_MICRO 0x1000 /* select microsecond resolution */ +#define MOD_NANO 0x2000 /* select nanosecond resolution */ +#define MOD_CLKB 0x4000 /* select clock B */ +#define MOD_CLKA 0x8000 /* select clock A */ + +/* + * Status codes (timex.status) + */ +#define STA_PLL 0x0001 /* enable PLL updates (rw) */ +#define STA_PPSFREQ 0x0002 /* enable PPS freq discipline (rw) */ +#define STA_PPSTIME 0x0004 /* enable PPS time discipline (rw) */ +#define STA_FLL 0x0008 /* enable FLL mode (rw) */ +#define STA_INS 0x0010 /* insert leap (rw) */ +#define STA_DEL 0x0020 /* delete leap (rw) */ +#define STA_UNSYNC 0x0040 /* clock unsynchronized (rw) */ +#define STA_FREQHOLD 0x0080 /* hold frequency (rw) */ +#define STA_PPSSIGNAL 0x0100 /* PPS signal present (ro) */ +#define STA_PPSJITTER 0x0200 /* PPS signal jitter exceeded (ro) */ +#define STA_PPSWANDER 0x0400 /* PPS signal wander exceeded (ro) */ +#define STA_PPSERROR 0x0800 /* PPS signal calibration error (ro) */ +#define STA_CLOCKERR 0x1000 /* clock hardware fault (ro) */ +#define STA_NANO 0x2000 /* resolution (0 = us, 1 = ns) (ro) */ +#define STA_MODE 0x4000 /* mode (0 = PLL, 1 = FLL) (ro) */ +#define STA_CLK 0x8000 /* clock source (0 = A, 1 = B) (ro) */ + +#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \ + STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK) + +/* + * Clock states (time_state) + */ +#define TIME_OK 0 /* no leap second warning */ +#define TIME_INS 1 /* insert leap second warning */ +#define TIME_DEL 2 /* delete leap second warning */ +#define TIME_OOP 3 /* leap second in progress */ +#define TIME_WAIT 4 /* leap second has occured */ +#define TIME_ERROR 5 /* error (see status word) */ + +/* + * NTP user interface (ntp_gettime()) - used to read kernel clock values + * + * Note: The time member is in microseconds if STA_NANO is zero and + * nanoseconds if not. + */ +struct ntptimeval { + struct timespec time; /* current time (ns) (ro) */ + long maxerror; /* maximum error (us) (ro) */ + long esterror; /* estimated error (us) (ro) */ + long tai; /* TAI offset */ + int time_state; /* time status */ +}; + +/* + * NTP daemon interface (ntp_adjtime()) - used to discipline CPU clock + * oscillator and determine status. + * + * Note: The offset, precision and jitter members are in microseconds if + * STA_NANO is zero and nanoseconds if not. + */ +struct timex { + unsigned int modes; /* clock mode bits (wo) */ + long offset; /* time offset (ns/us) (rw) */ + long freq; /* frequency offset (scaled PPM) (rw) */ + long maxerror; /* maximum error (us) (rw) */ + long esterror; /* estimated error (us) (rw) */ + int status; /* clock status bits (rw) */ + long constant; /* poll interval (log2 s) (rw) */ + long precision; /* clock precision (ns/us) (ro) */ + long tolerance; /* clock frequency tolerance (scaled + * PPM) (ro) */ + /* + * The following read-only structure members are implemented + * only if the PPS signal discipline is configured in the + * kernel. They are included in all configurations to insure + * portability. + */ + long ppsfreq; /* PPS frequency (scaled PPM) (ro) */ + long jitter; /* PPS jitter (ns/us) (ro) */ + int shift; /* interval duration (s) (shift) (ro) */ + long stabil; /* PPS stability (scaled PPM) (ro) */ + long jitcnt; /* jitter limit exceeded (ro) */ + long calcnt; /* calibration intervals (ro) */ + long errcnt; /* calibration errors (ro) */ + long stbcnt; /* stability limit exceeded (ro) */ +}; + +#if defined(__FreeBSD__) || defined(__NetBSD__) + +#ifdef _KERNEL +void ntp_update_second(int64_t *adjustment, time_t *newsec); +#ifdef __NetBSD__ +int ntp_adjtime1(struct timex *, void *, register_t *); +#endif /* __NetBSD__ */ +#else /* !_KERNEL */ +#include + +__BEGIN_DECLS +int ntp_adjtime(struct timex *); +int ntp_gettime(struct ntptimeval *); +__END_DECLS +#endif /* _KERNEL */ + +#endif /* __FreeBSD__ || __NetBSD__ */ + +#endif /* _SYS_TIMEX_H_ */ +#else /* !__HAVE_TIMECOUNTER */ /****************************************************************************** * * * Copyright (c) David L. Mills 1993, 1994 * @@ -309,3 +550,4 @@ __END_DECLS #endif /* _KERNEL */ #endif /* __NetBSD__ */ #endif /* _SYS_TIMEX_H_ */ +#endif /* !__HAVE_TIMECOUNTER */ Index: sys/ufs/ext2fs/ext2fs_alloc.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_alloc.c,v retrieving revision 1.27 diff -d -p -u -r1.27 ext2fs_alloc.c --- sys/ufs/ext2fs/ext2fs_alloc.c 2 Nov 2005 12:39:00 -0000 1.27 +++ sys/ufs/ext2fs/ext2fs_alloc.c 22 Nov 2005 13:44:35 -0000 @@ -206,8 +206,8 @@ ext2fs_valloc(struct vnode *pvp, int mod /* * Set up a new generation number for this inode. */ - if (++ext2gennumber < (u_long)time.tv_sec) - ext2gennumber = time.tv_sec; + if (++ext2gennumber < time_second) + ext2gennumber = time_second; ip->i_e2fs_gen = ext2gennumber; return (0); noinodes: Index: sys/ufs/ext2fs/ext2fs_inode.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_inode.c,v retrieving revision 1.51 diff -d -p -u -r1.51 ext2fs_inode.c --- sys/ufs/ext2fs/ext2fs_inode.c 11 Nov 2005 15:50:57 -0000 1.51 +++ sys/ufs/ext2fs/ext2fs_inode.c 22 Nov 2005 13:44:36 -0000 @@ -146,7 +146,6 @@ ext2fs_inactive(void *v) struct inode *ip = VTOI(vp); struct mount *mp; struct proc *p = ap->a_p; - struct timespec ts; int error = 0; if (prtactive && vp->v_usecount != 0) @@ -161,8 +160,7 @@ ext2fs_inactive(void *v) if (ext2fs_size(ip) != 0) { error = ext2fs_truncate(vp, (off_t)0, 0, NOCRED, NULL); } - nanotime(&ts); - ip->i_e2fs_dtime = ts.tv_sec; + ip->i_e2fs_dtime = time_uptime; ip->i_flag |= IN_CHANGE | IN_UPDATE; ext2fs_vfree(vp, ip->i_number, ip->i_e2fs_mode); vn_finished_write(mp, V_LOWER); Index: sys/ufs/ext2fs/ext2fs_subr.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_subr.c,v retrieving revision 1.18 diff -d -p -u -r1.18 ext2fs_subr.c --- sys/ufs/ext2fs/ext2fs_subr.c 2 Nov 2005 12:39:00 -0000 1.18 +++ sys/ufs/ext2fs/ext2fs_subr.c 22 Nov 2005 13:44:36 -0000 @@ -109,26 +109,28 @@ void ext2fs_itimes(struct inode *ip, const struct timespec *acc, const struct timespec *mod, const struct timespec *cre) { - struct timespec *ts = NULL, tsb; + struct timespec now; if (!(ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY))) { return; } + /* XXX: Use the technique of just "getnanotime; use it throughout the function" in other *_itimes()s functions instead of all the "ts = ts ? ts : getnanotime" mess? */ + getnanotime(&now); if (ip->i_flag & IN_ACCESS) { if (acc == NULL) - acc = ts == NULL ? (ts = nanotime(&tsb)) : ts; + acc = &now; ip->i_e2fs_atime = acc->tv_sec; } if (ip->i_flag & (IN_UPDATE | IN_MODIFY)) { if (mod == NULL) - mod = ts == NULL ? (ts = nanotime(&tsb)) : ts; + mod = &now; ip->i_e2fs_mtime = mod->tv_sec; ip->i_modrev++; } if (ip->i_flag & (IN_CHANGE | IN_MODIFY)) { if (cre == NULL) - cre = ts == NULL ? (ts = nanotime(&tsb)) : ts; + cre = &now; ip->i_e2fs_ctime = cre->tv_sec; } if (ip->i_flag & (IN_ACCESS | IN_MODIFY)) Index: sys/ufs/ext2fs/ext2fs_vfsops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v retrieving revision 1.93 diff -d -p -u -r1.93 ext2fs_vfsops.c --- sys/ufs/ext2fs/ext2fs_vfsops.c 2 Nov 2005 12:39:00 -0000 1.93 +++ sys/ufs/ext2fs/ext2fs_vfsops.c 22 Nov 2005 13:44:39 -0000 @@ -431,7 +431,7 @@ ext2fs_mount(struct mount *mp, const cha if (fs->e2fs_fmod != 0) { /* XXX */ fs->e2fs_fmod = 0; if (fs->e2fs.e2fs_state == 0) - fs->e2fs.e2fs_wtime = time.tv_sec; + fs->e2fs.e2fs_wtime = time_second; else printf("%s: file system not clean; please fsck(8)\n", mp->mnt_stat.f_mntfromname); @@ -894,7 +894,7 @@ loop: */ if (fs->e2fs_fmod != 0) { fs->e2fs_fmod = 0; - fs->e2fs.e2fs_wtime = time.tv_sec; + fs->e2fs.e2fs_wtime = time_second; if ((error = ext2fs_cgupdate(ump, waitfor))) allerror = error; } @@ -1016,8 +1016,8 @@ ext2fs_vget(struct mount *mp, ino_t ino, */ if (ip->i_e2fs_gen == 0) { - if (++ext2gennumber < (u_long)time.tv_sec) - ext2gennumber = time.tv_sec; + if (++ext2gennumber < (u_long)time_second) + ext2gennumber = time_second; ip->i_e2fs_gen = ext2gennumber; if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) ip->i_flag |= IN_MODIFIED; Index: sys/ufs/ext2fs/ext2fs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vnops.c,v retrieving revision 1.63 diff -d -p -u -r1.63 ext2fs_vnops.c --- sys/ufs/ext2fs/ext2fs_vnops.c 2 Nov 2005 12:39:00 -0000 1.63 +++ sys/ufs/ext2fs/ext2fs_vnops.c 22 Nov 2005 13:44:41 -0000 @@ -1340,6 +1340,7 @@ int ext2fs_vinit(struct mount *mntp, int (**specops)(void *), int (**fifoops)(void *), struct vnode **vpp) { + struct timeval tv; struct inode *ip; struct vnode *vp, *nvp; @@ -1385,8 +1386,9 @@ ext2fs_vinit(struct mount *mntp, int (** /* * Initialize modrev times */ - SETHIGH(ip->i_modrev, mono_time.tv_sec); - SETLOW(ip->i_modrev, mono_time.tv_usec * 4294); + getmicrouptime(&tv); + SETHIGH(ip->i_modrev, tv.tv_sec); + SETLOW(ip->i_modrev, tv.tv_usec * 4294); *vpp = vp; return (0); } Index: sys/ufs/ffs/ffs_alloc.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_alloc.c,v retrieving revision 1.88 diff -d -p -u -r1.88 ffs_alloc.c --- sys/ufs/ffs/ffs_alloc.c 2 Nov 2005 12:39:00 -0000 1.88 +++ sys/ufs/ffs/ffs_alloc.c 22 Nov 2005 13:44:45 -0000 @@ -719,7 +719,7 @@ ffs_valloc(struct vnode *pvp, int mode, ip->i_gen++; DIP_ASSIGN(ip, gen, ip->i_gen); if (fs->fs_magic == FS_UFS2_MAGIC) { - nanotime(&ts); + getnanotime(&ts); ip->i_ffs2_birthtime = ts.tv_sec; ip->i_ffs2_birthnsec = ts.tv_nsec; } @@ -1037,10 +1037,10 @@ ffs_fragextend(struct inode *ip, int cg, brelse(bp); return (0); } - cgp->cg_old_time = ufs_rw32(time.tv_sec, UFS_FSNEEDSWAP(fs)); + cgp->cg_old_time = ufs_rw32(time_second, UFS_FSNEEDSWAP(fs)); if ((fs->fs_magic != FS_UFS1_MAGIC) || (fs->fs_old_flags & FS_FLAGS_UPDATED)) - cgp->cg_time = ufs_rw64(time.tv_sec, UFS_FSNEEDSWAP(fs)); + cgp->cg_time = ufs_rw64(time_second, UFS_FSNEEDSWAP(fs)); bno = dtogd(fs, bprev); blksfree = cg_blksfree(cgp, UFS_FSNEEDSWAP(fs)); for (i = numfrags(fs, osize); i < frags; i++) @@ -1108,10 +1108,10 @@ ffs_alloccg(struct inode *ip, int cg, da brelse(bp); return (0); } - cgp->cg_old_time = ufs_rw32(time.tv_sec, needswap); + cgp->cg_old_time = ufs_rw32(time_second, needswap); if ((fs->fs_magic != FS_UFS1_MAGIC) || (fs->fs_old_flags & FS_FLAGS_UPDATED)) - cgp->cg_time = ufs_rw64(time.tv_sec, needswap); + cgp->cg_time = ufs_rw64(time_second, needswap); if (size == fs->fs_bsize) { blkno = ffs_alloccgblk(ip, bp, bpref); ACTIVECG_CLR(fs, cg); @@ -1400,10 +1400,10 @@ ffs_nodealloccg(struct inode *ip, int cg brelse(bp); return (0); } - cgp->cg_old_time = ufs_rw32(time.tv_sec, needswap); + cgp->cg_old_time = ufs_rw32(time_second, needswap); if ((fs->fs_magic != FS_UFS1_MAGIC) || (fs->fs_old_flags & FS_FLAGS_UPDATED)) - cgp->cg_time = ufs_rw64(time.tv_sec, needswap); + cgp->cg_time = ufs_rw64(time_second, needswap); inosused = cg_inosused(cgp, needswap); if (ipref) { ipref %= fs->fs_ipg; @@ -1539,10 +1539,10 @@ ffs_blkfree(struct fs *fs, struct vnode brelse(bp); return; } - cgp->cg_old_time = ufs_rw32(time.tv_sec, needswap); + cgp->cg_old_time = ufs_rw32(time_second, needswap); if ((fs->fs_magic != FS_UFS1_MAGIC) || (fs->fs_old_flags & FS_FLAGS_UPDATED)) - cgp->cg_time = ufs_rw64(time.tv_sec, needswap); + cgp->cg_time = ufs_rw64(time_second, needswap); cgbno = dtogd(fs, bno); blksfree = cg_blksfree(cgp, needswap); if (size == fs->fs_bsize) { @@ -1735,10 +1735,10 @@ ffs_freefile(struct fs *fs, struct vnode brelse(bp); return (0); } - cgp->cg_old_time = ufs_rw32(time.tv_sec, needswap); + cgp->cg_old_time = ufs_rw32(time_second, needswap); if ((fs->fs_magic != FS_UFS1_MAGIC) || (fs->fs_old_flags & FS_FLAGS_UPDATED)) - cgp->cg_time = ufs_rw64(time.tv_sec, needswap); + cgp->cg_time = ufs_rw64(time_second, needswap); inosused = cg_inosused(cgp, needswap); ino %= fs->fs_ipg; if (isclr(inosused, ino)) { Index: sys/ufs/ffs/ffs_inode.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_inode.c,v retrieving revision 1.78 diff -d -p -u -r1.78 ffs_inode.c --- sys/ufs/ffs/ffs_inode.c 11 Nov 2005 15:50:57 -0000 1.78 +++ sys/ufs/ffs/ffs_inode.c 22 Nov 2005 13:44:46 -0000 @@ -649,16 +649,18 @@ ffs_itimes(struct inode *ip, const struc return; } + /* XXX just call getnanotime early and use result if needed? */ if (ip->i_flag & IN_ACCESS) { if (acc == NULL) - acc = ts == NULL ? (ts = nanotime(&tsb)) : ts; + acc = ts == NULL ? (getnanotime(&tsb), ts = &tsb) : ts; DIP_ASSIGN(ip, atime, acc->tv_sec); DIP_ASSIGN(ip, atimensec, acc->tv_nsec); } if (ip->i_flag & (IN_UPDATE | IN_MODIFY)) { if ((ip->i_flags & SF_SNAPSHOT) == 0) { if (mod == NULL) - mod = ts == NULL ? (ts = nanotime(&tsb)) : ts; + mod = ts == NULL ? + (getnanotime(&tsb), ts = &tsb) : ts; DIP_ASSIGN(ip, mtime, mod->tv_sec); DIP_ASSIGN(ip, mtimensec, mod->tv_nsec); } @@ -666,7 +668,7 @@ ffs_itimes(struct inode *ip, const struc } if (ip->i_flag & (IN_CHANGE | IN_MODIFY)) { if (cre == NULL) - cre = ts == NULL ? (ts = nanotime(&tsb)) : ts; + cre = ts == NULL ? (getnanotime(&tsb), ts = &tsb) : ts; DIP_ASSIGN(ip, ctime, cre->tv_sec); DIP_ASSIGN(ip, ctimensec, cre->tv_nsec); } Index: sys/ufs/ffs/ffs_snapshot.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_snapshot.c,v retrieving revision 1.22 diff -d -p -u -r1.22 ffs_snapshot.c --- sys/ufs/ffs/ffs_snapshot.c 2 Nov 2005 12:39:00 -0000 1.22 +++ sys/ufs/ffs/ffs_snapshot.c 22 Nov 2005 13:44:49 -0000 @@ -288,7 +288,7 @@ ffs_snapshot(struct mount *mp, struct vn goto out; } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - microtime(&starttime); + getmicrotime(&starttime); /* * First, copy all the cylinder group maps that have changed. */ @@ -519,7 +519,7 @@ out1: #ifdef DEBUG if (starttime.tv_sec > 0) { - microtime(&endtime); + getmicrotime(&endtime); timersub(&endtime, &starttime, &endtime); printf("%s: suspended %ld.%03ld sec, redo %ld of %d\n", vp->v_mount->mnt_stat.f_mntonname, (long)endtime.tv_sec, Index: sys/ufs/ffs/ffs_vfsops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.176 diff -d -p -u -r1.176 ffs_vfsops.c --- sys/ufs/ffs/ffs_vfsops.c 2 Nov 2005 12:39:00 -0000 1.176 +++ sys/ufs/ffs/ffs_vfsops.c 22 Nov 2005 13:44:52 -0000 @@ -443,7 +443,7 @@ ffs_mount(struct mount *mp, const char * if (fs->fs_fmod != 0) { /* XXX */ fs->fs_fmod = 0; if (fs->fs_clean & FS_WASCLEAN) - fs->fs_time = time.tv_sec; + fs->fs_time = time_second; else { printf("%s: file system not clean (fs_clean=%x); please fsck(8)\n", mp->mnt_stat.f_mntfromname, fs->fs_clean); @@ -1375,7 +1375,7 @@ loop: */ if (fs->fs_fmod != 0) { fs->fs_fmod = 0; - fs->fs_time = time.tv_sec; + fs->fs_time = time_second; if ((error = ffs_cgupdate(ump, waitfor))) allerror = error; } Index: sys/ufs/lfs/lfs_itimes.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/lfs_itimes.c,v retrieving revision 1.3 diff -d -p -u -r1.3 lfs_itimes.c --- sys/ufs/lfs/lfs_itimes.c 30 Oct 2005 23:34:34 -0000 1.3 +++ sys/ufs/lfs/lfs_itimes.c 22 Nov 2005 13:44:53 -0000 @@ -72,7 +72,7 @@ lfs_itimes(struct inode *ip, const struc if (ip->i_flag & IN_ACCESS) { #ifdef _KERNEL if (acc == NULL) - acc = ts == NULL ? (ts = nanotime(&tsb)) : ts; + acc = ts == NULL ? (getnanotime(&tsb), ts = &tsb) : ts; #endif ip->i_ffs1_atime = acc->tv_sec; ip->i_ffs1_atimensec = acc->tv_nsec; @@ -96,7 +96,8 @@ lfs_itimes(struct inode *ip, const struc if (ip->i_flag & (IN_UPDATE | IN_MODIFY)) { #ifdef _KERNEL if (mod == NULL) - mod = ts == NULL ? (ts = nanotime(&tsb)) : ts; + mod = ts == NULL ? + (getnanotime(&tsb), ts = &tsb) : ts; #endif ip->i_ffs1_mtime = mod->tv_sec; ip->i_ffs1_mtimensec = mod->tv_nsec; @@ -105,7 +106,8 @@ lfs_itimes(struct inode *ip, const struc if (ip->i_flag & (IN_CHANGE | IN_MODIFY)) { #ifdef _KERNEL if (cre == NULL) - cre = ts == NULL ? (ts = nanotime(&tsb)) : ts; + cre = ts == NULL ? + (getnanotime(&tsb), ts = &tsb) : ts; #endif ip->i_ffs1_ctime = cre->tv_sec; ip->i_ffs1_ctimensec = cre->tv_nsec; Index: sys/ufs/lfs/lfs_segment.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/lfs_segment.c,v retrieving revision 1.167 diff -d -p -u -r1.167 lfs_segment.c --- sys/ufs/lfs/lfs_segment.c 26 Sep 2005 13:52:20 -0000 1.167 +++ sys/ufs/lfs/lfs_segment.c 22 Nov 2005 13:44:57 -0000 @@ -168,7 +168,7 @@ lfs_imtime(struct lfs *fs) struct inode *ip; ASSERT_MAYBE_SEGLOCK(fs); - nanotime(&ts); + getnanotime(&ts); ip = VTOI(fs->lfs_ivnode); ip->i_ffs1_mtime = ts.tv_sec; ip->i_ffs1_mtimensec = ts.tv_nsec; @@ -1791,9 +1791,9 @@ lfs_writeseg(struct lfs *fs, struct segm sup->su_nbytes += ssp->ss_ninos * sizeof (struct ufs1_dinode); /* sup->su_nbytes += fs->lfs_sumsize; */ if (fs->lfs_version == 1) - sup->su_olastmod = time.tv_sec; + sup->su_olastmod = time_second; else - sup->su_lastmod = time.tv_sec; + sup->su_lastmod = time_second; sup->su_ninos += ninos; ++sup->su_nsums; fs->lfs_dmeta += (btofsb(fs, fs->lfs_sumsize) + btofsb(fs, ninos * @@ -1936,9 +1936,9 @@ lfs_writeseg(struct lfs *fs, struct segm } } if (fs->lfs_version == 1) - ssp->ss_ocreate = time.tv_sec; + ssp->ss_ocreate = time_second; else { - ssp->ss_create = time.tv_sec; + ssp->ss_create = time_second; ssp->ss_serial = ++fs->lfs_serial; ssp->ss_ident = fs->lfs_ident; } @@ -2107,8 +2107,8 @@ lfs_writesuper(struct lfs *fs, daddr_t d /* Set timestamp of this version of the superblock */ if (fs->lfs_version == 1) - fs->lfs_otstamp = time.tv_sec; - fs->lfs_tstamp = time.tv_sec; + fs->lfs_otstamp = time_second; + fs->lfs_tstamp = time_second; /* Checksum the superblock and copy it into a buffer. */ fs->lfs_cksum = lfs_sb_cksum(&(fs->lfs_dlfs)); Index: sys/ufs/lfs/lfs_syscalls.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/lfs_syscalls.c,v retrieving revision 1.107 diff -d -p -u -r1.107 lfs_syscalls.c --- sys/ufs/lfs/lfs_syscalls.c 25 May 2005 01:50:01 -0000 1.107 +++ sys/ufs/lfs/lfs_syscalls.c 22 Nov 2005 13:44:58 -0000 @@ -951,7 +951,7 @@ lfs_segwait(fsid_t *fsidp, struct timeva struct mount *mntp; void *addr; u_long timeout; - int error, s; + int error; if (fsidp == NULL || (mntp = vfs_getvfs(fsidp)) == NULL) addr = &lfs_allclean_wakeup; @@ -961,10 +961,7 @@ lfs_segwait(fsid_t *fsidp, struct timeva * XXX THIS COULD SLEEP FOREVER IF TIMEOUT IS {0,0}! * XXX IS THAT WHAT IS INTENDED? */ - s = splclock(); - timeradd(tv, &time, tv); - timeout = hzto(tv); - splx(s); + timeout = tvtohz(tv); error = tsleep(addr, PCATCH | PUSER, "segment", timeout); return (error == ERESTART ? EINTR : 0); } Index: sys/ufs/ufs/ufs_lookup.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_lookup.c,v retrieving revision 1.69 diff -d -p -u -r1.69 ufs_lookup.c --- sys/ufs/ufs/ufs_lookup.c 2 Nov 2005 12:39:14 -0000 1.69 +++ sys/ufs/ufs/ufs_lookup.c 22 Nov 2005 13:45:00 -0000 @@ -839,7 +839,7 @@ ufs_direnter(struct vnode *dvp, struct v if (softdep_setup_directory_add(bp, dp, dp->i_offset, ufs_rw32(dirp->d_ino, needswap), newdirbp, 1) == 0) { bdwrite(bp); - nanotime(&ts); + getnanotime(&ts); return UFS_UPDATE(dvp, &ts, &ts, UPDATE_DIROP); } /* We have just allocated a directory block in an @@ -864,7 +864,7 @@ ufs_direnter(struct vnode *dvp, struct v } else { error = VOP_BWRITE(bp); } - nanotime(&ts); + getnanotime(&ts); ret = UFS_UPDATE(dvp, &ts, &ts, UPDATE_DIROP); if (error == 0) return (ret); Index: sys/ufs/ufs/ufs_quota.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_quota.c,v retrieving revision 1.35 diff -d -p -u -r1.35 ufs_quota.c --- sys/ufs/ufs/ufs_quota.c 10 Jul 2005 00:18:52 -0000 1.35 +++ sys/ufs/ufs/ufs_quota.c 22 Nov 2005 13:45:02 -0000 @@ -178,14 +178,14 @@ chkdqchg(struct inode *ip, int64_t chang */ if (ncurblocks >= dq->dq_bsoftlimit && dq->dq_bsoftlimit) { if (dq->dq_curblocks < dq->dq_bsoftlimit) { - dq->dq_btime = time.tv_sec + ip->i_ump->um_btime[type]; + dq->dq_btime = time_second + ip->i_ump->um_btime[type]; if (ip->i_uid == cred->cr_uid) uprintf("\n%s: warning, %s %s\n", ITOV(ip)->v_mount->mnt_stat.f_mntonname, quotatypes[type], "disk quota exceeded"); return (0); } - if (time.tv_sec > dq->dq_btime) { + if (time_second > dq->dq_btime) { if ((dq->dq_flags & DQ_BLKS) == 0 && ip->i_uid == cred->cr_uid) { uprintf("\n%s: write failed, %s %s\n", @@ -284,14 +284,14 @@ chkiqchg(struct inode *ip, int32_t chang */ if (ncurinodes >= dq->dq_isoftlimit && dq->dq_isoftlimit) { if (dq->dq_curinodes < dq->dq_isoftlimit) { - dq->dq_itime = time.tv_sec + ip->i_ump->um_itime[type]; + dq->dq_itime = time_second + ip->i_ump->um_itime[type]; if (ip->i_uid == cred->cr_uid) uprintf("\n%s: warning, %s %s\n", ITOV(ip)->v_mount->mnt_stat.f_mntonname, quotatypes[type], "inode quota exceeded"); return (0); } - if (time.tv_sec > dq->dq_itime) { + if (time_second > dq->dq_itime) { if ((dq->dq_flags & DQ_INODS) == 0 && ip->i_uid == cred->cr_uid) { uprintf("\n%s: write failed, %s %s\n", @@ -505,11 +505,11 @@ setquota(struct mount *mp, u_long id, in if (newlim.dqb_bsoftlimit && dq->dq_curblocks >= newlim.dqb_bsoftlimit && (dq->dq_bsoftlimit == 0 || dq->dq_curblocks < dq->dq_bsoftlimit)) - newlim.dqb_btime = time.tv_sec + ump->um_btime[type]; + newlim.dqb_btime = time_second + ump->um_btime[type]; if (newlim.dqb_isoftlimit && dq->dq_curinodes >= newlim.dqb_isoftlimit && (dq->dq_isoftlimit == 0 || dq->dq_curinodes < dq->dq_isoftlimit)) - newlim.dqb_itime = time.tv_sec + ump->um_itime[type]; + newlim.dqb_itime = time_second + ump->um_itime[type]; dq->dq_dqb = newlim; if (dq->dq_curblocks < dq->dq_bsoftlimit) dq->dq_flags &= ~DQ_BLKS; @@ -553,10 +553,10 @@ setuse(struct mount *mp, u_long id, int */ if (dq->dq_bsoftlimit && dq->dq_curblocks < dq->dq_bsoftlimit && usage.dqb_curblocks >= dq->dq_bsoftlimit) - dq->dq_btime = time.tv_sec + ump->um_btime[type]; + dq->dq_btime = time_second + ump->um_btime[type]; if (dq->dq_isoftlimit && dq->dq_curinodes < dq->dq_isoftlimit && usage.dqb_curinodes >= dq->dq_isoftlimit) - dq->dq_itime = time.tv_sec + ump->um_itime[type]; + dq->dq_itime = time_second + ump->um_itime[type]; dq->dq_curblocks = usage.dqb_curblocks; dq->dq_curinodes = usage.dqb_curinodes; if (dq->dq_curblocks < dq->dq_bsoftlimit) @@ -792,9 +792,9 @@ dqget(struct vnode *vp, u_long id, struc dq->dq_flags |= DQ_FAKE; if (dq->dq_id != 0) { if (dq->dq_btime == 0) - dq->dq_btime = time.tv_sec + ump->um_btime[type]; + dq->dq_btime = time_second + ump->um_btime[type]; if (dq->dq_itime == 0) - dq->dq_itime = time.tv_sec + ump->um_itime[type]; + dq->dq_itime = time_second + ump->um_itime[type]; } *dqp = dq; return (0); Index: sys/ufs/ufs/ufs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vnops.c,v retrieving revision 1.137 diff -d -p -u -r1.137 ufs_vnops.c --- sys/ufs/ufs/ufs_vnops.c 11 Nov 2005 15:50:57 -0000 1.137 +++ sys/ufs/ufs/ufs_vnops.c 22 Nov 2005 13:45:05 -0000 @@ -1981,6 +1981,7 @@ void ufs_vinit(struct mount *mntp, int (**specops)(void *), int (**fifoops)(void *), struct vnode **vpp) { + struct timeval tv; struct inode *ip; struct vnode *vp, *nvp; dev_t rdev; @@ -2035,8 +2036,9 @@ ufs_vinit(struct mount *mntp, int (**spe /* * Initialize modrev times */ - ip->i_modrev = (uint64_t)(uint)mono_time.tv_sec << 32 - | mono_time.tv_usec * 4294u; + getmicrouptime(&tv); + ip->i_modrev = (uint64_t)(uint)tv.tv_sec << 32 + | tv.tv_usec * 4294u; *vpp = vp; } Index: sys/uvm/uvm_meter.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_meter.c,v retrieving revision 1.36 diff -d -p -u -r1.36 uvm_meter.c --- sys/uvm/uvm_meter.c 9 Nov 2005 12:47:39 -0000 1.36 +++ sys/uvm/uvm_meter.c 22 Nov 2005 13:45:05 -0000 @@ -81,7 +81,7 @@ static void uvm_total(struct vmtotal *); void uvm_meter(void) { - if ((time.tv_sec % 5) == 0) + if ((time_second % 5) == 0) uvm_loadav(&averunnable); if (lwp0.l_slptime > (maxslp / 2)) wakeup(&proc0); Index: usr.bin/vmstat/vmstat.c =================================================================== RCS file: /cvsroot/src/usr.bin/vmstat/vmstat.c,v retrieving revision 1.138 diff -d -p -u -r1.138 vmstat.c --- usr.bin/vmstat/vmstat.c 22 Oct 2005 15:32:48 -0000 1.138 +++ usr.bin/vmstat/vmstat.c 22 Nov 2005 13:45:14 -0000 @@ -158,8 +158,12 @@ struct nlist namelist[] = { "_pool_head" }, #define X_UVMEXP 8 { "_uvmexp" }, -#define X_TIME 9 - { "_time" }, +#define X_TIME_SECOND 9 +#ifdef __HAVE_TIMECOUNTER + { "_time_second" }, +#else + { "_time" }, /* XXX uses same array slot as "X_TIME_SECOND" */ +#endif #define X_NL_SIZE 10 { NULL }, }; @@ -552,9 +556,13 @@ getuptime(void) if (boottime.tv_sec == 0) kread(namelist, X_BOOTTIME, &boottime, sizeof(boottime)); - kread(namelist, X_TIME, &now, sizeof(now)); - timersub(&now, &boottime, &diff); - uptime = diff.tv_sec; +#ifdef __HAVE_TIMECOUNTER + kread(namelist, X_TIME_SECOND, &now.tv_sec, sizeof(now)); + now.tv_usec = 0; +#else + kread(namelist, X_TIME_SECOND, &now, sizeof(now)); +#endif + uptime = now - boottime.tv_sec; if (uptime <= 0 || uptime > 60*60*24*365*10) errx(1, "time makes no sense; namelist must be wrong."); return (uptime); Index: usr.sbin/ntp/include/config.h =================================================================== RCS file: /cvsroot/src/usr.sbin/ntp/include/config.h,v retrieving revision 1.9 diff -d -p -u -r1.9 config.h --- usr.sbin/ntp/include/config.h 17 Jul 2005 12:46:51 -0000 1.9 +++ usr.sbin/ntp/include/config.h 22 Nov 2005 13:45:19 -0000 @@ -1,4 +1,4 @@ -/* $NetBSD: config.h,v 1.9 2005/07/17 12:46:51 he Exp $ */ +/* $NetBSD$ */ /* manually edited - check "XXX" comments */ /* config.h. Generated by configure. */ @@ -363,7 +363,8 @@ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `isfinite' function. */ -/* #undef HAVE_ISFINITE */ +/* XXX unused in code - force an error to ensure portability */ +#define HAVE_ISFINITE nonsense /* Define to 1 if you have the `kvm_open' function. */ #define HAVE_KVM_OPEN 1 @@ -630,10 +631,14 @@ #define HAVE_STRSTR 1 /* Do we have struct ntptimeval? */ -#define HAVE_STRUCT_NTPTIMEVAL 1 +#ifdef __HAVE_TIMECOUNTER /* XXX */ +#define HAVE_STRUCT_NTPTIMEVAL 1 /* XXX */ +#else /* XXX */ +/* #undef HAVE_STRUCT_NTPTIMEVAL_TIME_TV_NSEC */ /* XXX */ +#endif /* XXX */ /* Define to 1 if `time.tv_nsec' is member of `struct ntptimeval'. */ -/* #undef HAVE_STRUCT_NTPTIMEVAL_TIME_TV_NSEC */ +#define HAVE_STRUCT_NTPTIMEVAL_TIME_TV_NSEC 1 /* Does a system header define struct ppsclockev? */ /* #undef HAVE_STRUCT_PPSCLOCKEV */ @@ -720,7 +725,8 @@ #define HAVE_SYS_SOCKIO_H 1 /* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SOUNDCARD_H */ +/* XXX enable for some/all ports? */ +/* #define HAVE_SYS_SOUNDCARD_H 1 */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 @@ -927,7 +933,7 @@ /* #undef NO_PARENB_IGNPAR */ /* Default location of crypto key info */ -#define NTP_KEYSDIR "/etc/ntp" +#define NTP_KEYSDIR "/etc/ntp" /* XXX fix path */ /* Do we have ntp_{adj,get}time in libc? */ #define NTP_SYSCALLS_LIBC 1 @@ -1032,7 +1038,7 @@ /* #undef STREAMS_TLI */ /* canonical system (cpu-vendor-os) string */ -#define STR_SYSTEM "i386--netbsd2" +#define STR_SYSTEM "i386--netbsd3" /* XXX use MACHINE_ARCH or similar? */ /* Buggy syscall() (Solaris2.4)? */ /* #undef SYSCALL_BUG */ @@ -1068,6 +1074,7 @@ #define ULONG_CONST(a) a ## UL /* Must we have a CTTY for fsetown? */ +/* XXX not needed with current tty handling code */ /* #define USE_FSETOWNCTTY 1 */ /* Can we use SIGPOLL for tty IO? */ @@ -1079,8 +1086,8 @@ /* Version number of package */ #define VERSION "4.2.0" -#if 0 /* We'll define this in each Makefile as necessary */ /* ISC: Want IPv6? */ +#if 0 /* XXX We'll define this in each Makefile as necessary */ #define WANT_IPV6 #endif Index: usr.sbin/ntp/scripts/mkver =================================================================== RCS file: /cvsroot/src/usr.sbin/ntp/scripts/mkver,v retrieving revision 1.3 diff -d -p -u -r1.3 mkver --- usr.sbin/ntp/scripts/mkver 4 Dec 2003 16:41:57 -0000 1.3 +++ usr.sbin/ntp/scripts/mkver 22 Nov 2005 13:45:19 -0000 @@ -1,5 +1,5 @@ #!/bin/sh -# $NetBSD: mkver,v 1.3 2003/12/04 16:41:57 drochner Exp $ +# $NetBSD$ PROG=${1-UNKNOWN}