Index: kern/kern_exec.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_exec.c,v retrieving revision 1.454 diff -p -u -r1.454 kern_exec.c --- kern/kern_exec.c 5 Jan 2018 01:51:36 -0000 1.454 +++ kern/kern_exec.c 10 Jan 2018 23:05:14 -0000 @@ -105,6 +105,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_exec.c, #include #include #include +#include #include @@ -1156,6 +1157,7 @@ execve_runproc(struct lwp *l, struct exe vm->vm_issize = 0; vm->vm_maxsaddr = (void *)epp->ep_maxsaddr; vm->vm_minsaddr = (void *)epp->ep_minsaddr; + rusage_sync_proc(p); pax_aslr_init_vm(l, vm, epp); Index: kern/kern_resource.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_resource.c,v retrieving revision 1.176 diff -p -u -r1.176 kern_resource.c --- kern/kern_resource.c 24 Mar 2017 21:43:20 -0000 1.176 +++ kern/kern_resource.c 10 Jan 2018 23:05:14 -0000 @@ -552,6 +552,26 @@ calcru(struct proc *p, struct timeval *u } } +/* + * Sync members of struct rusage with the address space. + * + * Approximate old style usage by saying text and swap are as old, + * and unshared data is everything else. Re-define "unshared data" + * to match this. It had been zero since NetBSD day 0. + */ +void +rusage_sync_proc(struct proc *p) +{ + struct rusage *ru = p->p_stats->p_ru; + + mutex_enter(p->p_lock); + ru->ru_ixrss = p->p_vmspace->vm_tsize; + ru->ru_isrss = p->p_vmspace->vm_ssize; + ru->ru_idrss = curproc->p_vmspace->vm_map.size - + (ru->ru_ixrss + ru->ru_isrss); + mutex_exit(p->p_lock); +} + int sys___getrusage50(struct lwp *l, const struct sys___getrusage50_args *uap, register_t *retval) @@ -572,7 +592,8 @@ sys___getrusage50(struct lwp *l, const s } int -getrusage1(struct proc *p, int who, struct rusage *ru) { +getrusage1(struct proc *p, int who, struct rusage *ru) +{ switch (who) { case RUSAGE_SELF: Index: kern/kern_synch.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_synch.c,v retrieving revision 1.312 diff -p -u -r1.312 kern_synch.c --- kern/kern_synch.c 6 Aug 2017 09:14:14 -0000 1.312 +++ kern/kern_synch.c 10 Jan 2018 23:05:14 -0000 @@ -453,6 +453,31 @@ updatertime(lwp_t *l, const struct binti if (__predict_false(l->l_flag & LW_IDLE)) return; +#if defined(__sparc__) && 0 + { + /* + * "now - stime" becomes negative sometimes, which it shouldn't. + * try to figure out where it comes from, because we don't ever + * add a negative value from the timecounter side. + */ + struct bintime delta = *now; + bintime_sub(&delta, &l->l_stime); + if (delta.sec < 0) { + log(LOG_DEBUG, "cpu%u: (%u.%u:%s) " + "delta.sec = %lld, delta.frac = %llu, " + "now.sec = %lld, now.frac = %llu, " + "l_stime.sec = %lld, l_stime.frac = %llu, " + "RA = %p\n", + cpu_number(), l->l_proc->p_pid, l->l_lid, + l->l_name ? l->l_name : l->l_proc->p_comm, + (long long)delta.sec, (unsigned long long)delta.frac, + (long long)now->sec, (unsigned long long)now->frac, + (long long)l->l_stime.sec, + (unsigned long long)l->l_stime.frac, + __builtin_return_address(0)); + } + } +#endif /* rtime += now - stime */ bintime_add(&l->l_rtime, now); bintime_sub(&l->l_rtime, &l->l_stime); Index: kern/kern_tc.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_tc.c,v retrieving revision 1.48 diff -p -u -r1.48 kern_tc.c --- kern/kern_tc.c 2 Nov 2017 15:28:23 -0000 1.48 +++ kern/kern_tc.c 10 Jan 2018 23:05:14 -0000 @@ -308,10 +308,18 @@ static inline u_int tc_delta(struct timehands *th) { struct timecounter *tc; + u_int count, delta; tc = th->th_counter; - return ((tc->tc_get_timecount(tc) - - th->th_offset_count) & tc->tc_counter_mask); + count = tc->tc_get_timecount(tc); + delta = ((count - th->th_offset_count) & tc->tc_counter_mask); +#if defined(__sparc__) && !defined(_RUMPKERNEL) +if (delta & 0x80000000) + log(LOG_DEBUG, "%s: cpu%u: (%u.%u:%s) returning: %x, th_offset_count %llx, count %x mask %x\n", + __func__, cpu_number(), curlwp->l_proc->p_pid, curlwp->l_lid, curlwp->l_name ? curlwp->l_name : curlwp->l_proc->p_comm, + delta, (unsigned long long)th->th_offset_count, count, tc->tc_counter_mask); +#endif + return delta; } /* @@ -326,6 +334,7 @@ binuptime(struct bintime *bt) struct timehands *th; lwp_t *l; u_int lgen, gen; + u_int delta; TC_COUNT(nbinuptime); @@ -362,7 +371,14 @@ binuptime(struct bintime *bt) th = timehands; gen = th->th_generation; *bt = th->th_offset; - bintime_addx(bt, th->th_scale * tc_delta(th)); + delta = tc_delta(th); +#if defined(__sparc__) && !defined(_RUMPKERNEL) && 0 +if (delta & 0x80000000) + log(LOG_DEBUG, "%s: cpu%u: (%u.%u:%s) tc_delta() gave: %x (th_offset_count now %llx)\n", + __func__, cpu_number(), curlwp->l_proc->p_pid, curlwp->l_lid, curlwp->l_name ? curlwp->l_name : curlwp->l_proc->p_comm, + delta, (unsigned long long)th->th_offset_count); +#endif + bintime_addx(bt, th->th_scale * delta); } while (gen == 0 || gen != th->th_generation); __insn_barrier(); @@ -759,6 +775,12 @@ tc_windup(void) else ncount = 0; th->th_offset_count += delta; +#if defined(__sparc__) && !defined(_RUMPKERNEL) && 0 +if (delta & 0x80000000) + log(LOG_DEBUG, "%s: cpu%u: (%u.%u:%s) tc_delta() gave: %x (th_offset_count now %llx)\n", + __func__, cpu_number(), curlwp->l_proc->p_pid, curlwp->l_lid, curlwp->l_name ? curlwp->l_name : curlwp->l_proc->p_comm, + delta, (unsigned long long)th->th_offset_count); +#endif bintime_addx(&th->th_offset, th->th_scale * delta); /* Index: dev/sbus/dbri.c =================================================================== RCS file: /cvsroot/src/sys/dev/sbus/dbri.c,v retrieving revision 1.37 diff -p -u -r1.37 dbri.c --- dev/sbus/dbri.c 21 Dec 2017 21:56:29 -0000 1.37 +++ dev/sbus/dbri.c 10 Jan 2018 23:05:14 -0000 @@ -461,15 +461,14 @@ dbri_config_interrupts(device_t dev) dbri_init(sc); - mutex_spin_exit(&sc->sc_intr_lock); - - /* talking to the codec needs working interrupts */ if (mmcodec_init(sc) == -1) { + mutex_spin_exit(&sc->sc_intr_lock); printf("%s: no codec detected, aborting\n", device_xname(dev)); return 0; } + mutex_spin_exit(&sc->sc_intr_lock); /* Attach ourselves to the high level audio interface */ audio_attach_mi(&dbri_hw_if, sc, sc->sc_dev); @@ -550,7 +549,7 @@ dbri_init(struct dbri_softc *sc) bus_addr_t dmaaddr; int n; - KASSERT(mutex_owned(sc->sc_intr_lock)); + KASSERT(mutex_owned(&sc->sc_intr_lock)); dbri_reset(sc); sc->sc_mm.status = 0; @@ -624,7 +623,7 @@ dbri_command_send(struct dbri_softc *sc, bus_space_tag_t iot = sc->sc_iot; int maxloops = 1000000; - KASSERT(mutex_owned(sc->sc_intr_lock)); + KASSERT(mutex_owned(&sc->sc_intr_lock)); sc->sc_locked--; @@ -671,7 +670,7 @@ dbri_process_interrupt_buffer(struct dbr int32_t i; int orig_irqp = sc->sc_irqp; - KASSERT(mutex_owned(sc->sc_intr_lock)); + KASSERT(mutex_owned(&sc->sc_intr_lock)); while ((i = sc->sc_dma->intr[sc->sc_irqp]) != 0) { sc->sc_dma->intr[sc->sc_irqp] = 0; @@ -1003,6 +1002,8 @@ mmcodec_setcontrol(struct dbri_softc *sc int error, bail = 0; #endif + KASSERT(mutex_owned(&sc->sc_intr_lock)); + /* * Temporarily mute outputs and wait 125 us to make sure that it * happens. This avoids clicking noises. @@ -1068,7 +1069,6 @@ mmcodec_setcontrol(struct dbri_softc *sc goto fail; } #else - mutex_spin_enter(&sc->sc_intr_lock); while (((sc->sc_mm.status & 0xe4) != CS4215_ONE) && (bail < 10)) { DPRINTF("%s: cv_wait_sig %p\n", device_xname(sc->sc_dev), sc); error = cv_timedwait_sig(&sc->sc_cv, &sc->sc_intr_lock, hz); @@ -1080,7 +1080,6 @@ mmcodec_setcontrol(struct dbri_softc *sc } bail++; } - mutex_spin_exit(&sc->sc_intr_lock); if (bail >= 10) { aprint_error("%s: switching to control mode timed out (%x %x)\n", device_xname(sc->sc_dev), sc->sc_mm.status, @@ -2025,6 +2024,7 @@ dbri_commit(void *hdl) if (sc->sc_whack_codec == 0) return 0; + mutex_spin_enter(&sc->sc_intr_lock); ret = mmcodec_setcontrol(sc); if (ret) { DPRINTF("%s: control mode failed. Mutex %s PIL %x\n", __func__, @@ -2033,6 +2033,7 @@ dbri_commit(void *hdl) } else DPRINTF("%s: control mode ok\n", __func__); mmcodec_init_data(sc); + mutex_spin_exit(&sc->sc_intr_lock); return 0; } @@ -2225,8 +2226,11 @@ dbri_open(void *cookie, int flags) DPRINTF("%s: %d\n", __func__, sc->sc_refcount); - if (sc->sc_refcount == 0) + if (sc->sc_refcount == 0) { + mutex_spin_enter(&sc->sc_intr_lock); dbri_bring_up(sc); + mutex_spin_exit(&sc->sc_intr_lock); + } sc->sc_refcount++; Index: arch/sparc/conf/GENERIC =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/conf/GENERIC,v retrieving revision 1.256 diff -p -u -r1.256 GENERIC --- arch/sparc/conf/GENERIC 14 Sep 2017 07:58:43 -0000 1.256 +++ arch/sparc/conf/GENERIC 10 Jan 2018 23:05:14 -0000 @@ -125,7 +125,7 @@ options DDB_HISTORY_SIZE=100 # enable h ## Adds code to the kernel that does internal consistency checks, and will ## cause the kernel to panic if corruption of internal data structures ## is detected. -#options DIAGNOSTIC # extra kernel sanity checking +options DIAGNOSTIC # extra kernel sanity checking ## Enable (possibly expensive) debugging code that may also display messages ## on the system console Index: arch/sparc/sparc/timer.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/timer.c,v retrieving revision 1.32 diff -p -u -r1.32 timer.c --- arch/sparc/sparc/timer.c 19 Jan 2014 00:22:33 -0000 1.32 +++ arch/sparc/sparc/timer.c 10 Jan 2018 23:05:14 -0000 @@ -90,20 +90,24 @@ static struct counter { u_int offset; /* accumulated offset due to wraps */ u_int shift; /* scaling for valid bits */ u_int mask; /* valid bit mask */ -} cntr; + __cpu_simple_lock_t lock; /* protects access to offset and reg */ + struct evcnt missed; +} cntr __aligned(CACHE_LINE_SIZE) = { + .missed = EVCNT_INITIALIZER(EVCNT_TYPE_MISC, 0, "counter", "missed"), +}; /* * define timecounter */ static struct timecounter counter_timecounter = { - timer_get_timecount, /* get_timecount */ - 0, /* no poll_pps */ - ~0u, /* counter_mask */ - 0, /* frequency - set at initialisation */ - "timer-counter", /* name */ - 100, /* quality */ - &cntr /* private reference */ + .tc_get_timecount = timer_get_timecount, + .tc_poll_pps = NULL, + .tc_counter_mask = ~0u, + .tc_frequency = 0, + .tc_name = "timer-counter", + .tc_quality = 100, + .tc_priv = &cntr, }; /* @@ -112,29 +116,40 @@ static struct timecounter counter_timeco static u_int timer_get_timecount(struct timecounter *tc) { - struct counter *ctr = (struct counter *)tc->tc_priv; - - u_int c, res, r; + static u_int oldres, oldo; + u_int c, res, r, o; int s; + /* + * We use splhigh/__cpu_simple_lock here as we don't want + * any mutex or lockdebug overhead. + */ s = splhigh(); - - res = c = *ctr->cntreg; + __cpu_simple_lock(&cntr.lock); + res = c = *cntr.cntreg; res &= ~TMR_LIMIT; + o = cntr.offset; if (c != res) { - r = ctr->limit; + r = cntr.limit; + } else if (res < oldres && o == oldo) { + r = cntr.limit; + cntr.missed.ev_count++; } else { r = 0; } - - res >>= ctr->shift; - res &= ctr->mask; - res += r + ctr->offset; + oldres = res; + oldo = o; + __cpu_simple_unlock(&cntr.lock); splx(s); + + res >>= cntr.shift; + res &= cntr.mask; + + res += r + o; return res; } @@ -142,8 +157,15 @@ timer_get_timecount(struct timecounter * void tickle_tc(void) { + if (timecounter->tc_get_timecount == timer_get_timecount) { + int s; + + s = splhigh(); + __cpu_simple_lock(&cntr.lock); cntr.offset += cntr.limit; + __cpu_simple_unlock(&cntr.lock); + splx(s); } } @@ -155,6 +177,8 @@ timerattach(volatile int *cntreg, volati { u_int prec = 0, t0; + evcnt_attach_static(&cntr.missed); + /* * Calibrate delay() by tweaking the magic constant * until a delay(100) actually reads (at least) 100 us on the clock. @@ -190,13 +214,15 @@ timerattach(volatile int *cntreg, volati if ((1 << t0) & prec) break; + __cpu_simple_lock_init(&cntr.lock); + + cntr.offset = 1; cntr.shift = t0; cntr.mask = (1 << (31-t0))-1; counter_timecounter.tc_frequency = 1000000 * (TMR_SHIFT - t0 + 1); printf(": delay constant %d, frequency = %" PRIu64 " Hz\n", timerblurb, counter_timecounter.tc_frequency); -printf("timer: limit %u shift %u mask %x\n", cntr.limit, cntr.shift, cntr.mask); #if defined(SUN4) || defined(SUN4C) if (CPU_ISSUN4 || CPU_ISSUN4C) { @@ -214,6 +240,7 @@ printf("timer: limit %u shift %u mask %x cntr.limit = tmr_ustolim4m(tick); } #endif + /* link interrupt handlers */ intr_establish(10, 0, &level10, NULL, true); intr_establish(14, 0, &level14, NULL, true); @@ -225,6 +252,7 @@ printf("timer: limit %u shift %u mask %x cntr.cntreg = cntreg; cntr.limit >>= cntr.shift; +printf("timer: limit %u shift %u mask %x\n", cntr.limit, cntr.shift, cntr.mask); tc_init(&counter_timecounter); } Index: arch/sparc/sparc/timer_sun4m.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/timer_sun4m.c,v retrieving revision 1.30 diff -p -u -r1.30 timer_sun4m.c --- arch/sparc/sparc/timer_sun4m.c 19 Jan 2014 00:22:33 -0000 1.30 +++ arch/sparc/sparc/timer_sun4m.c 10 Jan 2018 23:05:14 -0000 @@ -74,7 +74,7 @@ __KERNEL_RCSID(0, "$NetBSD: timer_sun4m. #include #include -struct timer_4m *timerreg4m; +static struct timer_4m *timerreg4m; #define counterreg4m cpuinfo.counterreg_4m /* @@ -160,9 +160,13 @@ clockintr_4m(void *cap) */ if (cold) return 0; + kpreempt_disable(); - /* read the limit register to clear the interrupt */ + + /* Read the limit register to clear the interrupt. */ *((volatile int *)&timerreg4m->t_limit); + + /* Update the timecounter offset. */ tickle_tc(); /* Index: arch/sparc/sparc/timerreg.h =================================================================== RCS file: /cvsroot/src/sys/arch/sparc/sparc/timerreg.h,v retrieving revision 1.9 diff -p -u -r1.9 timerreg.h --- arch/sparc/sparc/timerreg.h 16 Nov 2005 03:00:23 -0000 1.9 +++ arch/sparc/sparc/timerreg.h 10 Jan 2018 23:05:14 -0000 @@ -120,9 +120,12 @@ struct counter_4m { /* counter that int */ #define tmr_ustolim(n) (((n) + 1) << TMR_SHIFT) -/*efine TMR_SHIFT4M 9 -* shift to obtain microseconds */ -/*efine tmr_ustolim4m(n) (((2*(n)) + 1) << TMR_SHIFT4M)*/ +#define TMR_SHIFT4M 9 /* shift to obtain microseconds */ +#if 1 +#define tmr_ustolim4m(n) (((2*(n)) + 1) << TMR_SHIFT4M) +#else #define tmr_ustolim4m(n) ((n) << TMR_SHIFT) +#endif /* The number of microseconds represented by a counter register value */ #define tmr_cnttous(c) ((((c) >> TMR_SHIFT) & TMR_MASK) - 1)