From 9ad2265733ae27758ebf470fc60be9e94434b5ac Mon Sep 17 00:00:00 2001 From: davide Date: Mon, 4 Mar 2013 11:22:19 +0000 Subject: MFcalloutng (r244355): Make loadavg calculation callout direct. There are several reasons for it: - it is very simple and doesn't worth context switch to SWI; - since SWI is no longer used here, we can remove twelve years old hack, excluding this SWI from from the loadavg statistics; - it fixes problem when eventtimer (HPET) shares interrupt with some other device, and that interrupt thread counted as permanent loadavg of 1; now loadavg accounted before that interrupt thread is scheduled. Sponsored by: Google Summer of Code 2012, iXsystems inc. Tested by: flo, marius, ian, Fabian Keil, markj --- sys/kern/kern_synch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sys/kern/kern_synch.c') diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 73dfd70..8783142 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -560,8 +560,9 @@ loadav(void *arg) * random variation to avoid synchronisation with processes that * run at regular intervals. */ - callout_reset(&loadav_callout, hz * 4 + (int)(random() % (hz * 2 + 1)), - loadav, NULL); + callout_reset_sbt(&loadav_callout, + tick_sbt * (hz * 4 + (int)(random() % (hz * 2 + 1))), 0, + loadav, NULL, C_DIRECT_EXEC | C_HARDCLOCK); } /* ARGSUSED */ -- cgit v1.1 From 8374b0e14140d03f8a6128eb532d6ae5f672571b Mon Sep 17 00:00:00 2001 From: davide Date: Mon, 4 Mar 2013 12:48:41 +0000 Subject: MFcalloutng: Introduce sbt variants of msleep(), msleep_spin(), pause(), tsleep() in the KPI, allowing to specify timeout in 'sbintime_t' rather than ticks. Sponsored by: Google Summer of Code 2012, iXsystems inc. Tested by: flo, marius, ian, markj, Fabian Keil --- sys/kern/kern_synch.c | 55 +++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 26 deletions(-) (limited to 'sys/kern/kern_synch.c') diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 8783142..5aae8d8 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -146,12 +146,12 @@ sleepinit(void) */ int _sleep(void *ident, struct lock_object *lock, int priority, - const char *wmesg, int timo) + const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags) { struct thread *td; struct proc *p; struct lock_class *class; - int catch, flags, lock_state, pri, rval; + int catch, lock_state, pri, rval, sleepq_flags; WITNESS_SAVE_DECL(lock_witness); td = curthread; @@ -162,7 +162,7 @@ _sleep(void *ident, struct lock_object *lock, int priority, #endif WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, "Sleeping on \"%s\"", wmesg); - KASSERT(timo != 0 || mtx_owned(&Giant) || lock != NULL, + KASSERT(sbt != 0 || mtx_owned(&Giant) || lock != NULL, ("sleeping without a lock")); KASSERT(p != NULL, ("msleep1")); KASSERT(ident != NULL && TD_IS_RUNNING(td), ("msleep")); @@ -199,13 +199,13 @@ _sleep(void *ident, struct lock_object *lock, int priority, sleepq_remove(td, td->td_wchan); if (ident == &pause_wchan) - flags = SLEEPQ_PAUSE; + sleepq_flags = SLEEPQ_PAUSE; else - flags = SLEEPQ_SLEEP; + sleepq_flags = SLEEPQ_SLEEP; if (catch) - flags |= SLEEPQ_INTERRUPTIBLE; + sleepq_flags |= SLEEPQ_INTERRUPTIBLE; if (priority & PBDRY) - flags |= SLEEPQ_STOP_ON_BDRY; + sleepq_flags |= SLEEPQ_STOP_ON_BDRY; sleepq_lock(ident); CTR5(KTR_PROC, "sleep: thread %ld (pid %ld, %s) on %s (%p)", @@ -231,18 +231,18 @@ _sleep(void *ident, struct lock_object *lock, int priority, * stopped, then td will no longer be on a sleep queue upon * return from cursig(). */ - sleepq_add(ident, lock, wmesg, flags, 0); - if (timo) - sleepq_set_timeout(ident, timo); + sleepq_add(ident, lock, wmesg, sleepq_flags, 0); + if (sbt != 0) + sleepq_set_timeout_sbt(ident, sbt, pr, flags); if (lock != NULL && class->lc_flags & LC_SLEEPABLE) { sleepq_release(ident); WITNESS_SAVE(lock, lock_witness); lock_state = class->lc_unlock(lock); sleepq_lock(ident); } - if (timo && catch) + if (sbt != 0 && catch) rval = sleepq_timedwait_sig(ident, pri); - else if (timo) + else if (sbt != 0) rval = sleepq_timedwait(ident, pri); else if (catch) rval = sleepq_wait_sig(ident, pri); @@ -263,7 +263,8 @@ _sleep(void *ident, struct lock_object *lock, int priority, } int -msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo) +msleep_spin_sbt(void *ident, struct mtx *mtx, const char *wmesg, + sbintime_t sbt, sbintime_t pr, int flags) { struct thread *td; struct proc *p; @@ -301,8 +302,8 @@ msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo) * We put ourselves on the sleep queue and start our timeout. */ sleepq_add(ident, &mtx->lock_object, wmesg, SLEEPQ_SLEEP, 0); - if (timo) - sleepq_set_timeout(ident, timo); + if (sbt != 0) + sleepq_set_timeout_sbt(ident, sbt, pr, flags); /* * Can't call ktrace with any spin locks held so it can lock the @@ -324,7 +325,7 @@ msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo) wmesg); sleepq_lock(ident); #endif - if (timo) + if (sbt != 0) rval = sleepq_timedwait(ident, 0); else { sleepq_wait(ident, 0); @@ -348,28 +349,30 @@ msleep_spin(void *ident, struct mtx *mtx, const char *wmesg, int timo) * to a "timo" value of one. */ int -pause(const char *wmesg, int timo) +pause_sbt(const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags) { - KASSERT(timo >= 0, ("pause: timo must be >= 0")); + int sbt_sec; + + sbt_sec = sbintime_getsec(sbt); + KASSERT(sbt_sec >= 0, ("pause: timo must be >= 0")); /* silently convert invalid timeouts */ - if (timo < 1) - timo = 1; + if (sbt == 0) + sbt = tick_sbt; if (cold) { /* - * We delay one HZ at a time to avoid overflowing the + * We delay one second at a time to avoid overflowing the * system specific DELAY() function(s): */ - while (timo >= hz) { + while (sbt_sec > 0) { DELAY(1000000); - timo -= hz; + sbt_sec--; } - if (timo > 0) - DELAY(timo * tick); + DELAY((sbt & 0xffffffff) / SBT_1US); return (0); } - return (tsleep(&pause_wchan, 0, wmesg, timo)); + return (_sleep(&pause_wchan, NULL, 0, wmesg, sbt, pr, flags)); } /* -- cgit v1.1