? ID Index: 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 --- arch/i386/acpi/acpi_wakeup.c 2 May 2005 14:54:46 -0000 1.16 +++ arch/i386/acpi/acpi_wakeup.c 26 Oct 2005 14:24:50 -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: arch/i386/conf/files.i386 =================================================================== RCS file: /cvsroot/src/sys/arch/i386/conf/files.i386,v retrieving revision 1.272 diff -d -p -u -r1.272 files.i386 --- arch/i386/conf/files.i386 7 Oct 2005 15:59:49 -0000 1.272 +++ arch/i386/conf/files.i386 26 Oct 2005 14:24:51 -0000 @@ -77,7 +77,7 @@ 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 kern/kern_microtime.c !timecounters & (i586_cpu | i686_cpu) file arch/i386/i386/mtrr_k6.c mtrr file netns/ns_cksum.c ns file arch/i386/i386/pmap.c @@ -86,6 +86,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 timecounters file arch/i386/i386/vm_machdep.c file dev/cons.c @@ -189,6 +190,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 & timecounters + # PCI-EISA bridges device pceb: eisabus, isabus attach pceb at pci Index: arch/i386/conf/std.i386 =================================================================== RCS file: /cvsroot/src/sys/arch/i386/conf/std.i386,v retrieving revision 1.25 diff -d -p -u -r1.25 std.i386 --- arch/i386/conf/std.i386 17 Sep 2005 09:44:07 -0000 1.25 +++ arch/i386/conf/std.i386 26 Oct 2005 14:24:51 -0000 @@ -14,3 +14,5 @@ options INET6_MD_CKSUM # machine-depend #options CRYPTO_MD_DES_CBC # machine-dependant DES CBC code #options CRYPTO_MD_BF_ENC # machine-dependant code for BF_encrypt #options CRYPTO_MD_BF_CBC # careful: uses bswapl, requires 486 + +options TIMECOUNTERS Index: 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 --- arch/i386/i386/apm.c 1 Jun 2005 16:49:14 -0000 1.87 +++ arch/i386/i386/apm.c 26 Oct 2005 14:24:51 -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: 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 --- arch/i386/i386/cpu.c 7 Jul 2005 13:20:53 -0000 1.24 +++ arch/i386/i386/cpu.c 26 Oct 2005 14:24:51 -0000 @@ -409,7 +409,7 @@ cpu_init(ci) if (ci->ci_cpu_class >= CPUCLASS_486) lcr0(rcr0() | CR0_WP); #endif -#if defined(I586_CPU) || defined(I686_CPU) +#if !defined(__HAVE_TIMECOUNTER) && (defined(I586_CPU) || defined(I686_CPU)) #ifndef NO_TSC_TIME /* * On systems with a cycle counter, use that for @@ -420,8 +420,8 @@ cpu_init(ci) if (cpu_feature & CPUID_TSC) { microtime_func = cc_microtime; } -#endif -#endif +#endif /* !NO_TSC_TIME */ +#endif /* !__HAVE_TIMECOUNTER && (I586_CPU || I686_CPU) */ #if defined(I686_CPU) /* * On a P6 or above, enable global TLB caching if the @@ -624,10 +624,10 @@ 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 !defined(__HAVE_TIMECOUNTER) && (defined(I586_CPU) || defined(I686_CPU)) if (ci->ci_feature_flags & CPUID_TSC) cc_microset(ci); -#endif +#endif /* !__HAVE_TIMECOUNTER && (I586_CPU || I686_CPU) */ microtime(&ci->ci_schedstate.spc_runtime); splx(s); } Index: 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 --- arch/i386/i386/ipifuncs.c 14 Jul 2003 22:13:10 -0000 1.10 +++ arch/i386/i386/ipifuncs.c 26 Oct 2005 14:24:51 -0000 @@ -86,7 +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) +#if !defined(__HAVE_TIMECOUNTER) && (defined(I586_CPU) || defined(I686_CPU)) cc_microset, #else 0, Index: 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 --- arch/i386/i386/machdep.c 22 Sep 2005 07:13:27 -0000 1.565 +++ arch/i386/i386/machdep.c 26 Oct 2005 14:24:52 -0000 @@ -255,8 +255,10 @@ 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; +#ifndef __HAVE_TIMECOUNTER +timecounters void (*microtime_func)(struct timeval *) = i8254_microtime; +#endif /* !__HAVE_TIMECOUNTER */ +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 +2286,13 @@ cpu_setmcontext(struct lwp *l, const mco void cpu_initclocks() { + (*initclock_func)(); +#if 0 /* XXX kardel XXX */ +#ifdef __HAVE_TIMECOUNTER + init_TSC_tc(); +#endif +#endif /* XXX kardel XXX */ } #ifdef MULTIPROCESSOR Index: arch/i386/i386/math_emulate.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/math_emulate.c,v retrieving revision 1.29 diff -d -p -u -r1.29 math_emulate.c --- arch/i386/i386/math_emulate.c 30 May 2005 04:12:41 -0000 1.29 +++ arch/i386/i386/math_emulate.c 26 Oct 2005 14:24:53 -0000 @@ -88,11 +88,8 @@ math_emulate(info, ksi) temp_real tmp; char * address; u_long oldeip; - int override_seg, override_addrsize, override_datasize; int prefix; - override_seg = override_addrsize = override_datasize = 0; - if (!USERMODE(info->tf_cs, info->tf_eflags)) panic("math emulator called from supervisor mode"); @@ -133,13 +130,13 @@ math_emulate(info, ksi) case INSPREF_ES: case INSPREF_FS: case INSPREF_GS: - override_seg = prefix; + /* override segment */ break; case INSPREF_OSIZE: - override_datasize = prefix; + /* override data size */ break; case INSPREF_ASIZE: - override_addrsize = prefix; + /* override address size */ break; case -1: math_abort(info, ksi, SIGSEGV, SEGV_ACCERR); Index: arch/i386/i386/microtime.S =================================================================== RCS file: /cvsroot/src/sys/arch/i386/i386/microtime.S,v retrieving revision 1.3 diff -d -p -u -r1.3 microtime.S --- arch/i386/i386/microtime.S 7 Aug 2003 16:27:55 -0000 1.3 +++ arch/i386/i386/microtime.S 26 Oct 2005 14:24:53 -0000 @@ -1,3 +1,4 @@ +/* XXXXXXXXXXXXXXXXXXXXXX delete after converstion to timecounters */ /* $NetBSD: microtime.S,v 1.3 2003/08/07 16:27:55 agc Exp $ */ /*- @@ -29,10 +30,13 @@ * SUCH DAMAGE. */ +#include "opt_timecounters.h" + #include #include #include +#ifndef TIMECOUNTERS #include "assym.h" /* LINTSTUB: include */ @@ -116,3 +120,4 @@ ENTRY(i8254_microtime) popl %ebx popl %edi ret +#endif /* TIMECOUNTERS */ Index: 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 --- arch/i386/i386/svr4_machdep.c 12 Mar 2005 16:33:45 -0000 1.75 +++ arch/i386/i386/svr4_machdep.c 26 Oct 2005 14:24:53 -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: arch/i386/i386/tsc.c =================================================================== RCS file: arch/i386/i386/tsc.c diff -N arch/i386/i386/tsc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ arch/i386/i386/tsc.c 26 Oct 2005 14:24:53 -0000 @@ -0,0 +1,168 @@ +/* $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); +} + +#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 */ + +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 + /* + * 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 (mp_ncpus > 1 && !smp_tsc) + 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: arch/i386/include/clock.h =================================================================== RCS file: arch/i386/include/clock.h diff -N arch/i386/include/clock.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ arch/i386/include/clock.h 26 Oct 2005 14:24:56 -0000 @@ -0,0 +1,6 @@ +/* $NetBSD$ */ + +/* XXX copyright */ + +void init_TSC(void); +void init_TSC_tc(void); Index: 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 --- arch/i386/include/cpu.h 11 Aug 2005 20:32:55 -0000 1.118 +++ arch/i386/include/cpu.h 26 Oct 2005 14:24:56 -0000 @@ -296,11 +296,15 @@ struct clockframe { */ extern void (*delay_func)(int); struct timeval; +#ifndef __HAVE_TIMECOUNTER extern void (*microtime_func)(struct timeval *); +#endif /* __HAVE_TIMECOUNTER */ #define DELAY(x) (*delay_func)(x) #define delay(x) (*delay_func)(x) +#ifndef __HAVE_TIMECOUNTER #define microtime(tv) (*microtime_func)(tv) +#endif /* __HAVE_TIMECOUNTER */ /* * pull in #defines for kinds of processors Index: 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 --- arch/i386/include/types.h 18 Jan 2004 18:23:19 -0000 1.45 +++ arch/i386/include/types.h 26 Oct 2005 14:24:56 -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: 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 --- arch/i386/isa/clock.c 29 May 2005 21:58:41 -0000 1.87 +++ arch/i386/isa/clock.c 26 Oct 2005 14:24:57 -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,29 @@ 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); +#ifdef __HAVE_TIMECOUNTER +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 */ +}; +#endif /* __HAVE_TIMECOUNTER */ + /* XXX use sc? */ __inline u_int mc146818_read(void *sc, u_int reg) @@ -420,12 +442,18 @@ startrtclock(void) printf("RTC BIOS diagnostic error %s\n", bitmask_snprintf(s, NVRAM_DIAG_BITS, bits, sizeof(bits))); } + +#ifdef __HAVE_TIMECOUNTER + tc_init(&i8254_timecounter); + + init_TSC(); +#endif /* __HAVE_TIMECOUNTER */ } int clockintr(void *arg, struct intrframe frame) { -#if defined(I586_CPU) || defined(I686_CPU) +#if !defined(__HAVE_TIMECOUNTER) && (defined(I586_CPU) || defined(I686_CPU)) static int microset_iter; /* call cc_microset once/sec */ struct cpu_info *ci = curcpu(); @@ -438,7 +466,7 @@ clockintr(void *arg, struct intrframe fr CPU_IS_PRIMARY(ci) && #endif (microset_iter--) == 0) { - cc_microset_time = time; + getmicrotime(&cc_microset_time); microset_iter = hz - 1; #if defined(MULTIPROCESSOR) x86_broadcast_ipi(X86_IPI_MICROSET); @@ -446,7 +474,7 @@ clockintr(void *arg, struct intrframe fr cc_microset(ci); } } -#endif +#endif /* !__HAVE_TIMECOUNTER && (I586_CPU || I686_CPU) */ hardclock((struct clockframe *)&frame); @@ -459,6 +487,38 @@ clockintr(void *arg, struct intrframe fr return -1; } +#ifdef __HAVE_TIMECOUNTER +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); +} +#endif /* __HAVE_TIMECOUNTER */ + int gettick(void) { @@ -594,14 +654,17 @@ sysbeep(int pitch, int period) #endif } +#if 0 /* XXXXXXXXXXXXXXXXXXXXXXXX not needed for timecounters?? XXXXXXXXXX */ #ifdef NTP extern int fixtick; /* XXX */ #endif /* NTP */ +#endif /* XXXXXXXXXXXXXXXXXXXXXXXX not needed for timecounters?? XXXXXXXXXX */ void i8254_initclocks(void) { +#if 0 /* XXXXXXXXXXXXXXXXXXXXXXXX not needed for timecounters?? XXXXXXXXXX */ #ifdef NTP /* * we'll actually get (TIMER_FREQ/rtclock_tval) interrupts/sec. @@ -609,6 +672,7 @@ i8254_initclocks(void) fixtick = 1000000 - ((int64_t)tick * TIMER_FREQ + rtclock_tval / 2) / rtclock_tval; #endif /* NTP */ +#endif /* XXXXXXXXXXXXXXXXXXXXXXXX not needed for timecounters?? XXXXXXXXXX */ /* * XXX If you're doing strange things with multiple clocks, you might @@ -616,6 +680,8 @@ i8254_initclocks(void) */ (void)isa_intr_establish(NULL, 0, IST_PULSE, IPL_CLOCK, (int (*)(void *))clockintr, 0); + + init_TSC_tc(); } void @@ -782,8 +848,9 @@ inittodr(time_t base) { mc_todregs rtclk; struct clock_ymdhms dt; + struct timespec ts; int s; -#if defined(I586_CPU) || defined(I686_CPU) +#if !defined(__HAVE_TIMECOUNTER) && (defined(I586_CPU) || defined(I686_CPU)) struct cpu_info *ci = curcpu(); #endif /* @@ -844,20 +911,24 @@ inittodr(time_t base) } } - time.tv_sec = clock_ymdhms_to_secs(&dt) + rtc_offset * 60; +#ifdef __HAVE_TIMECOUNTER + ts.tv_sec = clock_ymdhms_to_secs(&dt) + rtc_offset * 60; + ts.tv_nsec = 0; + tc_setclock(&ts); +#endif /* __HAVE_TIMECOUNTER */ #ifdef DEBUG_CLOCK printf("readclock: %ld (%ld)\n", time.tv_sec, base); #endif -#if defined(I586_CPU) || defined(I686_CPU) +#if !defined(__HAVE_TIMECOUNTER) && (defined(I586_CPU) || defined(I686_CPU)) if (ci->ci_feature_flags & CPUID_TSC) { - cc_microset_time = time; + getmicrotime(&cc_microset_time); cc_microset(ci); } -#endif +#endif /* !__HAVE_TIMECOUNTER && (I586_CPU || I686_CPU) */ - 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 +939,11 @@ inittodr(time_t base) fstime: timeset = 1; - time.tv_sec = base; +#ifdef __HAVE_TIMECOUNTER + ts.tv_sec = base; + ts.tv_nsec = 0; + tc_setclock(&ts); +#endif /* __HAVE_TIMECOUNTER */ printf("WARNING: CHECK AND RESET THE DATE!\n"); } @@ -895,7 +970,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: arch/i386/pci/geodecntr.c =================================================================== RCS file: arch/i386/pci/geodecntr.c diff -N arch/i386/pci/geodecntr.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ arch/i386/pci/geodecntr.c 26 Oct 2005 14:24:57 -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: 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 --- arch/x86/x86/lapic.c 29 May 2005 21:36:40 -0000 1.12 +++ arch/x86/x86/lapic.c 26 Oct 2005 14:24:59 -0000 @@ -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,7 +259,7 @@ lapic_clockintr(void *arg, struct intrfr cc_microset(ci); } } -#endif +#endif /* !__HAVE_TIMECOUNTER && (I586_CPU || I686_CPU || __x86_64__) */ hardclock((struct clockframe *)&frame); } Index: 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 --- arch/x86/x86/mtrr_i686.c 1 Nov 2003 17:00:50 -0000 1.3 +++ arch/x86/x86/mtrr_i686.c 26 Oct 2005 14:24:59 -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: compat/linux/common/linux_misc.c =================================================================== RCS file: /cvsroot/src/sys/compat/linux/common/linux_misc.c,v retrieving revision 1.140 diff -d -p -u -r1.140 linux_misc.c --- compat/linux/common/linux_misc.c 10 Sep 2005 19:20:50 -0000 1.140 +++ compat/linux/common/linux_misc.c 26 Oct 2005 14:24:59 -0000 @@ -722,7 +722,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; @@ -739,9 +739,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; @@ -1558,10 +1556,12 @@ linux_sys_sysinfo(l, v, retval) struct linux_sys_sysinfo_args /* { syscallarg(struct linux_sysinfo *) arg; } */ *uap = v; + struct bintime bt; struct linux_sysinfo si; struct loadavg *la; - si.uptime = time.tv_sec - boottime.tv_sec; + getbinuptime(&bt); + si.uptime = bt.sec; 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: 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 --- compat/linux/common/linux_misc_notalpha.c 3 May 2005 16:26:28 -0000 1.74 +++ compat/linux/common/linux_misc_notalpha.c 26 Oct 2005 14:25:00 -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: conf/files =================================================================== RCS file: /cvsroot/src/sys/conf/files,v retrieving revision 1.738 diff -d -p -u -r1.738 files --- conf/files 21 Oct 2005 04:07:48 -0000 1.738 +++ conf/files 26 Oct 2005 14:25:00 -0000 @@ -14,15 +14,16 @@ devclass tty # (note, these are case-sensitive) # defflag INSECURE -defflag MBUFTRACE -defflag KMEMSTATS defflag KCONT +defflag KMEMSTATS defflag KTRACE +defflag MBUFTRACE defflag SYSTRACE +defflag TIMECOUNTERS +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 +1248,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 timecounters file kern/kern_time.c file kern/kern_timeout.c file kern/kern_uuid.c Index: 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 --- contrib/dev/ic/athhal_osdep.c 19 Oct 2005 09:04:23 -0000 1.5 +++ contrib/dev/ic/athhal_osdep.c 26 Oct 2005 14:25:01 -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: dev/clockctl.c =================================================================== RCS file: /cvsroot/src/sys/dev/clockctl.c,v retrieving revision 1.13 diff -d -p -u -r1.13 clockctl.c --- dev/clockctl.c 27 Feb 2005 00:26:58 -0000 1.13 +++ dev/clockctl.c 26 Oct 2005 14:25:01 -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: dev/mm.c =================================================================== RCS file: /cvsroot/src/sys/dev/mm.c,v retrieving revision 1.6 diff -d -p -u -r1.6 mm.c --- dev/mm.c 20 Dec 2003 16:22:14 -0000 1.6 +++ dev/mm.c 26 Oct 2005 14:25:01 -0000 @@ -78,6 +78,6 @@ mmioctl(dev, cmd, data, flag, p) return 0; /*FALLTHROUGH*/ } - return EOPNOTSUPP; + return EOPNOTSUPP; /* XXXsimonb: ENOTTY here too? */ } } Index: dev/ic/com.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/com.c,v retrieving revision 1.236 diff -d -p -u -r1.236 com.c --- dev/ic/com.c 6 Sep 2005 21:40:39 -0000 1.236 +++ dev/ic/com.c 26 Oct 2005 14:25:02 -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: 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 --- dev/ic/comvar.h 4 Feb 2005 02:10:36 -0000 1.48 +++ dev/ic/comvar.h 26 Oct 2005 14:25:02 -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: 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 --- dev/ic/hd64570.c 27 Feb 2005 00:27:01 -0000 1.29 +++ dev/ic/hd64570.c 26 Oct 2005 14:25:03 -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: 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 --- dev/ic/icp.c 25 Aug 2005 22:33:19 -0000 1.16 +++ dev/ic/icp.c 26 Oct 2005 14:25:03 -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: 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 --- dev/ic/mlx.c 25 Aug 2005 22:33:19 -0000 1.36 +++ dev/ic/mlx.c 26 Oct 2005 14:25:04 -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; @@ -1001,7 +982,7 @@ mlx_periodic(struct mlx_softc *mlx) int etype, s; time_t ct; - ct = mlx_curtime(); + ct = time_second; if ((mlx->mlx_pause.mp_which != 0) && (mlx->mlx_pause.mp_when > 0) && @@ -1481,7 +1462,7 @@ mlx_pause_action(struct mlx_softc *mlx) int failsafe, i, cmd; time_t ct; - ct = mlx_curtime(); + ct = time_second; /* What are we doing here? */ if (mlx->mlx_pause.mp_when == 0) { @@ -1542,7 +1523,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 +2068,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: dev/ic/ncr53c9x.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/ncr53c9x.c,v retrieving revision 1.115 diff -d -p -u -r1.115 ncr53c9x.c --- dev/ic/ncr53c9x.c 30 May 2005 04:43:47 -0000 1.115 +++ dev/ic/ncr53c9x.c 26 Oct 2005 14:25:05 -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: 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 --- dev/ic/nslm7x.c 15 Oct 2005 00:41:48 -0000 1.23 +++ dev/ic/nslm7x.c 26 Oct 2005 14:25:06 -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: 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 --- dev/ic/z8530tty.c 6 Sep 2005 21:40:39 -0000 1.100 +++ dev/ic/z8530tty.c 26 Oct 2005 14:25:06 -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: 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 --- dev/pci/amr.c 26 Aug 2005 11:20:33 -0000 1.29 +++ dev/pci/amr.c 26 Oct 2005 14:25:07 -0000 @@ -809,11 +809,11 @@ amr_thread_create(void *cookie) static void amr_thread(void *cookie) { + struct bintime bt; struct amr_softc *amr; struct amr_ccb *ac; struct amr_logdrive *al; struct amr_enquiry *ae; - time_t curtime; int rv, i, s; amr = cookie; @@ -830,10 +830,10 @@ amr_thread(void *cookie) s = splbio(); amr_intr(cookie); - curtime = (time_t)mono_time.tv_sec; + getbinuptime(&bt); 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 > bt.sec) break; if ((ac->ac_flags & AC_MOAN) == 0) { printf("%s: ccb %d timed out; mailbox:\n", @@ -1143,6 +1143,7 @@ amr_mbox_wait(struct amr_softc *amr) static int amr_quartz_submit(struct amr_softc *amr, struct amr_ccb *ac) { + struct bintime bt; u_int32_t v; amr->amr_mbox->mb_poll = 0; @@ -1169,7 +1170,8 @@ 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; + getbinuptime(&bt); + ac->ac_start_time = bt.sec; ac->ac_flags |= AC_ACTIVE; amr_outl(amr, AMR_QREG_IDB, (amr->amr_mbox_paddr + 16) | AMR_QIDB_SUBMIT); @@ -1179,6 +1181,7 @@ amr_quartz_submit(struct amr_softc *amr, static int amr_std_submit(struct amr_softc *amr, struct amr_ccb *ac) { + struct bintime bt; amr->amr_mbox->mb_poll = 0; amr->amr_mbox->mb_ack = 0; @@ -1203,7 +1206,8 @@ 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; + getbinuptime(&bt); + ac->ac_start_time = bt.sec; ac->ac_flags |= AC_ACTIVE; amr_outb(amr, AMR_SREG_CMD, AMR_SCMD_POST); return (0); Index: dev/pci/files.pci =================================================================== RCS file: /cvsroot/src/sys/dev/pci/files.pci,v retrieving revision 1.240 diff -d -p -u -r1.240 files.pci --- dev/pci/files.pci 18 Oct 2005 17:53:14 -0000 1.240 +++ dev/pci/files.pci 26 Oct 2005 14:25:07 -0000 @@ -468,10 +468,13 @@ attach joy at eso with joy_eso file dev/pci/joy_eso.c joy_eso # ESS Maestro-1/2/2e PCI AC97 Audio Accelerator -device esm: audiobus, auconv, mulaw, ac97 +device esm { }: audiobus, auconv, mulaw, ac97 attach esm at pci file dev/pci/esm.c esm +attach mpu at esm with mpu_esm +file dev/pci/mpu_esm.c mpu_esm + # S3 SonicVibes (S3 617) device sv { }: audiobus, auconv, mulaw, midibus attach sv at pci Index: dev/pci/pccbb.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/pccbb.c,v retrieving revision 1.125 diff -d -p -u -r1.125 pccbb.c --- dev/pci/pccbb.c 9 Sep 2005 14:50:58 -0000 1.125 +++ dev/pci/pccbb.c 26 Oct 2005 14:25:08 -0000 @@ -2447,6 +2447,7 @@ pccbb_pcmcia_socket_enable(pch) spsr = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_STAT); +printf(" spsr read 1 = 0x%08x\n", spsr); if (spsr & CB_SOCKET_STAT_5VCARD) { DPRINTF(("5V card\n")); voltage = CARDBUS_VCC_5V | CARDBUS_VPP_VCC; Index: 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 --- dev/pci/viaenv.c 23 Oct 2005 14:01:36 -0000 1.12 +++ dev/pci/viaenv.c 26 Oct 2005 14:25:09 -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: dev/pckbport/pms.c =================================================================== RCS file: /cvsroot/src/sys/dev/pckbport/pms.c,v retrieving revision 1.6 diff -d -p -u -r1.6 pms.c --- dev/pckbport/pms.c 27 Feb 2005 00:27:42 -0000 1.6 +++ dev/pckbport/pms.c 26 Oct 2005 14:25:09 -0000 @@ -492,16 +492,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: dev/pckbport/synaptics.c =================================================================== RCS file: /cvsroot/src/sys/dev/pckbport/synaptics.c,v retrieving revision 1.6 diff -d -p -u -r1.6 synaptics.c --- dev/pckbport/synaptics.c 20 Jun 2005 02:49:19 -0000 1.6 +++ dev/pckbport/synaptics.c 26 Oct 2005 14:25:09 -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: dev/pcmcia/pcmcia_cis.c =================================================================== RCS file: /cvsroot/src/sys/dev/pcmcia/pcmcia_cis.c,v retrieving revision 1.39 diff -d -p -u -r1.39 pcmcia_cis.c --- dev/pcmcia/pcmcia_cis.c 27 Feb 2005 00:27:43 -0000 1.39 +++ dev/pcmcia/pcmcia_cis.c 26 Oct 2005 14:25:10 -0000 @@ -217,10 +217,8 @@ pcmcia_scan_cis(dev, fct, arg) /* Call the function for the END tuple, since the CIS semantics depend on it */ if ((*fct) (&tuple, arg)) { - pcmcia_chip_mem_unmap(pct, pch, - window); ret = 1; - goto done; + goto done_and_unmap; } tuple.ptr++; break; @@ -296,7 +294,6 @@ pcmcia_scan_cis(dev, fct, arg) * distant regions */ if ((addr >= PCMCIA_CIS_SIZE) || - ((addr + length) < 0) || ((addr + length) >= PCMCIA_CIS_SIZE)) { DPRINTF((" skipped, " @@ -403,10 +400,8 @@ pcmcia_scan_cis(dev, fct, arg) default: { if ((*fct) (&tuple, arg)) { - pcmcia_chip_mem_unmap(pct, - pch, window); ret = 1; - goto done; + goto done_and_unmap; } } break; @@ -511,6 +506,7 @@ pcmcia_scan_cis(dev, fct, arg) } } +done_and_unmap: pcmcia_chip_mem_unmap(pct, pch, window); done: Index: 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 --- dev/raidframe/rf_etimer.h 29 May 2005 22:03:09 -0000 1.9 +++ dev/raidframe/rf_etimer.h 26 Oct 2005 14:25:10 -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: 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 --- dev/scsipi/st.c 15 Oct 2005 17:29:26 -0000 1.185 +++ dev/scsipi/st.c 26 Oct 2005 14:25:11 -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: 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 --- dev/wscons/wsmouse.c 21 Jun 2005 14:01:13 -0000 1.36 +++ dev/wscons/wsmouse.c 26 Oct 2005 14:25:11 -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: 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 --- dist/pf/net/pfvar.h 1 Jul 2005 12:37:35 -0000 1.9 +++ dist/pf/net/pfvar.h 26 Oct 2005 14:25:13 -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: fs/msdosfs/msdosfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/msdosfs/msdosfs_vnops.c,v retrieving revision 1.20 diff -d -p -u -r1.20 msdosfs_vnops.c --- fs/msdosfs/msdosfs_vnops.c 12 Sep 2005 16:24:41 -0000 1.20 +++ fs/msdosfs/msdosfs_vnops.c 26 Oct 2005 14:25:13 -0000 @@ -1846,22 +1846,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: fs/ptyfs/ptyfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/fs/ptyfs/ptyfs_vnops.c,v retrieving revision 1.10 diff -d -p -u -r1.10 ptyfs_vnops.c --- fs/ptyfs/ptyfs_vnops.c 12 Oct 2005 15:23:33 -0000 1.10 +++ fs/ptyfs/ptyfs_vnops.c 26 Oct 2005 14:25:14 -0000 @@ -775,10 +775,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: @@ -806,8 +806,7 @@ ptyfs_read(void *v) int error; ptyfs->ptyfs_flag |= PTYFS_ACCESS; - /* hardclock() resolution is good enough for ptyfs */ - TIMEVAL_TO_TIMESPEC(&time, &ts); + getnanotime(&ts); (void)VOP_UPDATE(vp, &ts, &ts, 0); switch (ptyfs->ptyfs_type) { @@ -843,8 +842,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)VOP_UPDATE(vp, &ts, &ts, 0); switch (ptyfs->ptyfs_type) { @@ -956,21 +954,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: 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 --- fs/smbfs/smbfs_node.c 30 Aug 2005 19:04:51 -0000 1.25 +++ fs/smbfs/smbfs_node.c 26 Oct 2005 14:25:14 -0000 @@ -310,8 +310,8 @@ smbfs_inactive(v) void smbfs_attr_cacheenter(struct vnode *vp, struct smbfattr *fap) { + struct bintime bt; struct smbnode *np = VTOSMB(vp); - int s; if (vp->v_type == VREG) { if (np->n_size != fap->fa_size) { @@ -326,22 +326,20 @@ 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); + getbinuptime(&bt); + np->n_attrage = bt.sec; } int smbfs_attr_cachelookup(struct vnode *vp, struct vattr *va) { + struct bintime bt; 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); + getbinuptime(&bt); + diff = bt.sec - np->n_attrage; if (diff > SMBFS_ATTRTIMO) /* XXX should be configurable */ return ENOENT; Index: 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 --- fs/smbfs/smbfs_smb.c 12 Sep 2005 16:54:35 -0000 1.28 +++ fs/smbfs/smbfs_smb.c 26 Oct 2005 14:25:14 -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: fs/tmpfs/tmpfs_subr.c =================================================================== RCS file: /cvsroot/src/sys/fs/tmpfs/tmpfs_subr.c,v retrieving revision 1.11 diff -d -p -u -r1.11 tmpfs_subr.c --- fs/tmpfs/tmpfs_subr.c 30 Sep 2005 14:29:19 -0000 1.11 +++ fs/tmpfs/tmpfs_subr.c 26 Oct 2005 14:25:15 -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; @@ -1210,9 +1210,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); @@ -1220,21 +1219,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: kern/init_main.c =================================================================== RCS file: /cvsroot/src/sys/kern/init_main.c,v retrieving revision 1.251 diff -d -p -u -r1.251 init_main.c --- kern/init_main.c 5 Aug 2005 11:03:18 -0000 1.251 +++ kern/init_main.c 26 Oct 2005 14:25:15 -0000 @@ -74,17 +74,18 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.251 2005/08/05 11:03:18 junyoung 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" @@ -184,7 +185,6 @@ struct proc *initproc; struct vnode *rootvp, *swapdev_vp; int boothowto; int cold = 1; /* still working on startup */ -struct timeval boottime; time_t rootfstime; /* recorded root fs time, if known */ __volatile int start_init_exec; /* semaphore for start_init() */ @@ -202,6 +202,9 @@ void main(void); void main(void) { +#ifdef __HAVE_TIMECOUNTER + struct timeval time; +#endif struct lwp *l; struct proc *p; struct pdevinit *pdev; @@ -440,6 +443,10 @@ main(void) */ inittodr(rootfstime); +#ifdef NTP + ntp_init(); /* XXXXXXXXX right place?!?! XXXXXXXXX */ +#endif + CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_ROOTFS; #ifdef ROOTFS_MAGICLINKS CIRCLEQ_FIRST(&mountlist)->mnt_flag |= MNT_MAGICLINKS; @@ -474,9 +481,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: 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 --- kern/init_sysctl.c 8 Oct 2005 06:35:56 -0000 1.56 +++ kern/init_sysctl.c 26 Oct 2005 14:25:16 -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: 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 --- kern/kern_acct.c 23 Jun 2005 23:15:12 -0000 1.61 +++ kern/kern_acct.c 26 Oct 2005 14:25:16 -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: 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 --- kern/kern_clock.c 12 Sep 2005 16:21:31 -0000 1.95 +++ kern/kern_clock.c 26 Oct 2005 14:25:17 -0000 @@ -1,3 +1,4 @@ +/* XXXX !__HAVE_TIMEKEEPER case XXXX */ /* $NetBSD: kern_clock.c,v 1.95 2005/09/12 16:21:31 christos Exp $ */ /*- @@ -93,6 +94,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_clock.c #include #include #include +#include #include #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS @@ -127,188 +129,6 @@ __KERNEL_RCSID(0, "$NetBSD: kern_clock.c * profhz/stathz for statistics. (For profiling, every tick counts.) */ -#ifdef NTP /* NTP phase-locked loop in kernel */ -/* - * Phase/frequency-lock loop (PLL/FLL) definitions - * - * The following variables are read and set by the ntp_adjtime() system - * call. - * - * time_state shows the state of the system clock, with values defined - * in the timex.h header file. - * - * time_status shows the status of the system clock, with bits defined - * in the timex.h header file. - * - * time_offset is used by the PLL/FLL to adjust the system time in small - * increments. - * - * time_constant determines the bandwidth or "stiffness" of the PLL. - * - * time_tolerance determines maximum frequency error or tolerance of the - * CPU clock oscillator and is a property of the architecture; however, - * in principle it could change as result of the presence of external - * discipline signals, for instance. - * - * time_precision is usually equal to the kernel tick variable; however, - * in cases where a precision clock counter or external clock is - * available, the resolution can be much less than this and depend on - * whether the external clock is working or not. - * - * time_maxerror is initialized by a ntp_adjtime() call and increased by - * the kernel once each second to reflect the maximum error bound - * growth. - * - * time_esterror is set and read by the ntp_adjtime() call, but - * otherwise not used by the kernel. - */ -int time_state = TIME_OK; /* clock state */ -int time_status = STA_UNSYNC; /* clock status bits */ -long time_offset = 0; /* time offset (us) */ -long time_constant = 0; /* pll time constant */ -long time_tolerance = MAXFREQ; /* frequency tolerance (scaled ppm) */ -long time_precision = 1; /* clock precision (us) */ -long time_maxerror = MAXPHASE; /* maximum error (us) */ -long time_esterror = MAXPHASE; /* estimated error (us) */ - -/* - * The following variables establish the state of the PLL/FLL and the - * residual time and frequency offset of the local clock. The scale - * factors are defined in the timex.h header file. - * - * time_phase and time_freq are the phase increment and the frequency - * increment, respectively, of the kernel time variable. - * - * time_freq is set via ntp_adjtime() from a value stored in a file when - * the synchronization daemon is first started. Its value is retrieved - * via ntp_adjtime() and written to the file about once per hour by the - * daemon. - * - * time_adj is the adjustment added to the value of tick at each timer - * interrupt and is recomputed from time_phase and time_freq at each - * seconds rollover. - * - * time_reftime is the second's portion of the system time at the last - * call to ntp_adjtime(). It is used to adjust the time_freq variable - * and to increase the time_maxerror as the time since last update - * increases. - */ -long time_phase = 0; /* phase offset (scaled us) */ -long time_freq = 0; /* frequency offset (scaled ppm) */ -long time_adj = 0; /* tick adjust (scaled 1 / hz) */ -long time_reftime = 0; /* time at last adjustment (s) */ - -#ifdef PPS_SYNC -/* - * The following variables are used only if the kernel PPS discipline - * code is configured (PPS_SYNC). The scale factors are defined in the - * timex.h header file. - * - * pps_time contains the time at each calibration interval, as read by - * microtime(). pps_count counts the seconds of the calibration - * interval, the duration of which is nominally pps_shift in powers of - * two. - * - * pps_offset is the time offset produced by the time median filter - * pps_tf[], while pps_jitter is the dispersion (jitter) measured by - * this filter. - * - * pps_freq is the frequency offset produced by the frequency median - * filter pps_ff[], while pps_stabil is the dispersion (wander) measured - * by this filter. - * - * pps_usec is latched from a high resolution counter or external clock - * at pps_time. Here we want the hardware counter contents only, not the - * contents plus the time_tv.usec as usual. - * - * pps_valid counts the number of seconds since the last PPS update. It - * is used as a watchdog timer to disable the PPS discipline should the - * PPS signal be lost. - * - * pps_glitch counts the number of seconds since the beginning of an - * offset burst more than tick/2 from current nominal offset. It is used - * mainly to suppress error bursts due to priority conflicts between the - * PPS interrupt and timer interrupt. - * - * pps_intcnt counts the calibration intervals for use in the interval- - * adaptation algorithm. It's just too complicated for words. - * - * pps_kc_hardpps_source contains an arbitrary value that uniquely - * identifies the currently bound source of the PPS signal, or NULL - * if no source is bound. - * - * pps_kc_hardpps_mode indicates which transitions, if any, of the PPS - * signal should be reported. - */ -struct timeval pps_time; /* kernel time at last interval */ -long pps_tf[] = {0, 0, 0}; /* pps time offset median filter (us) */ -long pps_offset = 0; /* pps time offset (us) */ -long pps_jitter = MAXTIME; /* time dispersion (jitter) (us) */ -long pps_ff[] = {0, 0, 0}; /* pps frequency offset median filter */ -long pps_freq = 0; /* frequency offset (scaled ppm) */ -long pps_stabil = MAXFREQ; /* frequency dispersion (scaled ppm) */ -long pps_usec = 0; /* microsec counter at last interval */ -long pps_valid = PPS_VALID; /* pps signal watchdog counter */ -int pps_glitch = 0; /* pps signal glitch counter */ -int pps_count = 0; /* calibration interval counter (s) */ -int pps_shift = PPS_SHIFT; /* interval duration (s) (shift) */ -int pps_intcnt = 0; /* intervals at current duration */ -void *pps_kc_hardpps_source = NULL; /* current PPS supplier's identifier */ -int pps_kc_hardpps_mode = 0; /* interesting edges of PPS signal */ - -/* - * PPS signal quality monitors - * - * pps_jitcnt counts the seconds that have been discarded because the - * jitter measured by the time median filter exceeds the limit MAXTIME - * (100 us). - * - * pps_calcnt counts the frequency calibration intervals, which are - * variable from 4 s to 256 s. - * - * pps_errcnt counts the calibration intervals which have been discarded - * because the wander exceeds the limit MAXFREQ (100 ppm) or where the - * calibration interval jitter exceeds two ticks. - * - * pps_stbcnt counts the calibration intervals that have been discarded - * because the frequency wander exceeds the limit MAXFREQ / 4 (25 us). - */ -long pps_jitcnt = 0; /* jitter limit exceeded */ -long pps_calcnt = 0; /* calibration intervals */ -long pps_errcnt = 0; /* calibration errors */ -long pps_stbcnt = 0; /* stability limit exceeded */ -#endif /* PPS_SYNC */ - -#ifdef EXT_CLOCK -/* - * External clock definitions - * - * The following definitions and declarations are used only if an - * external clock is configured on the system. - */ -#define CLOCK_INTERVAL 30 /* CPU clock update interval (s) */ - -/* - * The clock_count variable is set to CLOCK_INTERVAL at each PPS - * interrupt and decremented once each second. - */ -int clock_count = 0; /* CPU clock counter */ - -#ifdef HIGHBALL -/* - * The clock_offset and clock_cpu variables are used by the HIGHBALL - * interface. The clock_offset variable defines the offset between - * system time and the HIGBALL counters. The clock_cpu variable contains - * the offset between the system clock and the HIGHBALL clock for use in - * disciplining the kernel time variable. - */ -extern struct timeval clock_offset; /* Highball clock offset */ -long clock_cpu = 0; /* CPU clock adjust */ -#endif /* HIGHBALL */ -#endif /* EXT_CLOCK */ -#endif /* NTP */ - - /* * Bump a timeval by a small number of usec's. */ @@ -332,6 +152,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 */ +#if 0 /* XXXXXXXXXXXXXXXXX what's in tc_ticktock() now?? XXXXXXXXXXXXXXXXX */ int tickfix, tickfixinterval; /* used if tick not really integral */ #ifndef NTP static int tickfixcnt; /* accumulated fractional error */ @@ -339,16 +160,11 @@ static int tickfixcnt; /* accumulated int fixtick; /* used by NTP for same */ int shifthz; #endif +#endif /* XXXXXXXXXXXXXXXXX what's in tc_ticktock() now?? XXXXXXXXXXXXXXXXX */ -/* - * We might want ldd to load the both words from time at once. - * To succeed we need to be quadword aligned. - * The sparc already does that, and that it has worked so far is a fluke. - */ -volatile struct timeval time __attribute__((__aligned__(__alignof__(quad_t)))); -volatile struct timeval mono_time; - +#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS void *softclock_si; +#endif /* * Initialize clock frequencies and start both clocks running. @@ -369,6 +185,8 @@ initclocks(void) * code do its bit. */ psdiv = 1; + + inittimecounter(); cpu_initclocks(); /* @@ -386,6 +204,7 @@ initclocks(void) panic("statscheddiv"); } +#if 0 /* XXXXXXXXXXXXXXXXX what's in tc_ticktock() now?? XXXXXXXXXXXXXXXXX */ #ifdef NTP switch (hz) { case 1: @@ -456,6 +275,7 @@ initclocks(void) fixtick = (1000000 - (hz*tick)); } #endif +#endif /* XXXXXXXXXXXXXXXXX what's in tc_ticktock() now?? XXXXXXXXXXXXXXXXX */ } /* @@ -466,15 +286,19 @@ hardclock(struct clockframe *frame) { struct lwp *l; struct proc *p; +#if 0 /* XXXXXXXXXXXXXXXXX what's in tc_ticktock() now?? XXXXXXXXXXXXXXXXX */ int delta; extern int tickdelta; extern long timedelta; +#endif /* XXXXXXXXXXXXXXXXX what's in tc_ticktock() now?? XXXXXXXXXXXXXXXXX */ struct cpu_info *ci = curcpu(); struct ptimer *pt; +#if 0 /* XXXXXXXXXXXXXXXXX what's in tc_ticktock() now?? XXXXXXXXXXXXXXXXX */ #ifdef NTP int time_update; int ltemp; #endif +#endif /* XXXXXXXXXXXXXXXXX what's in tc_ticktock() now?? XXXXXXXXXXXXXXXXX */ l = curlwp; if (l) { @@ -492,6 +316,8 @@ hardclock(struct clockframe *frame) itimerfire(pt); } + tc_ticktock(); + /* * If no separate statistics clock is available, run it from here. */ @@ -509,6 +335,13 @@ hardclock(struct clockframe *frame) return; #endif +/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +/* XXXXXXXXXXXXXX Do timecounters have our fancy shift stuff? XXXXXXXXXXXXXX */ +/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ + +#if 0 /* XXXXXXXXXXXXXXXXX what's in tc_ticktock() now?? XXXXXXXXXXXXXXXXX */ /* * Increment the time-of-day. The increment is normally just * ``tick''. If the machine is one which has a clock frequency @@ -563,35 +396,9 @@ hardclock(struct clockframe *frame) time_update += ltemp; } -#ifdef HIGHBALL - /* - * If the HIGHBALL board is installed, we need to adjust the - * external clock offset in order to close the hardware feedback - * loop. This will adjust the external clock phase and frequency - * in small amounts. The additional phase noise and frequency - * wander this causes should be minimal. We also need to - * discipline the kernel time variable, since the PLL is used to - * discipline the external clock. If the Highball board is not - * present, we discipline kernel time with the PLL as usual. We - * assume that the external clock phase adjustment (time_update) - * and kernel phase adjustment (clock_cpu) are less than the - * value of tick. - */ - clock_offset.tv_usec += time_update; - if (clock_offset.tv_usec >= 1000000) { - clock_offset.tv_sec++; - clock_offset.tv_usec -= 1000000; - } - if (clock_offset.tv_usec < 0) { - clock_offset.tv_sec--; - clock_offset.tv_usec += 1000000; - } - time.tv_usec += clock_cpu; - clock_cpu = 0; -#else time.tv_usec += time_update; -#endif /* HIGHBALL */ +/* XXX start of freebsd ntp_update_second */ /* * On rollover of the second the phase adjustment to be used for * the next second is calculated. Also, the maximum error is @@ -787,56 +594,16 @@ hardclock(struct clockframe *frame) } break; } - -#ifdef EXT_CLOCK - /* - * If an external clock is present, it is necessary to - * discipline the kernel time variable anyway, since not - * all system components use the microtime() interface. - * Here, the time offset between the external clock and - * kernel time variable is computed every so often. - */ - clock_count++; - if (clock_count > CLOCK_INTERVAL) { - clock_count = 0; - microtime(&clock_ext); - delta.tv_sec = clock_ext.tv_sec - time.tv_sec; - delta.tv_usec = clock_ext.tv_usec - - time.tv_usec; - if (delta.tv_usec < 0) - delta.tv_sec--; - if (delta.tv_usec >= 500000) { - delta.tv_usec -= 1000000; - delta.tv_sec++; - } - if (delta.tv_usec < -500000) { - delta.tv_usec += 1000000; - delta.tv_sec--; - } - if (delta.tv_sec > 0 || (delta.tv_sec == 0 && - delta.tv_usec > MAXPHASE) || - delta.tv_sec < -1 || (delta.tv_sec == -1 && - delta.tv_usec < -MAXPHASE)) { - time = clock_ext; - delta.tv_sec = 0; - delta.tv_usec = 0; - } -#ifdef HIGHBALL - clock_cpu = delta.tv_usec; -#else /* HIGHBALL */ - hardupdate(delta.tv_usec); -#endif /* HIGHBALL */ - } -#endif /* EXT_CLOCK */ } - #endif /* NTP */ +#endif /* XXXXXXXXXXXXXXXXX what's in tc_ticktock() now?? XXXXXXXXXXXXXXXXX */ /* * 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. */ + hardclock_ticks++; if (callout_hardclock()) { if (CLKF_BASEPRI(frame)) { /* @@ -858,16 +625,30 @@ hardclock(struct clockframe *frame) } } +/* XXXXXXXXXX need tvtohz - most callers use "getmicrotime(now); timersub(want, now); hzto(want);" when just "tvtohz(want);" will do! XXXXXXXXXX */ /* * Compute number of hz until specified time. Used to compute second * argument to callout_reset() from an absolute time. */ int -hzto(struct timeval *tv) +hzto(struct timeval *tvp) +{ + struct timeval now, tv; + + tv = *tvp; /* Don't modify original tvp. */ + getmicrotime(&now); + timersub(&tv, &now, &tv); + return tvtohz(&tv); +} + +/* + * Compute number of ticks in the specified amount of time. + */ +int +tvtohz(struct timeval *tv) { unsigned long ticks; long sec, usec; - int s; /* * If the number of usecs in the whole seconds part of the time @@ -881,7 +662,7 @@ hzto(struct timeval *tv) * 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 assume that hz is integral. + * case, but it is slightly slower and assumes that hz is integral. * * Otherwise, round the time difference down to the maximum * representable value. @@ -889,10 +670,8 @@ hzto(struct timeval *tv) * If ints are 32-bit, then the maximum value for any timeout in * 10ms ticks is 248 days. */ - s = splclock(); - sec = tv->tv_sec - time.tv_sec; - usec = tv->tv_usec - time.tv_usec; - splx(s); + sec = tv->tv_sec; + usec = tv->tv_usec; if (usec < 0) { sec--; @@ -922,6 +701,22 @@ hzto(struct timeval *tv) } /* + * 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. * * Kernel profiling passes proc0 which never exits and hence @@ -1100,347 +895,3 @@ statclock(struct clockframe *frame) } } } - - -#ifdef NTP /* NTP phase-locked loop in kernel */ - -/* - * 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 oscillatores and nominal update - * intervals less than 1024 s, operation should be in phase-lock mode - * (STA_FLL = 0), where the loop is disciplined to phase. For update - * intervals greater than thiss, operation should be in frequency-lock - * mode (STA_FLL = 1), where the loop is disciplined to frequency. - * - * Note: splclock() is in effect. - */ -void -hardupdate(long offset) -{ - long ltemp, mtemp; - - if (!(time_status & STA_PLL) && !(time_status & STA_PPSTIME)) - return; - ltemp = offset; -#ifdef PPS_SYNC - if (time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL) - ltemp = pps_offset; -#endif /* PPS_SYNC */ - - /* - * Scale the phase adjustment and clamp to the operating range. - */ - if (ltemp > MAXPHASE) - time_offset = MAXPHASE << SHIFT_UPDATE; - else if (ltemp < -MAXPHASE) - time_offset = -(MAXPHASE << SHIFT_UPDATE); - else - time_offset = ltemp << SHIFT_UPDATE; - - /* - * Select whether the frequency is to be controlled and in which - * mode (PLL or FLL). Clamp to the operating range. Ugly - * multiply/divide should be replaced someday. - */ - if (time_status & STA_FREQHOLD || time_reftime == 0) - time_reftime = time.tv_sec; - mtemp = time.tv_sec - time_reftime; - time_reftime = time.tv_sec; - if (time_status & STA_FLL) { - if (mtemp >= MINSEC) { - ltemp = ((time_offset / mtemp) << (SHIFT_USEC - - SHIFT_UPDATE)); - if (ltemp < 0) - time_freq -= -ltemp >> SHIFT_KH; - else - time_freq += ltemp >> SHIFT_KH; - } - } else { - if (mtemp < MAXSEC) { - ltemp *= mtemp; - if (ltemp < 0) - time_freq -= -ltemp >> (time_constant + - time_constant + SHIFT_KF - - SHIFT_USEC); - else - time_freq += ltemp >> (time_constant + - time_constant + SHIFT_KF - - SHIFT_USEC); - } - } - if (time_freq > time_tolerance) - time_freq = time_tolerance; - else if (time_freq < -time_tolerance) - time_freq = -time_tolerance; -} - -#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 timeval *tvp, /* time at PPS */ - long usec /* hardware counter at PPS */) -{ - long u_usec, v_usec, bigtick; - long cal_sec, cal_usec; - - /* - * An occasional glitch can be produced when the PPS interrupt - * occurs in the hardclock() routine before the time variable is - * updated. Here the offset is discarded when the difference - * between it and the last one is greater than tick/2, but not - * if the interval since the first discard exceeds 30 s. - */ - time_status |= STA_PPSSIGNAL; - time_status &= ~(STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR); - pps_valid = 0; - u_usec = -tvp->tv_usec; - if (u_usec < -500000) - u_usec += 1000000; - v_usec = pps_offset - u_usec; - if (v_usec < 0) - v_usec = -v_usec; - if (v_usec > (tick >> 1)) { - if (pps_glitch > MAXGLITCH) { - pps_glitch = 0; - pps_tf[2] = u_usec; - pps_tf[1] = u_usec; - } else { - pps_glitch++; - u_usec = pps_offset; - } - } else - pps_glitch = 0; - - /* - * A three-stage median filter is used to help deglitch the pps - * time. The median sample becomes the time offset estimate; the - * difference between the other two samples becomes the time - * dispersion (jitter) estimate. - */ - pps_tf[2] = pps_tf[1]; - pps_tf[1] = pps_tf[0]; - pps_tf[0] = u_usec; - if (pps_tf[0] > pps_tf[1]) { - if (pps_tf[1] > pps_tf[2]) { - pps_offset = pps_tf[1]; /* 0 1 2 */ - v_usec = pps_tf[0] - pps_tf[2]; - } else if (pps_tf[2] > pps_tf[0]) { - pps_offset = pps_tf[0]; /* 2 0 1 */ - v_usec = pps_tf[2] - pps_tf[1]; - } else { - pps_offset = pps_tf[2]; /* 0 2 1 */ - v_usec = pps_tf[0] - pps_tf[1]; - } - } else { - if (pps_tf[1] < pps_tf[2]) { - pps_offset = pps_tf[1]; /* 2 1 0 */ - v_usec = pps_tf[2] - pps_tf[0]; - } else if (pps_tf[2] < pps_tf[0]) { - pps_offset = pps_tf[0]; /* 1 0 2 */ - v_usec = pps_tf[1] - pps_tf[2]; - } else { - pps_offset = pps_tf[2]; /* 1 2 0 */ - v_usec = pps_tf[1] - pps_tf[0]; - } - } - if (v_usec > MAXTIME) - pps_jitcnt++; - v_usec = (v_usec << PPS_AVG) - pps_jitter; - if (v_usec < 0) - pps_jitter -= -v_usec >> PPS_AVG; - else - pps_jitter += v_usec >> PPS_AVG; - if (pps_jitter > (MAXTIME >> 1)) - time_status |= STA_PPSJITTER; - - /* - * During the calibration interval adjust the starting time when - * the tick overflows. At the end of the interval compute the - * duration of the interval and the difference of the hardware - * counters at the beginning and end of the interval. This code - * is deliciously complicated by the fact valid differences may - * exceed the value of tick when using long calibration - * intervals and small ticks. Note that the counter can be - * greater than tick if caught at just the wrong instant, but - * the values returned and used here are correct. - */ - bigtick = (long)tick << SHIFT_USEC; - pps_usec -= pps_freq; - if (pps_usec >= bigtick) - pps_usec -= bigtick; - if (pps_usec < 0) - pps_usec += bigtick; - pps_time.tv_sec++; - pps_count++; - if (pps_count < (1 << pps_shift)) - return; - pps_count = 0; - pps_calcnt++; - u_usec = usec << SHIFT_USEC; - v_usec = pps_usec - u_usec; - if (v_usec >= bigtick >> 1) - v_usec -= bigtick; - if (v_usec < -(bigtick >> 1)) - v_usec += bigtick; - if (v_usec < 0) - v_usec = -(-v_usec >> pps_shift); - else - v_usec = v_usec >> pps_shift; - pps_usec = u_usec; - cal_sec = tvp->tv_sec; - cal_usec = tvp->tv_usec; - cal_sec -= pps_time.tv_sec; - cal_usec -= pps_time.tv_usec; - if (cal_usec < 0) { - cal_usec += 1000000; - cal_sec--; - } - pps_time = *tvp; - - /* - * Check for lost interrupts, noise, excessive jitter and - * excessive frequency error. The number of timer ticks during - * the interval may vary +-1 tick. Add to this a margin of one - * tick for the PPS signal jitter and maximum frequency - * deviation. If the limits are exceeded, the calibration - * interval is reset to the minimum and we start over. - */ - u_usec = (long)tick << 1; - if (!((cal_sec == -1 && cal_usec > (1000000 - u_usec)) - || (cal_sec == 0 && cal_usec < u_usec)) - || v_usec > time_tolerance || v_usec < -time_tolerance) { - pps_errcnt++; - pps_shift = PPS_SHIFT; - pps_intcnt = 0; - time_status |= STA_PPSERROR; - return; - } - - /* - * A three-stage median filter is used to help deglitch the pps - * frequency. The median sample becomes the frequency offset - * estimate; the difference between the other two samples - * becomes the frequency dispersion (stability) estimate. - */ - pps_ff[2] = pps_ff[1]; - pps_ff[1] = pps_ff[0]; - pps_ff[0] = v_usec; - if (pps_ff[0] > pps_ff[1]) { - if (pps_ff[1] > pps_ff[2]) { - u_usec = pps_ff[1]; /* 0 1 2 */ - v_usec = pps_ff[0] - pps_ff[2]; - } else if (pps_ff[2] > pps_ff[0]) { - u_usec = pps_ff[0]; /* 2 0 1 */ - v_usec = pps_ff[2] - pps_ff[1]; - } else { - u_usec = pps_ff[2]; /* 0 2 1 */ - v_usec = pps_ff[0] - pps_ff[1]; - } - } else { - if (pps_ff[1] < pps_ff[2]) { - u_usec = pps_ff[1]; /* 2 1 0 */ - v_usec = pps_ff[2] - pps_ff[0]; - } else if (pps_ff[2] < pps_ff[0]) { - u_usec = pps_ff[0]; /* 1 0 2 */ - v_usec = pps_ff[1] - pps_ff[2]; - } else { - u_usec = pps_ff[2]; /* 1 2 0 */ - v_usec = pps_ff[1] - pps_ff[0]; - } - } - - /* - * Here the frequency dispersion (stability) is updated. If it - * is less than one-fourth the maximum (MAXFREQ), the frequency - * offset is updated as well, but clamped to the tolerance. It - * will be processed later by the hardclock() routine. - */ - v_usec = (v_usec >> 1) - pps_stabil; - if (v_usec < 0) - pps_stabil -= -v_usec >> PPS_AVG; - else - pps_stabil += v_usec >> PPS_AVG; - if (pps_stabil > MAXFREQ >> 2) { - pps_stbcnt++; - time_status |= STA_PPSWANDER; - return; - } - if (time_status & STA_PPSFREQ) { - if (u_usec < 0) { - pps_freq -= -u_usec >> PPS_AVG; - if (pps_freq < -time_tolerance) - pps_freq = -time_tolerance; - u_usec = -u_usec; - } else { - pps_freq += u_usec >> PPS_AVG; - if (pps_freq > time_tolerance) - pps_freq = time_tolerance; - } - } - - /* - * Here the calibration interval is adjusted. If the maximum - * time difference is greater than tick / 4, reduce the interval - * by half. If this is not the case for four consecutive - * intervals, double the interval. - */ - if (u_usec << pps_shift > bigtick >> 2) { - pps_intcnt = 0; - if (pps_shift > PPS_SHIFT) - pps_shift--; - } else if (pps_intcnt >= 4) { - pps_intcnt = 0; - if (pps_shift < PPS_SHIFTMAX) - pps_shift++; - } else - pps_intcnt++; -} -#endif /* PPS_SYNC */ -#endif /* NTP */ - -/* - * XXX: Until all md code has it. - */ -struct timespec * -nanotime(struct timespec *ts) -{ - struct timeval tv; - - microtime(&tv); - TIMEVAL_TO_TIMESPEC(&tv, ts); - return ts; -} Index: 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 --- kern/kern_event.c 23 Oct 2005 01:33:32 -0000 1.24 +++ kern/kern_event.c 26 Oct 2005 14:25:18 -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: 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 --- kern/kern_fork.c 17 May 2005 19:22:19 -0000 1.122 +++ kern/kern_fork.c 26 Oct 2005 14:25:18 -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: 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 --- kern/kern_ktrace.c 29 May 2005 22:24:15 -0000 1.97 +++ kern/kern_ktrace.c 26 Oct 2005 14:25:18 -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: 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 --- kern/kern_microtime.c 23 Jan 2005 08:39:51 -0000 1.14 +++ kern/kern_microtime.c 26 Oct 2005 14:25:18 -0000 @@ -1,3 +1,5 @@ +/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX review in the freebsd timecounter world XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +#if 0 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX need for timecounters? XXXXXXXXXXX */ /* $NetBSD: kern_microtime.c,v 1.14 2005/01/23 08:39:51 yamt Exp $ */ /*- @@ -126,7 +128,7 @@ cc_microtime(struct timeval *tvp) */ /* XXXSMP: not atomic */ simple_lock(µtime_slock); - t = time; + getmicrotime(&t); } /* @@ -220,3 +222,4 @@ cc_microset(struct cpu_info *ci) ci->ci_cc_denom = cpu_frequency(ci); } } +#endif /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX need for timecounters? XXXXXXXXXXX */ Index: 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 --- kern/kern_ntptime.c 26 Feb 2005 21:34:55 -0000 1.28 +++ kern/kern_ntptime.c 26 Oct 2005 14:25:19 -0000 @@ -1,55 +1,40 @@ +/* XXXX !__HAVE_TIMEKEEPER case XXXX */ /* $NetBSD: kern_ntptime.c,v 1.28 2005/02/26 21:34:55 perry Exp $ */ -/****************************************************************************** - * * - * Copyright (c) David L. Mills 1993, 1994 * - * * - * 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. * - * * - ******************************************************************************/ +/*- + *********************************************************************** + * * + * 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 kern_ntptime.c - * - * 24 Sep 94 David L. Mills - * Tightened code at exits. - * - * 24 Mar 94 David L. Mills - * Revised syscall interface to include new variables for PPS - * time discipline. - * - * 14 Feb 94 David L. Mills - * Added code for external clock - * - * 28 Nov 93 David L. Mills - * Revised frequency scaling to conform with adjusted parameters + * Adapted from the original sources for FreeBSD and timecounters by: + * Poul-Henning Kamp . * - * 17 Sep 93 David L. Mills - * Created file - */ -/* - * ntp_gettime(), ntp_adjtime() - precision time interface for SunOS - * V4.1.1 and V4.1.3 + * 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. * - * These routines consitute 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 hardclock() to adjust the phase and - * frequency of the phase-lock loop which controls the system clock. + * 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" @@ -71,34 +56,164 @@ __KERNEL_RCSID(0, "$NetBSD: kern_ntptime #ifdef NTP /* - * The following variables are used by the hardclock() routine in the - * kern_clock.c module and are described in that module. + * Single-precision macros for 64-bit machines */ -extern int time_state; /* clock state */ -extern int time_status; /* clock status bits */ -extern long time_offset; /* time adjustment (us) */ -extern long time_freq; /* frequency offset (scaled ppm) */ -extern long time_maxerror; /* maximum error (us) */ -extern long time_esterror; /* estimated error (us) */ -extern long time_constant; /* pll time constant */ -extern long time_precision; /* clock precision (us) */ -extern long time_tolerance; /* frequency tolerance (scaled ppm) */ -extern int time_adjusted; /* ntp might have changed the system time */ +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 only if the PPS signal discipline - * is configured in the kernel. + * 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. */ -extern int pps_shift; /* interval duration (s) (shift) */ -extern long pps_freq; /* pps frequency offset (scaled ppm) */ -extern long pps_jitter; /* pps jitter (us) */ -extern long pps_stabil; /* pps stability (scaled ppm) */ -extern long pps_jitcnt; /* jitter limit exceeded */ -extern long pps_calcnt; /* calibration intervals */ -extern long pps_errcnt; /* calibration errors */ -extern long pps_stbcnt; /* stability limit exceeded */ +#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 */ + +/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX need this in the freebsd world? XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + * pps_kc_hardpps_source contains an arbitrary value that uniquely + * identifies the currently bound source of the PPS signal, or NULL + * if no source is bound. + * + * pps_kc_hardpps_mode indicates which transitions, if any, of the PPS + * signal should be reported. + */ +void *pps_kc_hardpps_source = NULL; /* current PPS supplier's identifier */ +int pps_kc_hardpps_mode = 0; /* interesting edges of PPS signal */ #endif /* PPS_SYNC */ +/* + * End of phase/frequency-lock loop (PLL/FLL) definitions + */ + +static void hardupdate(long offset); /*ARGSUSED*/ /* @@ -114,34 +229,15 @@ sys_ntp_gettime(l, v, retval) struct sys_ntp_gettime_args /* { syscallarg(struct ntptimeval *) ntvp; } */ *uap = v; - struct timeval atv; struct ntptimeval ntv; int error = 0; - int s; if (SCARG(uap, ntvp)) { - s = splclock(); -#ifdef EXT_CLOCK - /* - * The microtime() external clock routine returns a - * status code. If less than zero, we declare an error - * in the clock status word and return the kernel - * (software) time variable. While there are other - * places that call microtime(), this is the only place - * that matters from an application point of view. - */ - if (microtime(&atv) < 0) { - time_status |= STA_CLOCKERR; - ntv.time = time; - } else - time_status &= ~STA_CLOCKERR; -#else /* EXT_CLOCK */ - microtime(&atv); -#endif /* EXT_CLOCK */ - ntv.time = atv; + nanotime(&ntv.time); ntv.maxerror = time_maxerror; ntv.esterror = time_esterror; - (void) splx(s); + ntv.tai = time_tai; + ntv.time_state = time_state; error = copyout((caddr_t)&ntv, (caddr_t)SCARG(uap, ntvp), sizeof(ntv)); @@ -149,39 +245,37 @@ sys_ntp_gettime(l, v, retval) 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. + * 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 + * 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 + * 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 + * PPS wander exceeded or calibration error when frequency + * synchronization requested */ (time_status & STA_PPSFREQ && time_status & (STA_PPSWANDER | STA_PPSERROR))) - *retval = TIME_ERROR; - else - *retval = (register_t)time_state; + ntv.time_state = TIME_ERROR; + + *retval = (register_t)ntv.time_state; } return(error); } @@ -222,68 +316,126 @@ ntp_adjtime1(ntv, v, retval) struct sys_ntp_adjtime_args /* { syscallarg(struct timex *) tp; } */ *uap = v; - int error = 0; + long freq; int modes; int s; + int error = 0; /* - * Update selected clock variables. Note that there is no error - * checking here on the assumption the superuser should know - * what it is doing. + * 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_FREQUENCY) -#ifdef PPS_SYNC - time_freq = ntv->freq - pps_freq; -#else /* PPS_SYNC */ - time_freq = ntv->freq; -#endif /* PPS_SYNC */ 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) - time_constant = ntv->constant; - if (modes & MOD_OFFSET) - hardupdate(ntv->offset); + 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 + * Retrieve all clock variables. Note that the TAI offset is + * returned only by ntp_gettime(); */ - if (time_offset < 0) - ntv->offset = -(-time_offset >> SHIFT_UPDATE); + if (time_status & STA_NANO) + ntv->offset = L_GINT(time_offset); else - ntv->offset = time_offset >> SHIFT_UPDATE; -#ifdef PPS_SYNC - ntv->freq = time_freq + pps_freq; -#else /* PPS_SYNC */ - ntv->freq = time_freq; -#endif /* PPS_SYNC */ + 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; - ntv->precision = time_precision; - ntv->tolerance = time_tolerance; + 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 = pps_freq; - ntv->jitter = pps_jitter >> PPS_AVG; + 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 */ - (void)splx(s); + splx(s); error = copyout((caddr_t)ntv, (caddr_t)SCARG(uap, tp), sizeof(*ntv)); if (!error) { @@ -298,85 +450,520 @@ ntp_adjtime1(ntv, v, retval) (time_status & STA_PPSTIME && time_status & STA_PPSJITTER) || (time_status & STA_PPSFREQ && - time_status & (STA_PPSWANDER | STA_PPSERROR))) + time_status & (STA_PPSWANDER | STA_PPSERROR))) { *retval = TIME_ERROR; - else + } 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 timeval atv; struct ntptimeval ntv; - int s; /* * Construct ntp_timeval. */ - s = splclock(); -#ifdef EXT_CLOCK - /* - * The microtime() external clock routine returns a - * status code. If less than zero, we declare an error - * in the clock status word and return the kernel - * (software) time variable. While there are other - * places that call microtime(), this is the only place - * that matters from an application point of view. - */ - if (microtime(&atv) < 0) { - time_status |= STA_CLOCKERR; - ntv.time = time; - } else { - time_status &= ~STA_CLOCKERR; - } -#else /* EXT_CLOCK */ - microtime(&atv); -#endif /* EXT_CLOCK */ - ntv.time = atv; + nanotime(&ntv.time); ntv.maxerror = time_maxerror; ntv.esterror = time_esterror; - splx(s); + ntv.tai = time_tai; + ntv.time_state = time_state; -#ifdef notyet +#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. + * 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)) || - ntv.time_state = TIME_ERROR; /* - * PPS signal lost when either time or frequency - * synchronization requested + * PPS signal lost when either time or frequency synchronization + * requested */ - (time_status & (STA_PPSFREQ | STA_PPSTIME) && + (time_status & (STA_PPSFREQ | STA_PPSTIME) && !(time_status & STA_PPSSIGNAL)) || /* - * PPS jitter exceeded when time synchronization - * requested + * PPS jitter exceeded when time synchronization requested */ - (time_status & STA_PPSTIME && + (time_status & STA_PPSTIME && time_status & STA_PPSJITTER) || /* - * PPS wander exceeded or calibration error when - * frequency synchronization requested + * PPS wander exceeded or calibration error when frequency + * synchronization requested */ - (time_status & STA_PPSFREQ && + (time_status & STA_PPSFREQ && time_status & (STA_PPSWANDER | STA_PPSERROR))) ntv.time_state = TIME_ERROR; else @@ -406,6 +993,16 @@ SYSCTL_SETUP(sysctl_kern_ntptime_setup, 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. */ Index: kern/kern_sig.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_sig.c,v retrieving revision 1.210 diff -d -p -u -r1.210 kern_sig.c --- kern/kern_sig.c 23 Oct 2005 00:09:14 -0000 1.210 +++ kern/kern_sig.c 26 Oct 2005 14:25:20 -0000 @@ -2358,10 +2358,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); @@ -2416,12 +2415,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); } /* @@ -2468,26 +2465,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: kern/kern_synch.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_synch.c,v retrieving revision 1.151 diff -d -p -u -r1.151 kern_synch.c --- kern/kern_synch.c 6 Oct 2005 07:02:14 -0000 1.151 +++ kern/kern_synch.c 26 Oct 2005 14:25:20 -0000 @@ -390,6 +390,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 @@ -458,7 +459,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 @@ -537,7 +541,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: kern/kern_sysctl.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_sysctl.c,v retrieving revision 1.186 diff -d -p -u -r1.186 kern_sysctl.c --- kern/kern_sysctl.c 21 Aug 2005 13:14:54 -0000 1.186 +++ kern/kern_sysctl.c 26 Oct 2005 14:25:21 -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: kern/kern_tc.c =================================================================== RCS file: kern/kern_tc.c diff -N kern/kern_tc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ kern/kern_tc.c 26 Oct 2005 14:25:21 -0000 @@ -0,0 +1,827 @@ +/* $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 +#include +#include /* XXX just to get AB_VERBOSE */ +#include +#include +#include +#include +#include +#include + +/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +#undef KASSERT +#define KASSERT(a, b) /* nothing */ +/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ + +/* + * 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, ("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, ("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, ("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); +} Index: kern/kern_time.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_time.c,v retrieving revision 1.95 diff -d -p -u -r1.95 kern_time.c --- kern/kern_time.c 23 Oct 2005 00:09:14 -0000 1.95 +++ kern/kern_time.c 26 Oct 2005 14:25:22 -0000 @@ -1,3 +1,4 @@ +/* XXXX !__HAVE_TIMEKEEPER case XXXX */ /* $NetBSD: kern_time.c,v 1.95 2005/10/23 00:09:14 cube Exp $ */ /*- @@ -85,7 +86,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_time.c, #include #include #include -#include +#include #include #include @@ -102,6 +103,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_time.c, #include static void timerupcall(struct lwp *, void *); +static int itimespecfix(struct timespec *); /* XXX move itimerfix to timespecs */ /* Time of day and interval timer support. * @@ -116,13 +118,15 @@ static void timerupcall(struct lwp *, vo int settime(struct timeval *tv) { - struct timeval delta; + struct timeval delta, tv1; + struct timespec ts; struct cpu_info *ci; int s; /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ s = splclock(); - timersub(tv, &time, &delta); + microtime(&tv1); + timersub(tv, &tv1, &delta); if ((delta.tv_sec < 0 || delta.tv_usec < 0) && securelevel > 1) { splx(s); return (EPERM); @@ -133,7 +137,9 @@ settime(struct timeval *tv) return (EPERM); } #endif - time = *tv; + ts.tv_sec = tv->tv_sec; + ts.tv_nsec = tv->tv_usec * 1000; + tc_setclock(&ts); (void) spllowersoftclock(); timeradd(&boottime, &delta, &boottime); /* @@ -145,9 +151,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,22 +168,15 @@ 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) { case CLOCK_REALTIME: - microtime(&atv); - TIMEVAL_TO_TIMESPEC(&atv,&ats); + nanotime(&ats); break; case CLOCK_MONOTONIC: - /* XXX "hz" granularity */ - s = splclock(); - atv = mono_time; - splx(s); - TIMEVAL_TO_TIMESPEC(&atv,&ats); + nanouptime(&ats); break; default: return (EINVAL); @@ -266,28 +265,22 @@ sys_nanosleep(struct lwp *l, void *v, re syscallarg(struct timespec *) rqtp; syscallarg(struct timespec *) rmtp; } */ *uap = v; - struct timespec rqt; - struct timespec rmt; - struct timeval atv, utv; - int error, s, timo; + struct timespec rmt, rqt; + int error, timo; error = copyin(SCARG(uap, rqtp), &rqt, sizeof(struct timespec)); if (error) return (error); - TIMESPEC_TO_TIMEVAL(&atv,&rqt); - if (itimerfix(&atv)) + if (itimespecfix(&rqt)) return (EINVAL); - s = splclock(); - timeradd(&atv,&time,&atv); - timo = hzto(&atv); + timo = tstohz(&rqt); /* * Avoid inadvertantly sleeping forever */ if (timo == 0) timo = 1; - splx(s); error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep", timo); if (error == ERESTART) @@ -298,15 +291,12 @@ sys_nanosleep(struct lwp *l, void *v, re if (SCARG(uap, rmtp)) { int error1; - s = splclock(); - utv = time; - splx(s); + getnanotime(&rmt); - timersub(&atv, &utv, &utv); - if (utv.tv_sec < 0) - timerclear(&utv); + timespecsub(&rqt, &rmt, &rmt); + if (rmt.tv_sec < 0) + timespecclear(&rmt); - TIMEVAL_TO_TIMESPEC(&utv,&rmt); error1 = copyout((caddr_t)&rmt, (caddr_t)SCARG(uap,rmtp), sizeof(rmt)); if (error1) @@ -680,6 +670,7 @@ timer_settime(struct ptimer *pt) void timer_gettime(struct ptimer *pt, struct itimerval *aitv) { + struct timeval now; struct ptimer *ptn; *aitv = pt->pt_time; @@ -692,10 +683,11 @@ timer_gettime(struct ptimer *pt, struct * off. */ if (timerisset(&aitv->it_value)) { - if (timercmp(&aitv->it_value, &time, <)) + getmicrotime(&now); + if (timercmp(&aitv->it_value, &now, <)) timerclear(&aitv->it_value); else - timersub(&aitv->it_value, &time, + timersub(&aitv->it_value, &now, &aitv->it_value); } } else if (pt->pt_active) { @@ -747,9 +739,10 @@ int dotimer_settime(int timerid, struct itimerspec *value, struct itimerspec *ovalue, int flags, struct proc *p) { - int s; + struct timeval now; struct itimerval val, oval; struct ptimer *pt; + int s; if ((p->p_timers == NULL) || (timerid < 2) || (timerid >= TIMER_MAX) || @@ -774,12 +767,15 @@ dotimer_settime(int timerid, struct itim */ if (timerisset(&pt->pt_time.it_value)) { if (pt->pt_type == CLOCK_REALTIME) { - if ((flags & TIMER_ABSTIME) == 0) - timeradd(&pt->pt_time.it_value, &time, + if ((flags & TIMER_ABSTIME) == 0) { + getmicrotime(&now); + timeradd(&pt->pt_time.it_value, &now, &pt->pt_time.it_value); + } } else { if ((flags & TIMER_ABSTIME) != 0) { - timersub(&pt->pt_time.it_value, &time, + getmicrotime(&now); + timersub(&pt->pt_time.it_value, &now, &pt->pt_time.it_value); if (!timerisset(&pt->pt_time.it_value) || pt->pt_time.it_value.tv_sec < 0) { @@ -868,6 +864,49 @@ sys_timer_getoverrun(struct lwp *l, void return (0); } +/* + * Real interval timer expired: + * send process whose timer expired an alarm signal. + * If time is not set up to reload, then just return. + * Else compute next time timer should go off which is > current time. + * This is where delay in processing this timeout causes multiple + * SIGALRM calls to be compressed into one. + */ +void +realtimerexpire(void *arg) +{ + struct timeval now; + struct ptimer *pt; + int s; + + pt = (struct ptimer *)arg; + + itimerfire(pt); + + if (!timerisset(&pt->pt_time.it_interval)) { + timerclear(&pt->pt_time.it_value); + return; + } + 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++; + } +} + /* Glue function that triggers an upcall; called from userret(). */ static void timerupcall(struct lwp *l, void *arg) @@ -909,48 +948,6 @@ timerupcall(struct lwp *l, void *arg) KERNEL_PROC_UNLOCK(l); } - -/* - * Real interval timer expired: - * send process whose timer expired an alarm signal. - * If time is not set up to reload, then just return. - * Else compute next time timer should go off which is > current time. - * This is where delay in processing this timeout causes multiple - * SIGALRM calls to be compressed into one. - */ -void -realtimerexpire(void *arg) -{ - struct ptimer *pt; - int s; - - pt = (struct ptimer *)arg; - - itimerfire(pt); - - if (!timerisset(&pt->pt_time.it_interval)) { - timerclear(&pt->pt_time.it_value); - return; - } - for (;;) { - s = splclock(); - timeradd(&pt->pt_time.it_value, - &pt->pt_time.it_interval, &pt->pt_time.it_value); - if (timercmp(&pt->pt_time.it_value, &time, >)) { - /* - * 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++; - } -} - /* BSD routine to get the value of an interval timer. */ /* ARGSUSED */ int @@ -1028,6 +1025,7 @@ sys_setitimer(struct lwp *l, void *v, re int dosetitimer(struct proc *p, int which, struct itimerval *itvp) { + struct timeval now; struct ptimer *pt; int s; @@ -1075,7 +1073,8 @@ dosetitimer(struct proc *p, int which, s s = splclock(); if ((which == ITIMER_REAL) && timerisset(&pt->pt_time.it_value)) { /* Convert to absolute time */ - timeradd(&pt->pt_time.it_value, &time, &pt->pt_time.it_value); + getmicrotime(&now); + timeradd(&pt->pt_time.it_value, &now, &pt->pt_time.it_value); } timer_settime(pt); splx(s); @@ -1181,6 +1180,17 @@ itimerfix(struct timeval *tv) return (0); } +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); +} + /* * Decrement an interval timer by a specified number * of microseconds, which must be less than a second, @@ -1305,12 +1315,9 @@ int ratecheck(struct timeval *lasttime, const struct timeval *mininterval) { struct timeval tv, delta; - int s, rv = 0; - - s = splclock(); - tv = mono_time; - splx(s); + int rv = 0; + getmicrouptime(&tv); timersub(&tv, lasttime, &delta); /* @@ -1333,12 +1340,9 @@ int ppsratecheck(struct timeval *lasttime, int *curpps, int maxpps) { struct timeval tv, delta; - int s, rv; - - s = splclock(); - tv = mono_time; - splx(s); + int rv; + getmicrouptime(&tv); timersub(&tv, lasttime, &delta); /* Index: 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 --- kern/subr_disk.c 15 Oct 2005 17:29:26 -0000 1.71 +++ kern/subr_disk.c 26 Oct 2005 14:25:22 -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: kern/subr_pool.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_pool.c,v retrieving revision 1.106 diff -d -p -u -r1.106 subr_pool.c --- kern/subr_pool.c 16 Oct 2005 02:55:18 -0000 1.106 +++ kern/subr_pool.c 26 Oct 2005 14:25:23 -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: 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 --- kern/sys_generic.c 29 May 2005 22:24:15 -0000 1.83 +++ kern/sys_generic.c 26 Oct 2005 14:25:23 -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: kern/sys_pipe.c =================================================================== RCS file: /cvsroot/src/sys/kern/sys_pipe.c,v retrieving revision 1.66 diff -d -p -u -r1.66 sys_pipe.c --- kern/sys_pipe.c 11 Sep 2005 17:55:26 -0000 1.66 +++ kern/sys_pipe.c 26 Oct 2005 14:25:24 -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); @@ -582,7 +574,7 @@ again: } if (error == 0) - PIPE_TIMESTAMP(&rpipe->pipe_atime); + getmicrotime(&rpipe->pipe_atime); PIPE_LOCK(rpipe); pipeunlock(rpipe); @@ -1079,7 +1071,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: 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 --- kern/sysv_msg.c 1 Apr 2005 11:59:37 -0000 1.39 +++ kern/sysv_msg.c 26 Oct 2005 14:25:24 -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: kern/sysv_sem.c =================================================================== RCS file: /cvsroot/src/sys/kern/sysv_sem.c,v retrieving revision 1.56 diff -d -p -u -r1.56 sysv_sem.c --- kern/sysv_sem.c 1 Apr 2005 11:59:37 -0000 1.56 +++ kern/sysv_sem.c 26 Oct 2005 14:25:24 -0000 @@ -391,7 +391,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: @@ -548,7 +548,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, @@ -800,7 +800,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: kern/sysv_shm.c =================================================================== RCS file: /cvsroot/src/sys/kern/sysv_shm.c,v retrieving revision 1.84 diff -d -p -u -r1.84 sysv_shm.c --- kern/sysv_shm.c 1 Apr 2005 11:59:37 -0000 1.84 +++ kern/sysv_shm.c 26 Oct 2005 14:25:25 -0000 @@ -209,7 +209,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); @@ -380,7 +380,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; @@ -447,7 +447,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) @@ -562,7 +562,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: kern/tty.c =================================================================== RCS file: /cvsroot/src/sys/kern/tty.c,v retrieving revision 1.176 diff -d -p -u -r1.176 tty.c --- kern/tty.c 13 Oct 2005 16:18:43 -0000 1.176 +++ kern/tty.c 26 Oct 2005 14:25:25 -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: 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 --- lib/libkern/arc4random.c 26 Feb 2005 22:58:56 -0000 1.14 +++ lib/libkern/arc4random.c 26 Oct 2005 14:25:25 -0000 @@ -72,14 +72,22 @@ #define ARC4_RESEED_SECONDS 300 #define ARC4_KEYBYTES 32 /* 256 bit key */ +#ifdef _STANDALONE /* XXX ugly! */ +static void +getbinuptime(struct bintime *bt) +{ + + /* XXX - print warning? */ + bt->sec = 1; + bt->frac = 0; +} +#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 struct bintime arc4_nextreseed; static inline u_int8_t arc4_randbyte(void); @@ -123,8 +131,8 @@ 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; + getbinuptime(&arc4_nextreseed); + arc4_nextreseed.sec += 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 +151,8 @@ arc4_randrekey(void) } /* Reset for next reseed cycle. */ - arc4_tv_nextreseed = mono_time; - arc4_tv_nextreseed.tv_sec += ARC4_RESEED_SECONDS; + getbinuptime(&arc4_nextreseed); + arc4_nextreseed.sec += ARC4_RESEED_SECONDS; arc4_numruns = 0; /* @@ -192,6 +200,7 @@ arc4_randbyte(void) u_int32_t arc4random(void) { + struct bintime bt; u_int32_t ret; int i; @@ -199,8 +208,9 @@ arc4random(void) if (!arc4_initialized) arc4_init(); + getbinuptime(&bt); if ((++arc4_numruns > ARC4_MAXRUNS) || - (mono_time.tv_sec > arc4_tv_nextreseed.tv_sec)) { + (bt.sec > arc4_nextreseed.sec)) { arc4_randrekey(); } @@ -212,6 +222,7 @@ arc4random(void) void arc4randbytes(void *p, size_t len) { + struct bintime bt; u_int8_t *buf; size_t i; @@ -220,8 +231,9 @@ arc4randbytes(void *p, size_t len) for (i = 0; i < len; buf[i] = arc4_randbyte(), i++) ; arc4_numruns += len / sizeof(u_int32_t); + getbinuptime(&bt); if ((arc4_numruns > ARC4_MAXRUNS) || - (mono_time.tv_sec > arc4_tv_nextreseed.tv_sec)) { + (bt.sec > arc4_nextreseed.sec)) { arc4_randrekey(); } } Index: miscfs/kernfs/kernfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/kernfs/kernfs_vnops.c,v retrieving revision 1.112 diff -d -p -u -r1.112 kernfs_vnops.c --- miscfs/kernfs/kernfs_vnops.c 1 Sep 2005 06:25:26 -0000 1.112 +++ miscfs/kernfs/kernfs_vnops.c 26 Oct 2005 14:25:26 -0000 @@ -829,17 +829,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: miscfs/portal/portal_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/portal/portal_vnops.c,v retrieving revision 1.60 diff -d -p -u -r1.60 portal_vnops.c --- miscfs/portal/portal_vnops.c 30 Aug 2005 20:08:01 -0000 1.60 +++ miscfs/portal/portal_vnops.c 26 Oct 2005 14:25:26 -0000 @@ -551,12 +551,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: miscfs/procfs/procfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_vnops.c,v retrieving revision 1.126 diff -d -p -u -r1.126 procfs_vnops.c --- miscfs/procfs/procfs_vnops.c 1 Oct 2005 03:17:37 -0000 1.126 +++ miscfs/procfs/procfs_vnops.c 26 Oct 2005 14:25:27 -0000 @@ -593,9 +593,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 @@ -603,13 +601,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: 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 --- miscfs/syncfs/sync_subr.c 11 Sep 2005 17:55:56 -0000 1.19 +++ miscfs/syncfs/sync_subr.c 26 Oct 2005 14:25:27 -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: 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 --- net/if_arcsubr.c 5 Jun 2005 22:31:40 -0000 1.49 +++ net/if_arcsubr.c 26 Oct 2005 14:25:27 -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: 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 --- net/if_bridge.c 1 Jun 2005 19:45:34 -0000 1.31 +++ net/if_bridge.c 26 Oct 2005 14:25:28 -0000 @@ -796,6 +796,7 @@ bridge_ioctl_gifs(struct bridge_softc *s int bridge_ioctl_rts(struct bridge_softc *sc, void *arg) { + struct bintime bt; struct ifbaconf *bac = arg; struct bridge_rtnode *brt; struct ifbareq bareq; @@ -811,9 +812,10 @@ 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) { + getbinuptime(&bt); + bareq.ifba_expire = brt->brt_expire - bt.sec; + } else bareq.ifba_expire = 0; bareq.ifba_flags = brt->brt_flags; @@ -1617,6 +1619,7 @@ int bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, struct ifnet *dst_if, int setflags, uint8_t flags) { + struct bintime bt; struct bridge_rtnode *brt; int error; @@ -1638,7 +1641,8 @@ bridge_rtupdate(struct bridge_softc *sc, return (ENOMEM); memset(brt, 0, sizeof(*brt)); - brt->brt_expire = mono_time.tv_sec + sc->sc_brttimeout; + getbinuptime(&bt); + brt->brt_expire = bt.sec + sc->sc_brttimeout; brt->brt_flags = IFBAF_DYNAMIC; memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN); @@ -1651,8 +1655,12 @@ 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 { + getbinuptime(&bt); + brt->brt_expire = bt.sec + sc->sc_brttimeout; + } } return (0); @@ -1733,12 +1741,14 @@ bridge_timer(void *arg) void bridge_rtage(struct bridge_softc *sc) { + struct bintime bt; struct bridge_rtnode *brt, *nbrt; 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) + getbinuptime(&bt); + if (bt.sec >= brt->brt_expire) bridge_rtnode_destroy(sc, brt); } } Index: 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 --- net/if_ecosubr.c 18 Aug 2005 00:30:58 -0000 1.17 +++ net/if_ecosubr.c 26 Oct 2005 14:25:28 -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: 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 --- net/if_ethersubr.c 10 Jun 2005 11:11:38 -0000 1.126 +++ net/if_ethersubr.c 26 Oct 2005 14:25:28 -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: 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 --- net/if_fddisubr.c 30 May 2005 04:17:59 -0000 1.56 +++ net/if_fddisubr.c 26 Oct 2005 14:25:29 -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: 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 --- net/if_hippisubr.c 30 May 2005 04:17:59 -0000 1.20 +++ net/if_hippisubr.c 26 Oct 2005 14:25:29 -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: 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 --- net/if_ieee1394subr.c 6 Aug 2005 14:09:54 -0000 1.30 +++ net/if_ieee1394subr.c 26 Oct 2005 14:25:29 -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: 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 --- net/if_ppp.c 29 May 2005 21:22:52 -0000 1.101 +++ net/if_ppp.c 26 Oct 2005 14:25:30 -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: 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 --- net/if_pppoe.c 31 Aug 2005 00:00:26 -0000 1.61 +++ net/if_pppoe.c 26 Oct 2005 14:25:30 -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: 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 --- net/if_sl.c 18 Aug 2005 00:30:58 -0000 1.92 +++ net/if_sl.c 26 Oct 2005 14:25:30 -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) { + getbintime(&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; + getbintime(&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; + getbintime(&sc->sc_lastpacket); s = spltty(); @@ -976,7 +977,7 @@ slintr(void *arg) } sc->sc_if.if_ipackets++; - sc->sc_lastpacket = time; + getbintime(&sc->sc_lastpacket); #ifdef INET s = splnet(); Index: 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 --- net/if_slvar.h 26 Feb 2005 22:45:09 -0000 1.27 +++ net/if_slvar.h 26 Oct 2005 14:25:30 -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: 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 --- net/if_spppsubr.c 29 May 2005 21:22:53 -0000 1.85 +++ net/if_spppsubr.c 26 Oct 2005 14:25:32 -0000 @@ -464,6 +464,7 @@ static const struct cp *cps[IDX_COUNT] = void sppp_input(struct ifnet *ifp, struct mbuf *m) { + struct bintime bt; struct ppp_header *h = NULL; struct ifqueue *inq = 0; u_int16_t protocol; @@ -475,7 +476,8 @@ 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; + getbinuptime(&bt); + sp->pp_last_receive = bt.sec; } if (m->m_pkthdr.len <= PPP_HEADER_LEN) { @@ -612,7 +614,8 @@ 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; + getbinuptime(&bt); + sp->pp_last_activity = bt.sec; } break; #endif @@ -627,7 +630,8 @@ 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; + getbinuptime(&bt); + sp->pp_last_activity = bt.sec; } break; #endif @@ -686,6 +690,7 @@ static int sppp_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rt) { + struct bintime bt; struct sppp *sp = (struct sppp *) ifp; struct ppp_header *h = NULL; struct ifqueue *ifq = NULL; /* XXX */ @@ -695,7 +700,8 @@ sppp_output(struct ifnet *ifp, struct mb s = splnet(); - sp->pp_last_activity = mono_time.tv_sec; + getbinuptime(&bt); + sp->pp_last_activity = bt.sec; if ((ifp->if_flags & IFF_UP) == 0 || (ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == 0) { @@ -1241,11 +1247,14 @@ static void sppp_cisco_send(struct sppp *sp, int type, int32_t par1, int32_t par2) { STDDCL; + struct bintime bt; 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; + getbinuptime(&bt); + t = bt.sec * 1000; MGETHDR(m, M_DONTWAIT, MT_DATA); if (! m) return; @@ -2022,9 +2031,11 @@ static void sppp_lcp_up(struct sppp *sp) { STDDCL; + struct bintime bt; /* Initialize activity timestamp: opening a connection is an activity */ - sp->pp_last_receive = sp->pp_last_activity = mono_time.tv_sec; + getbinuptime(&bt); + sp->pp_last_receive = sp->pp_last_activity = bt.sec; /* * If this interface is passive or dial-on-demand, and we are @@ -4632,12 +4643,14 @@ sppp_auth_send(const struct cp *cp, stru static void sppp_keepalive(void *dummy) { + struct bintime bt; struct sppp *sp; int s; time_t now; s = splnet(); - now = mono_time.tv_sec; + getbinuptime(&bt); + now = bt.sec; for (sp=spppq; sp; sp=sp->pp_next) { struct ifnet *ifp = &sp->pp_if; Index: 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 --- net/if_strip.c 18 Aug 2005 00:30:58 -0000 1.61 +++ net/if_strip.c 26 Oct 2005 14:25:33 -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) { + getbintime(&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; + getbintime(&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; + getbintime(&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; + getbintime(&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; + getbintime(&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: 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 --- net/if_stripvar.h 5 Dec 2004 05:43:04 -0000 1.13 +++ net/if_stripvar.h 26 Oct 2005 14:25:33 -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: 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 --- net/if_tap.c 20 Jun 2005 02:49:19 -0000 1.10 +++ net/if_tap.c 26 Oct 2005 14:25:33 -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 now; + 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 time. It's not meant + * for anything but avoiding hard-coding an address. */ - ui = (mono_time.tv_sec ^ mono_time.tv_usec) & 0xffffff; + getmicrotime(&now); + ui = (now.tv_sec ^ now.tv_usec) & 0xffffff; memcpy(enaddr+3, (u_int8_t *)&ui, 3); aprint_normal("%s: Ethernet address %s\n", sc->sc_dev.dv_xname, Index: 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 --- net/if_tokensubr.c 30 May 2005 04:17:59 -0000 1.32 +++ net/if_tokensubr.c 26 Oct 2005 14:25:34 -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: net/route.c =================================================================== RCS file: /cvsroot/src/sys/net/route.c,v retrieving revision 1.66 diff -d -p -u -r1.66 route.c --- net/route.c 29 May 2005 21:22:53 -0000 1.66 +++ net/route.c 26 Oct 2005 14:25:34 -0000 @@ -945,13 +945,12 @@ rt_timer_add(struct rtentry *rt, void (*func)(struct rtentry *, struct rttimer *), struct rttimer_queue *queue) { + struct bintime bt; struct rttimer *r; long current_time; - int s; - s = splclock(); - current_time = mono_time.tv_sec; - splx(s); + getbinuptime(&bt); + current_time = bt.sec; /* * If there's already a timer with this action, destroy it before @@ -991,14 +990,14 @@ rt_timer_add(struct rtentry *rt, void rt_timer_timer(void *arg) { + struct bintime bt; struct rttimer_queue *rtq; struct rttimer *r; long current_time; int s; - s = splclock(); - current_time = mono_time.tv_sec; - splx(s); + getbinuptime(&bt); + current_time = bt.sec; s = splsoftnet(); for (rtq = LIST_FIRST(&rttimer_queue_head); rtq != NULL; Index: 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 --- netatalk/at_control.c 26 Feb 2005 22:45:09 -0000 1.10 +++ netatalk/at_control.c 26 Oct 2005 14:25:34 -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: 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 --- netccitt/pk_acct.c 6 Oct 2005 16:32:14 -0000 1.20 +++ netccitt/pk_acct.c 26 Oct 2005 14:25:34 -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: 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 --- netccitt/pk_subr.c 29 May 2005 21:53:52 -0000 1.30 +++ netccitt/pk_subr.c 26 Oct 2005 14:25:35 -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: 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 --- netinet/if_arp.c 20 Jun 2005 02:49:18 -0000 1.106 +++ netinet/if_arp.c 26 Oct 2005 14:25:36 -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,14 @@ 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) { - time.tv_sec++; + if (time_second == 0) { + struct timespec ts; + ts.tv_sec = 1; + ts.tv_nsec = 0; + tc_setclock(&ts); } callout_init(&arptimer_ch); callout_reset(&arptimer_ch, hz, arptimer, NULL); @@ -456,7 +460,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 +691,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 +723,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 +1035,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: 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 --- netinet/in_gif.c 26 Jun 2005 10:39:21 -0000 1.45 +++ netinet/in_gif.c 26 Oct 2005 14:25:36 -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: 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 --- netinet/ip_flow.c 17 Oct 2005 19:51:24 -0000 1.30 +++ netinet/ip_flow.c 26 Oct 2005 14:25:36 -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: 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 --- netinet/ip_id.c 23 Mar 2004 05:31:54 -0000 1.8 +++ netinet/ip_id.c 26 Oct 2005 14:25:36 -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: netinet/ip_input.c =================================================================== RCS file: /cvsroot/src/sys/netinet/ip_input.c,v retrieving revision 1.220 diff -d -p -u -r1.220 ip_input.c --- netinet/ip_input.c 23 Oct 2005 18:38:53 -0000 1.220 +++ netinet/ip_input.c 26 Oct 2005 14:25:36 -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: netinet/tcp_input.c =================================================================== RCS file: /cvsroot/src/sys/netinet/tcp_input.c,v retrieving revision 1.236 diff -d -p -u -r1.236 tcp_input.c --- netinet/tcp_input.c 12 Aug 2005 14:41:00 -0000 1.236 +++ netinet/tcp_input.c 26 Oct 2005 14:25:38 -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: netinet6/icmp6.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/icmp6.c,v retrieving revision 1.111 diff -d -p -u -r1.111 icmp6.c --- netinet6/icmp6.c 19 Oct 2005 20:42:54 -0000 1.111 +++ netinet6/icmp6.c 26 Oct 2005 14:25:40 -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: netinet6/in6.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/in6.c,v retrieving revision 1.93 diff -d -p -u -r1.93 in6.c --- netinet6/in6.c 29 May 2005 21:43:51 -0000 1.93 +++ netinet6/in6.c 26 Oct 2005 14:25:42 -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: netinet6/in6.h =================================================================== RCS file: /cvsroot/src/sys/netinet6/in6.h,v retrieving revision 1.47 diff -d -p -u -r1.47 in6.h --- netinet6/in6.h 28 Aug 2005 21:01:53 -0000 1.47 +++ netinet6/in6.h 26 Oct 2005 14:25:42 -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: 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 --- netinet6/in6_gif.c 26 Jun 2005 10:39:21 -0000 1.43 +++ netinet6/in6_gif.c 26 Oct 2005 14:25:42 -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: 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 --- netinet6/ip6_forward.c 29 May 2005 21:43:51 -0000 1.45 +++ netinet6/ip6_forward.c 26 Oct 2005 14:25:42 -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: 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 --- netinet6/ip6_id.c 23 Mar 2004 05:31:54 -0000 1.13 +++ netinet6/ip6_id.c 26 Oct 2005 14:25:42 -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: 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 --- netinet6/ip6_mroute.c 21 Oct 2005 18:00:45 -0000 1.67 +++ netinet6/ip6_mroute.c 26 Oct 2005 14:25:43 -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: netinet6/ipsec.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/ipsec.c,v retrieving revision 1.104 diff -d -p -u -r1.104 ipsec.c --- netinet6/ipsec.c 9 Sep 2005 15:38:05 -0000 1.104 +++ netinet6/ipsec.c 26 Oct 2005 14:25:44 -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: netinet6/nd6.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/nd6.c,v retrieving revision 1.94 diff -d -p -u -r1.94 nd6.c --- netinet6/nd6.c 29 May 2005 21:43:51 -0000 1.94 +++ netinet6/nd6.c 26 Oct 2005 14:25:45 -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: 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 --- netinet6/nd6_rtr.c 29 May 2005 21:43:51 -0000 1.52 +++ netinet6/nd6_rtr.c 26 Oct 2005 14:25:45 -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: 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 --- netipsec/ipsec_osdep.h 18 Aug 2005 00:30:59 -0000 1.13 +++ netipsec/ipsec_osdep.h 26 Oct 2005 14:25:46 -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: 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 --- netiso/iso_snpac.c 31 May 2005 01:37:06 -0000 1.33 +++ netiso/iso_snpac.c 26 Oct 2005 14:25:46 -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: 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 --- netiso/tp_input.c 29 May 2005 21:27:45 -0000 1.22 +++ netiso/tp_input.c 26 Oct 2005 14:25:47 -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: 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 --- netiso/tp_iso.c 26 Feb 2005 22:39:49 -0000 1.19 +++ netiso/tp_iso.c 26 Oct 2005 14:25:47 -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: 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 --- netiso/tp_meas.c 19 Apr 2004 05:16:46 -0000 1.11 +++ netiso/tp_meas.c 26 Oct 2005 14:25:47 -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: 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 --- netiso/tp_pcb.c 19 Apr 2004 05:16:46 -0000 1.26 +++ netiso/tp_pcb.c 26 Oct 2005 14:25:47 -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: 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 --- netiso/tp_usrreq.c 29 May 2005 21:27:45 -0000 1.26 +++ netiso/tp_usrreq.c 26 Oct 2005 14:25:47 -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: netkey/key.c =================================================================== RCS file: /cvsroot/src/sys/netkey/key.c,v retrieving revision 1.136 diff -d -p -u -r1.136 key.c --- netkey/key.c 3 Oct 2005 13:14:38 -0000 1.136 +++ netkey/key.c 26 Oct 2005 14:25:49 -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: 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 --- netns/ns_error.c 26 Feb 2005 22:39:50 -0000 1.17 +++ netns/ns_error.c 26 Oct 2005 14:25:50 -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: 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 --- netns/ns_input.c 26 Feb 2005 22:39:50 -0000 1.22 +++ netns/ns_input.c 26 Oct 2005 14:25:50 -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: 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 --- netsmb/smb_trantcp.c 26 Feb 2005 22:39:50 -0000 1.18 +++ netsmb/smb_trantcp.c 26 Oct 2005 14:25:50 -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: nfs/nfs.h =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs.h,v retrieving revision 1.51 diff -d -p -u -r1.51 nfs.h --- nfs/nfs.h 25 Sep 2005 21:57:40 -0000 1.51 +++ nfs/nfs.h 26 Oct 2005 14:25:50 -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: 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 --- nfs/nfs_nqlease.c 22 May 2004 22:52:15 -0000 1.56 +++ nfs/nfs_nqlease.c 26 Oct 2005 14:25:51 -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: 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 --- nfs/nfs_serv.c 6 Oct 2005 10:23:01 -0000 1.98 +++ nfs/nfs_serv.c 26 Oct 2005 14:25:52 -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: nfs/nfs_socket.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_socket.c,v retrieving revision 1.117 diff -d -p -u -r1.117 nfs_socket.c --- nfs/nfs_socket.c 25 Sep 2005 12:49:09 -0000 1.117 +++ nfs/nfs_socket.c 26 Oct 2005 14:25:52 -0000 @@ -862,7 +862,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 @@ -1100,7 +1100,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 @@ -1337,8 +1337,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; @@ -1393,7 +1393,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); @@ -1591,6 +1591,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; @@ -1694,8 +1695,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(); } @@ -1703,7 +1704,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) @@ -2088,7 +2090,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: nfs/nfs_subs.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_subs.c,v retrieving revision 1.153 diff -d -p -u -r1.153 nfs_subs.c --- nfs/nfs_subs.c 23 Sep 2005 12:10:33 -0000 1.153 +++ nfs/nfs_subs.c 26 Oct 2005 14:25:53 -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: 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 --- nfs/nfs_syscalls.c 23 Sep 2005 12:10:33 -0000 1.82 +++ nfs/nfs_syscalls.c 26 Oct 2005 14:25:54 -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: 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 --- nfs/nfs_vfsops.c 23 Sep 2005 12:10:33 -0000 1.150 +++ nfs/nfs_vfsops.c 26 Oct 2005 14:25:54 -0000 @@ -58,6 +58,7 @@ __KERNEL_RCSID(0, "$NetBSD: nfs_vfsops.c #include #include #include +#include #include #include @@ -299,6 +300,7 @@ nfs_fsinfo(nmp, vp, cred, p) int nfs_mountroot() { + struct timespec ts; struct nfs_diskless *nd; struct vattr attr; struct mount *mp; @@ -315,11 +317,14 @@ 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) - time.tv_sec = NFS_MAXATTRTIMO; + if (time_second < NFS_MAXATTRTIMO) { + ts.tv_sec = NFS_MAXATTRTIMO; + ts.tv_nsec = 0; + tc_setclock(&ts); + } /* * Call nfs_boot_init() to fill in the nfs_diskless struct. Index: nfs/nfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_vnops.c,v retrieving revision 1.227 diff -d -p -u -r1.227 nfs_vnops.c --- nfs/nfs_vnops.c 19 Sep 2005 00:49:52 -0000 1.227 +++ nfs/nfs_vnops.c 26 Oct 2005 14:25:55 -0000 @@ -336,12 +336,14 @@ nfs_access(v) u_int32_t mode, rmode; const int v3 = NFS_ISV3(vp); #endif + struct bintime bt; int cachevalid; struct nfsnode *np = VTONFS(vp); struct nfsmount *nmp = VFSTONFS(vp->v_mount); + getbinuptime(&bt); cachevalid = (np->n_accstamp != -1 && - (mono_time.tv_sec - np->n_accstamp) < NFS_ATTRTIMEO(nmp, np) && + (bt.sec - np->n_accstamp) < NFS_ATTRTIMEO(nmp, np) && np->n_accuid == ap->a_cred->cr_uid); /* @@ -435,7 +437,8 @@ 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; + getbinuptime(&bt); + np->n_accstamp = bt.sec; np->n_accuid = ap->a_cred->cr_uid; np->n_accmode = ap->a_mode; np->n_accerror = error; @@ -1785,7 +1788,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 @@ -1795,14 +1800,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); } @@ -3536,8 +3537,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)); } @@ -3560,8 +3560,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)); } @@ -3618,8 +3617,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)); } @@ -3642,8 +3640,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)); } @@ -3667,14 +3664,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: nfs/nfsm_subs.h =================================================================== RCS file: /cvsroot/src/sys/nfs/nfsm_subs.h,v retrieving revision 1.42 diff -d -p -u -r1.42 nfsm_subs.h --- nfs/nfsm_subs.h 1 Oct 2005 06:13:55 -0000 1.42 +++ nfs/nfsm_subs.h 26 Oct 2005 14:25:55 -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_atime = *ts; \ + getnanotime(&(a)->va_atime); \ (a)->va_vaflags |= VA_UTIMES_NULL; \ break; \ }; } Index: nfs/nqnfs.h =================================================================== RCS file: /cvsroot/src/sys/nfs/nqnfs.h,v retrieving revision 1.16 diff -d -p -u -r1.16 nqnfs.h --- nfs/nqnfs.h 21 Apr 2004 02:22:49 -0000 1.16 +++ nfs/nqnfs.h 26 Oct 2005 14:25:56 -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: opencrypto/crypto.c =================================================================== RCS file: /cvsroot/src/sys/opencrypto/crypto.c,v retrieving revision 1.10 diff -d -p -u -r1.10 crypto.c --- opencrypto/crypto.c 26 Feb 2005 22:39:52 -0000 1.10 +++ opencrypto/crypto.c 26 Oct 2005 14:25:56 -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/kernel.h =================================================================== RCS file: /cvsroot/src/sys/sys/kernel.h,v retrieving revision 1.22 diff -d -p -u -r1.22 kernel.h --- sys/kernel.h 2 Oct 2003 12:14:00 -0000 1.22 +++ sys/kernel.h 26 Oct 2005 14:25:56 -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/sysctl.h =================================================================== RCS file: /cvsroot/src/sys/sys/sysctl.h,v retrieving revision 1.141 diff -d -p -u -r1.141 sysctl.h --- sys/sysctl.h 7 Sep 2005 16:26:16 -0000 1.141 +++ sys/sysctl.h 26 Oct 2005 14:25:57 -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/systm.h =================================================================== RCS file: /cvsroot/src/sys/sys/systm.h,v retrieving revision 1.181 diff -d -p -u -r1.181 systm.h --- sys/systm.h 23 Oct 2005 00:09:14 -0000 1.181 +++ sys/systm.h 26 Oct 2005 14:25:57 -0000 @@ -267,25 +267,18 @@ 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 hardupdate(long offset); -#ifdef PPS_SYNC -void hardpps(struct timeval *, long); -extern void *pps_kc_hardpps_source; -extern int pps_kc_hardpps_mode; -#endif -#endif void initclocks(void); void inittodr(time_t); void resettodr(void); void cpu_initclocks(void); void setrootfstime(time_t); +#ifdef NTP +void ntp_init(void); +#endif void startprofclock(struct proc *); void stopprofclock(struct proc *); Index: 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/time.h 23 Oct 2005 00:09:14 -0000 1.51 +++ sys/time.h 26 Oct 2005 14:25:57 -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/timepps.h =================================================================== RCS file: /cvsroot/src/sys/sys/timepps.h,v retrieving revision 1.10 diff -d -p -u -r1.10 timepps.h --- sys/timepps.h 19 Sep 2005 03:18:00 -0000 1.10 +++ sys/timepps.h 26 Oct 2005 14:25:57 -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/timetc.h =================================================================== RCS file: sys/timetc.h diff -N sys/timetc.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/timetc.h 26 Oct 2005 14:25:57 -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/timevar.h =================================================================== RCS file: /cvsroot/src/sys/sys/timevar.h,v retrieving revision 1.2 diff -d -p -u -r1.2 timevar.h --- sys/timevar.h 24 Oct 2005 13:43:27 -0000 1.2 +++ sys/timevar.h 26 Oct 2005 14:25:57 -0000 @@ -36,18 +36,162 @@ * 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" !) + * + */ + +void binuptime(struct bintime *bt); +void nanouptime(struct timespec *tsp); +void microuptime(struct timeval *tvp); + +void bintime(struct bintime *bt); +void nanotime(struct timespec *tsp); +void microtime(struct timeval *tvp); + +void getbinuptime(struct bintime *bt); +void getnanouptime(struct timespec *tsp); +void getmicrouptime(struct timeval *tvp); + +void getbintime(struct bintime *bt); +void getnanotime(struct timespec *tsp); +void getmicrotime(struct timeval *tvp); + +/* 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 *); + +/* 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 */ +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/timex.h =================================================================== RCS file: /cvsroot/src/sys/sys/timex.h,v retrieving revision 1.8 diff -d -p -u -r1.8 timex.h --- sys/timex.h 3 Feb 2005 19:20:02 -0000 1.8 +++ sys/timex.h 26 Oct 2005 14:25:57 -0000 @@ -1,24 +1,35 @@ +/* XXX !__HAVE_TIMECOUNTER case */ /* $NetBSD: timex.h,v 1.8 2005/02/03 19:20:02 perry Exp $ */ -/****************************************************************************** - * * - * Copyright (c) David L. Mills 1993, 1994 * - * * - * 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. * - * * - ******************************************************************************/ +/*- + *********************************************************************** + * * + * 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. * @@ -36,168 +47,83 @@ * * 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 - * private syscalls and data structures and require specific kernel + * 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 syscall(SYS_ntp_gettime, tptr) + * int ntp_gettime(struct ntptimeval *ntv); * - * int SYS_ntp_gettime defined in syscall.h header file - * struct ntptimeval *tptr pointer to ntptimeval structure + * 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, mode, tptr) - * - * int SYS_ntp_adjtime defined in syscall.h header file - * struct timex *tptr pointer to timex structure + * 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 engineering parameters of the - * phase-lock loop (PLL) model used in the kernel implementation. These - * parameters have been carefully chosen by analysis for good stability - * and wide dynamic range. - * - * The hz variable is defined in the kernel build environment. It - * establishes the timer interrupt frequency, 100 Hz for the SunOS - * kernel, 256 Hz for the Ultrix kernel and 1024 Hz for the OSF/1 - * kernel. SHIFT_HZ expresses the same value as the nearest power of two - * in order to avoid hardware multiply operations. - * - * SHIFT_KG and SHIFT_KF establish the damping of the PLL and are chosen - * for a slightly underdamped convergence characteristic. SHIFT_KH - * establishes the damping of the FLL and is chosen by wisdom and black - * art. - * - * MAXTC establishes the maximum time constant of the PLL. With the - * SHIFT_KG and SHIFT_KF values given and a time constant range from - * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours, - * respectively. - */ - - -#define SHIFT_KG 6 /* phase factor (shift) */ -#define SHIFT_KF 16 /* PLL frequency factor (shift) */ -#define SHIFT_KH 2 /* FLL frequency factor (shift) */ -#define MAXTC 6 /* maximum time constant (shift) */ - -/* - * The following defines establish the scaling of the various variables - * used by the PLL. They are chosen to allow the greatest precision - * possible without overflow of a 32-bit word. - * - * SHIFT_SCALE defines the scaling (shift) of the time_phase variable, - * which serves as a an extension to the low-order bits of the system - * clock variable time.tv_usec. - * - * SHIFT_UPDATE defines the scaling (shift) of the time_offset variable, - * which represents the current time offset with respect to standard - * time. - * - * SHIFT_USEC defines the scaling (shift) of the time_freq and - * time_tolerance variables, which represent the current frequency - * offset and maximum frequency tolerance. - * - * FINEUSEC is 1 us in SHIFT_UPDATE units of the time_phase variable. - */ -#define SHIFT_SCALE 22 /* phase scale (shift) */ -#define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* time offset scale (shift) */ -#define SHIFT_USEC 16 /* frequency offset scale (shift) */ -#define FINEUSEC (1L << SHIFT_SCALE) /* 1 us in phase units */ - -/* - * The following defines establish the performance envelope of the PLL. - * They insure it operates within predefined limits, in order to satisfy - * correctness assertions. An excursion which exceeds these bounds is - * clamped to the bound and operation proceeds accordingly. In practice, - * this can occur only if something has failed or is operating out of - * tolerance, but otherwise the PLL continues to operate in a stable - * mode. - * - * MAXPHASE must be set greater than or equal to CLOCK.MAX (128 ms), as - * defined in the NTP specification. CLOCK.MAX establishes the maximum - * time offset allowed before the system time is reset, rather than - * incrementally adjusted. Here, the maximum offset is clamped to - * MAXPHASE only in order to prevent overflow errors due to defective - * protocol implementations. - * - * MAXFREQ is the maximum frequency tolerance of the CPU clock - * oscillator plus the maximum slew rate allowed by the protocol. It - * should be set to at least the frequency tolerance of the oscillator - * plus 100 ppm for vernier frequency adjustments. If the kernel - * PPS discipline code is configured (PPS_SYNC), the oscillator time and - * frequency are disciplined to an external source, presumably with - * negligible time and frequency error relative to UTC, and MAXFREQ can - * be reduced. - * - * MAXTIME is the maximum jitter tolerance of the PPS signal if the - * kernel PPS discipline code is configured (PPS_SYNC). - * - * MINSEC and MAXSEC define the lower and upper bounds on the interval - * between protocol updates. - */ -#define MAXPHASE 512000L /* max phase error (us) */ -#ifdef PPS_SYNC -#define MAXFREQ (512L << SHIFT_USEC) /* max freq error (100 ppm) */ -#define MAXTIME (200L << PPS_AVG) /* max PPS error (jitter) (200 us) */ -#else -#define MAXFREQ (512L << SHIFT_USEC) /* max freq error (200 ppm) */ -#endif /* PPS_SYNC */ -#define MINSEC 16L /* min interval between updates (s) */ -#define MAXSEC 1200L /* max interval between updates (s) */ - -#ifdef PPS_SYNC -/* - * The following defines are used only if a pulse-per-second (PPS) - * signal is available and connected via a modem control lead, such as - * produced by the optional ppsclock feature incorporated in the Sun - * asynch driver. They establish the design parameters of the frequency- - * lock loop used to discipline the CPU clock oscillator to the PPS - * signal. - * - * PPS_AVG is the averaging factor for the frequency loop, as well as - * the time and frequency dispersion. - * - * PPS_SHIFT and PPS_SHIFTMAX specify the minimum and maximum - * calibration intervals, respectively, in seconds as a power of two. - * - * PPS_VALID is the maximum interval before the PPS signal is considered - * invalid and protocol updates used directly instead. - * - * MAXGLITCH is the maximum interval before a time offset of more than - * MAXTIME is believed. + * 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 PPS_AVG 2 /* pps averaging constant (shift) */ -#define PPS_SHIFT 2 /* min interval duration (s) (shift) */ -#define PPS_SHIFTMAX 8 /* max interval duration (s) (shift) */ -#define PPS_VALID 120 /* pps signal watchdog max (s) */ -#define MAXGLITCH 30 /* pps signal glitch max (s) */ -#endif /* PPS_SYNC */ +#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() system calls. + * the ntp_gettime() and ntp_adjtime() syscalls. * * Control mode codes (timex.modes) */ @@ -206,9 +132,13 @@ #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_CLKB 0x4000 /* set clock B */ -#define MOD_CLKA 0x8000 /* set clock A */ +#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) @@ -216,22 +146,22 @@ #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 /* select frequency-lock mode (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) /* read-only bits */ + STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK) /* * Clock states (time_state) @@ -240,72 +170,73 @@ #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 occurred */ -#define TIME_ERROR 5 /* clock not synchronized */ +#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: maximum error = NTP synch distance = dispersion + delay / 2; - * estimated error = NTP dispersion. + * Note: The time member is in microseconds if STA_NANO is zero and + * nanoseconds if not. */ struct ntptimeval { - struct timeval time; /* current time (ro) */ + 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 + * 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 (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; /* pll time constant (rw) */ - long precision; /* clock precision (us) (ro) */ - long tolerance; /* clock frequency tolerance (scaled - * ppm) (ro) */ + 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. + * kernel. They are included in all configurations to insure + * portability. */ - long ppsfreq; /* pps frequency (scaled ppm) (ro) */ - long jitter; /* pps jitter (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) */ - + 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__) -#ifndef _KERNEL +#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_gettime (struct ntptimeval *); -int ntp_adjtime (struct timex *); +int ntp_adjtime(struct timex *); +int ntp_gettime(struct ntptimeval *); __END_DECLS - -#endif /* not _KERNEL */ +#endif /* _KERNEL */ #endif /* __FreeBSD__ || __NetBSD__ */ -#ifdef __NetBSD__ -#ifdef _KERNEL -__BEGIN_DECLS -int ntp_settime1(struct timex *, register_t *); -int ntp_adjtime1(struct timex *, void *, register_t *); -__END_DECLS -#endif /* _KERNEL */ -#endif /* __NetBSD__ */ #endif /* _SYS_TIMEX_H_ */ Index: ufs/ext2fs/ext2fs_alloc.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_alloc.c,v retrieving revision 1.26 diff -d -p -u -r1.26 ext2fs_alloc.c --- ufs/ext2fs/ext2fs_alloc.c 30 Aug 2005 22:01:12 -0000 1.26 +++ ufs/ext2fs/ext2fs_alloc.c 26 Oct 2005 14:25:57 -0000 @@ -212,8 +212,8 @@ ext2fs_valloc(void *v) /* * 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: ufs/ext2fs/ext2fs_inode.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_inode.c,v retrieving revision 1.49 diff -d -p -u -r1.49 ext2fs_inode.c --- ufs/ext2fs/ext2fs_inode.c 26 Sep 2005 13:52:20 -0000 1.49 +++ ufs/ext2fs/ext2fs_inode.c 26 Oct 2005 14:25:58 -0000 @@ -146,7 +146,7 @@ ext2fs_inactive(void *v) struct inode *ip = VTOI(vp); struct mount *mp; struct proc *p = ap->a_p; - struct timespec ts; + struct bintime now; int error = 0; if (prtactive && vp->v_usecount != 0) @@ -161,8 +161,8 @@ ext2fs_inactive(void *v) if (ext2fs_size(ip) != 0) { error = VOP_TRUNCATE(vp, (off_t)0, 0, NOCRED, NULL); } - nanotime(&ts); - ip->i_e2fs_dtime = ts.tv_sec; + getbintime(&now); + ip->i_e2fs_dtime = now.sec; ip->i_flag |= IN_CHANGE | IN_UPDATE; VOP_VFREE(vp, ip->i_number, ip->i_e2fs_mode); vn_finished_write(mp, V_LOWER); Index: ufs/ext2fs/ext2fs_subr.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_subr.c,v retrieving revision 1.17 diff -d -p -u -r1.17 ext2fs_subr.c --- ufs/ext2fs/ext2fs_subr.c 27 Sep 2005 06:48:55 -0000 1.17 +++ ufs/ext2fs/ext2fs_subr.c 26 Oct 2005 14:25:58 -0000 @@ -115,26 +115,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: ufs/ext2fs/ext2fs_vfsops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v retrieving revision 1.92 diff -d -p -u -r1.92 ext2fs_vfsops.c --- ufs/ext2fs/ext2fs_vfsops.c 27 Sep 2005 06:48:55 -0000 1.92 +++ ufs/ext2fs/ext2fs_vfsops.c 26 Oct 2005 14:25:58 -0000 @@ -430,7 +430,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); @@ -893,7 +893,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; } @@ -1015,8 +1015,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: ufs/ext2fs/ext2fs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vnops.c,v retrieving revision 1.62 diff -d -p -u -r1.62 ext2fs_vnops.c --- ufs/ext2fs/ext2fs_vnops.c 12 Sep 2005 16:24:41 -0000 1.62 +++ ufs/ext2fs/ext2fs_vnops.c 26 Oct 2005 14:25:59 -0000 @@ -1308,6 +1308,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; @@ -1353,8 +1354,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: ufs/ffs/ffs_alloc.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_alloc.c,v retrieving revision 1.87 diff -d -p -u -r1.87 ffs_alloc.c --- ufs/ffs/ffs_alloc.c 26 Sep 2005 13:52:20 -0000 1.87 +++ ufs/ffs/ffs_alloc.c 26 Oct 2005 14:25:59 -0000 @@ -724,7 +724,7 @@ ffs_valloc(void *v) 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; } @@ -1042,10 +1042,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++) @@ -1113,10 +1113,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); @@ -1405,10 +1405,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; @@ -1544,10 +1544,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) { @@ -1746,10 +1746,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: ufs/ffs/ffs_inode.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_inode.c,v retrieving revision 1.76 diff -d -p -u -r1.76 ffs_inode.c --- ufs/ffs/ffs_inode.c 27 Sep 2005 06:48:55 -0000 1.76 +++ ufs/ffs/ffs_inode.c 26 Oct 2005 14:25:59 -0000 @@ -659,16 +659,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); } @@ -676,7 +678,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: ufs/ffs/ffs_snapshot.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_snapshot.c,v retrieving revision 1.21 diff -d -p -u -r1.21 ffs_snapshot.c --- ufs/ffs/ffs_snapshot.c 26 Sep 2005 14:10:32 -0000 1.21 +++ ufs/ffs/ffs_snapshot.c 26 Oct 2005 14:26:00 -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: ufs/ffs/ffs_vfsops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.175 diff -d -p -u -r1.175 ffs_vfsops.c --- ufs/ffs/ffs_vfsops.c 27 Sep 2005 06:48:55 -0000 1.175 +++ ufs/ffs/ffs_vfsops.c 26 Oct 2005 14:26:01 -0000 @@ -437,7 +437,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); @@ -1369,7 +1369,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: ufs/lfs/lfs_itimes.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/lfs_itimes.c,v retrieving revision 1.2 diff -d -p -u -r1.2 lfs_itimes.c --- ufs/lfs/lfs_itimes.c 13 Sep 2005 04:40:42 -0000 1.2 +++ ufs/lfs/lfs_itimes.c 26 Oct 2005 14:26:01 -0000 @@ -73,7 +73,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; @@ -97,7 +97,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; @@ -106,7 +107,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: 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 --- ufs/lfs/lfs_segment.c 26 Sep 2005 13:52:20 -0000 1.167 +++ ufs/lfs/lfs_segment.c 26 Oct 2005 14:26:02 -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; @@ -616,7 +616,7 @@ lfs_segwrite(struct mount *mp, int flags } if (dirty) - error = LFS_BWRITE_LOG(bp); /* Ifile */ + (void) LFS_BWRITE_LOG(bp); /* Ifile */ else brelse(bp); segleft -= fs->lfs_sepb; @@ -831,7 +831,7 @@ lfs_writeinode(struct lfs *fs, struct se daddr_t daddr; int32_t *daddrp; /* XXX ondisk32 */ ino_t ino; - int error, i, ndx, fsb = 0; + int i, ndx, fsb = 0; int redo_ifile = 0; int gotblk = 0; @@ -995,7 +995,7 @@ lfs_writeinode(struct lfs *fs, struct se LFS_IENTRY(ifp, fs, ino, ibp); daddr = ifp->if_daddr; ifp->if_daddr = dbtofsb(fs, bp->b_blkno) + fsb; - error = LFS_BWRITE_LOG(ibp); /* Ifile */ + (void) LFS_BWRITE_LOG(ibp); /* Ifile */ } /* @@ -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: 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 --- ufs/lfs/lfs_syscalls.c 25 May 2005 01:50:01 -0000 1.107 +++ ufs/lfs/lfs_syscalls.c 26 Oct 2005 14:26:02 -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: ufs/lfs/lfs_vfsops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/lfs/lfs_vfsops.c,v retrieving revision 1.188 diff -d -p -u -r1.188 lfs_vfsops.c --- ufs/lfs/lfs_vfsops.c 27 Sep 2005 06:48:56 -0000 1.188 +++ ufs/lfs/lfs_vfsops.c 26 Oct 2005 14:26:04 -0000 @@ -655,7 +655,7 @@ update_inoblk(struct lfs *fs, daddr_t of LFS_IENTRY(ifp, fs, dip->di_inumber, ibp); daddr = ifp->if_daddr; ifp->if_daddr = dbtofsb(fs, dbp->b_blkno); - error = LFS_BWRITE_LOG(ibp); /* Ifile */ + (void) LFS_BWRITE_LOG(ibp); /* Ifile */ /* And do segment accounting */ if (dtosn(fs, daddr) != dtosn(fs, dbtofsb(fs, dbp->b_blkno))) { if (daddr > 0) { Index: ufs/ufs/ufs_lookup.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_lookup.c,v retrieving revision 1.68 diff -d -p -u -r1.68 ufs_lookup.c --- ufs/ufs/ufs_lookup.c 26 Sep 2005 13:52:20 -0000 1.68 +++ ufs/ufs/ufs_lookup.c 26 Oct 2005 14:26:04 -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 VOP_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 = VOP_UPDATE(dvp, &ts, &ts, UPDATE_DIROP); if (error == 0) return (ret); Index: 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 --- ufs/ufs/ufs_quota.c 10 Jul 2005 00:18:52 -0000 1.35 +++ ufs/ufs/ufs_quota.c 26 Oct 2005 14:26:04 -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: ufs/ufs/ufs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vnops.c,v retrieving revision 1.135 diff -d -p -u -r1.135 ufs_vnops.c --- ufs/ufs/ufs_vnops.c 27 Sep 2005 06:48:56 -0000 1.135 +++ ufs/ufs/ufs_vnops.c 26 Oct 2005 14:26:05 -0000 @@ -1978,6 +1978,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; @@ -2032,8 +2033,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: uvm/uvm_extern.h =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_extern.h,v retrieving revision 1.106 diff -d -p -u -r1.106 uvm_extern.h --- uvm/uvm_extern.h 1 Sep 2005 02:21:12 -0000 1.106 +++ uvm/uvm_extern.h 26 Oct 2005 14:26:05 -0000 @@ -321,8 +321,17 @@ struct uvmexp { /* pageouts are in pdpageouts below */ int swapins; /* swapins */ int swapouts; /* swapouts */ - int pgswapin; /* pages swapped in */ + int pgswapin; /* pages swapped in */ /* XXXXXX not used! */ int pgswapout; /* pages swapped out */ + int e_faults; /* faults on executable pages */ + int e_pageins; /* executable pages swapped in */ + int e_pageouts; /* executable pages swapped out */ + int a_faults; /* faults on anonymous pages */ + int a_pageins; /* anonymous pages swapped in */ + int a_pageouts; /* anonymous pages swapped out */ + int f_faults; /* faults on filesystem pages */ + int f_pageins; /* filesystem pages swapped in */ + int f_pageouts; /* filesystem pages swapped out */ int forks; /* forks */ int forks_ppwait; /* forks where parent waits */ int forks_sharevm; /* forks where vmspace is shared */ @@ -456,6 +465,15 @@ struct uvmexp_sysctl { int64_t colorhit; int64_t colormiss; int64_t ncolors; + int64_t e_faults; + int64_t e_pageins; + int64_t e_pageouts; + int64_t a_faults; + int64_t a_pageins; + int64_t a_pageouts; + int64_t f_faults; + int64_t f_pageins; + int64_t f_pageouts; }; #ifdef _KERNEL Index: uvm/uvm_fault.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_fault.c,v retrieving revision 1.101 diff -d -p -u -r1.101 uvm_fault.c --- uvm/uvm_fault.c 13 Sep 2005 22:00:05 -0000 1.101 +++ uvm/uvm_fault.c 26 Oct 2005 14:26:06 -0000 @@ -695,6 +695,14 @@ ReFault: return (EFAULT); } + if (amap) + uvmexp.a_faults++; + else if (UVM_OBJ_IS_VTEXT(uobj)) + uvmexp.e_faults++; + else if (UVM_OBJ_IS_VNODE(uobj)) + uvmexp.f_faults++; + /* else ????? */ + /* * establish range of interest based on advice from mapper * and then clip to fit map entry. note that we only want Index: uvm/uvm_meter.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_meter.c,v retrieving revision 1.35 diff -d -p -u -r1.35 uvm_meter.c --- uvm/uvm_meter.c 27 Jun 2005 02:19:48 -0000 1.35 +++ uvm/uvm_meter.c 26 Oct 2005 14:26:06 -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); @@ -465,7 +465,7 @@ uvm_total(struct vmtotal *totalp) */ #if 0 /* - * XXXCDC: BOGUS! rethink this. in the mean time + * XXXCDC: BOGUS! rethink this. in the mean time * don't do it. */ paging = 0; Index: uvm/uvm_pdaemon.c =================================================================== RCS file: /cvsroot/src/sys/uvm/uvm_pdaemon.c,v retrieving revision 1.68 diff -d -p -u -r1.68 uvm_pdaemon.c --- uvm/uvm_pdaemon.c 13 Sep 2005 22:00:05 -0000 1.68 +++ uvm/uvm_pdaemon.c 26 Oct 2005 14:26:07 -0000 @@ -700,6 +700,14 @@ uvmpd_scan_inactive(struct pglist *pglst uvmexp.pgswapout++; + if (anon) + uvmexp.a_pageouts++; + else if (uobj && UVM_OBJ_IS_VTEXT(uobj)) + uvmexp.e_pageouts++; + else if (uobj && UVM_OBJ_IS_VNODE(uobj)) + uvmexp.f_pageouts++; + /* else ????? */ + /* * add the new page to the cluster. */