Index: sys/proc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/proc.h,v retrieving revision 1.504 diff -u -p -r1.504 proc.h --- sys/proc.h 2 Mar 2008 07:39:22 -0000 1.504 +++ sys/proc.h 10 Mar 2008 01:36:41 -0000 @@ -335,7 +335,7 @@ do { \ #define TDF_SINTR 0x00000008 /* Sleep is interruptible. */ #define TDF_TIMEOUT 0x00000010 /* Timing out during sleep. */ #define TDF_IDLETD 0x00000020 /* This is a per-CPU idle thread. */ -#define TDF_UNUSEDx40 0x00000040 /* --available-- */ +#define TDF_CANSWAP 0x00000040 /* Thread can be swapped. */ #define TDF_SLEEPABORT 0x00000080 /* sleepq_abort was called. */ #define TDF_KTH_SUSP 0x00000100 /* kthread is suspended */ #define TDF_UBORROWING 0x00000200 /* Thread is borrowing user pri. */ @@ -782,7 +782,8 @@ MALLOC_DECLARE(M_ZOMBIE); } while (0) /* Check whether a thread is safe to be swapped out. */ -#define thread_safetoswapout(td) (TD_IS_SLEEPING(td) || TD_IS_SUSPENDED(td)) +#define thread_safetoswapout(td) \ + ((td)->td_state == TDS_INHIBITED && ((td)->td_flags & TDF_CANSWAP)) /* Control whether or not it is safe for curthread to sleep. */ #define THREAD_NO_SLEEPING() do { \ Index: sys/sched.h =================================================================== RCS file: /home/ncvs/src/sys/sys/sched.h,v retrieving revision 1.35 diff -u -p -r1.35 sched.h --- sys/sched.h 10 Mar 2008 01:30:34 -0000 1.35 +++ sys/sched.h 10 Mar 2008 01:36:41 -0000 @@ -100,7 +100,7 @@ void sched_lend_prio(struct thread *td, void sched_lend_user_prio(struct thread *td, u_char pri); fixpt_t sched_pctcpu(struct thread *td); void sched_prio(struct thread *td, u_char prio); -void sched_sleep(struct thread *td); +void sched_sleep(struct thread *td, u_char prio); void sched_switch(struct thread *td, struct thread *newtd, int flags); void sched_throw(struct thread *td); void sched_unlend_prio(struct thread *td, u_char prio); Index: sys/sleepqueue.h =================================================================== RCS file: /home/ncvs/src/sys/sys/sleepqueue.h,v retrieving revision 1.12 diff -u -p -r1.12 sleepqueue.h --- sys/sleepqueue.h 31 Mar 2007 23:23:42 -0000 1.12 +++ sys/sleepqueue.h 10 Mar 2008 01:36:41 -0000 @@ -92,7 +92,7 @@ struct thread; void init_sleepqueues(void); void sleepq_abort(struct thread *td, int intrval); void sleepq_add(void *wchan, struct lock_object *lock, const char *wmesg, - int flags, int queue); + int flags, int queue, u_char prio); struct sleepqueue *sleepq_alloc(void); void sleepq_broadcast(void *wchan, int flags, int pri, int queue); void sleepq_free(struct sleepqueue *sq); Index: kern/kern_condvar.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_condvar.c,v retrieving revision 1.62 diff -u -p -r1.62 kern_condvar.c --- kern/kern_condvar.c 4 Jun 2007 23:50:56 -0000 1.62 +++ kern/kern_condvar.c 10 Mar 2008 01:36:41 -0000 @@ -125,7 +125,7 @@ _cv_wait(struct cv *cvp, struct lock_obj cvp->cv_waiters++; DROP_GIANT(); - sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0); + sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0, 0); if (class->lc_flags & LC_SLEEPABLE) sleepq_release(cvp); lock_state = class->lc_unlock(lock); @@ -178,7 +178,7 @@ _cv_wait_unlock(struct cv *cvp, struct l cvp->cv_waiters++; DROP_GIANT(); - sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0); + sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0, 0); if (class->lc_flags & LC_SLEEPABLE) sleepq_release(cvp); class->lc_unlock(lock); @@ -236,7 +236,7 @@ _cv_wait_sig(struct cv *cvp, struct lock DROP_GIANT(); sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR | - SLEEPQ_INTERRUPTIBLE, 0); + SLEEPQ_INTERRUPTIBLE, 0, 0); if (class->lc_flags & LC_SLEEPABLE) sleepq_release(cvp); lock_state = class->lc_unlock(lock); @@ -295,7 +295,7 @@ _cv_timedwait(struct cv *cvp, struct loc cvp->cv_waiters++; DROP_GIANT(); - sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0); + sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0, 0); sleepq_set_timeout(cvp, timo); if (class->lc_flags & LC_SLEEPABLE) sleepq_release(cvp); @@ -359,7 +359,7 @@ _cv_timedwait_sig(struct cv *cvp, struct DROP_GIANT(); sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR | - SLEEPQ_INTERRUPTIBLE, 0); + SLEEPQ_INTERRUPTIBLE, 0, 0); sleepq_set_timeout(cvp, timo); if (class->lc_flags & LC_SLEEPABLE) sleepq_release(cvp); Index: kern/kern_sx.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_sx.c,v retrieving revision 1.58 diff -u -p -r1.58 kern_sx.c --- kern/kern_sx.c 15 Dec 2007 23:13:31 -0000 1.58 +++ kern/kern_sx.c 10 Mar 2008 01:36:41 -0000 @@ -554,7 +554,7 @@ _sx_xlock_hard(struct sx *sx, uintptr_t GIANT_SAVE(); sleepq_add(&sx->lock_object, NULL, sx->lock_object.lo_name, SLEEPQ_SX | ((opts & SX_INTERRUPTIBLE) ? - SLEEPQ_INTERRUPTIBLE : 0), SQ_EXCLUSIVE_QUEUE); + SLEEPQ_INTERRUPTIBLE : 0), SQ_EXCLUSIVE_QUEUE, 0); if (!(opts & SX_INTERRUPTIBLE)) sleepq_wait(&sx->lock_object); else @@ -759,7 +759,7 @@ _sx_slock_hard(struct sx *sx, int opts, GIANT_SAVE(); sleepq_add(&sx->lock_object, NULL, sx->lock_object.lo_name, SLEEPQ_SX | ((opts & SX_INTERRUPTIBLE) ? - SLEEPQ_INTERRUPTIBLE : 0), SQ_SHARED_QUEUE); + SLEEPQ_INTERRUPTIBLE : 0), SQ_SHARED_QUEUE, 0); if (!(opts & SX_INTERRUPTIBLE)) sleepq_wait(&sx->lock_object); else Index: kern/kern_synch.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_synch.c,v retrieving revision 1.305 diff -u -p -r1.305 kern_synch.c --- kern/kern_synch.c 10 Jan 2008 22:11:20 -0000 1.305 +++ kern/kern_synch.c 10 Mar 2008 01:36:41 -0000 @@ -160,6 +160,7 @@ _sleep(ident, lock, priority, wmesg, tim return (0); } catch = priority & PCATCH; + pri = priority & PRIMASK; rval = 0; /* @@ -198,7 +199,7 @@ _sleep(ident, lock, priority, wmesg, tim * stopped, then td will no longer be on a sleep queue upon * return from cursig(). */ - sleepq_add(ident, ident == &lbolt ? NULL : lock, wmesg, flags, 0); + sleepq_add(ident, ident == &lbolt ? NULL : lock, wmesg, flags, 0, pri); if (timo) sleepq_set_timeout(ident, timo); if (lock != NULL && class->lc_flags & LC_SLEEPABLE) { @@ -207,17 +208,6 @@ _sleep(ident, lock, priority, wmesg, tim lock_state = class->lc_unlock(lock); sleepq_lock(ident); } - - /* - * Adjust this thread's priority, if necessary. - */ - pri = priority & PRIMASK; - if (pri != 0 && pri != td->td_priority) { - thread_lock(td); - sched_prio(td, pri); - thread_unlock(td); - } - if (timo && catch) rval = sleepq_timedwait_sig(ident); else if (timo) @@ -282,7 +272,7 @@ msleep_spin(ident, mtx, wmesg, timo) /* * We put ourselves on the sleep queue and start our timeout. */ - sleepq_add(ident, &mtx->lock_object, wmesg, SLEEPQ_SLEEP, 0); + sleepq_add(ident, &mtx->lock_object, wmesg, SLEEPQ_SLEEP, 0, 0); if (timo) sleepq_set_timeout(ident, timo); Index: kern/kern_thread.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_thread.c,v retrieving revision 1.266 diff -u -p -r1.266 kern_thread.c --- kern/kern_thread.c 2 Mar 2008 07:39:22 -0000 1.266 +++ kern/kern_thread.c 10 Mar 2008 01:36:42 -0000 @@ -876,8 +876,8 @@ thread_suspend_switch(struct thread *td) p->p_suspcount++; PROC_UNLOCK(p); thread_lock(td); - sched_sleep(td); TD_SET_SUSPENDED(td); + sched_sleep(td, 0); PROC_SUNLOCK(p); DROP_GIANT(); mi_switch(SW_VOL, NULL); @@ -896,8 +896,8 @@ thread_suspend_one(struct thread *td) THREAD_LOCK_ASSERT(td, MA_OWNED); KASSERT(!TD_IS_SUSPENDED(td), ("already suspended")); p->p_suspcount++; - sched_sleep(td); TD_SET_SUSPENDED(td); + sched_sleep(td, 0); } void Index: kern/kern_timeout.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_timeout.c,v retrieving revision 1.109 diff -u -p -r1.109 kern_timeout.c --- kern/kern_timeout.c 6 Feb 2008 00:04:09 -0000 1.109 +++ kern/kern_timeout.c 10 Mar 2008 01:36:42 -0000 @@ -562,7 +562,7 @@ again: mtx_unlock_spin(&callout_lock); sleepq_add(&callout_wait, &callout_lock.lock_object, "codrain", - SLEEPQ_SLEEP, 0); + SLEEPQ_SLEEP, 0, 0); sleepq_wait(&callout_wait); sq_locked = 0; Index: kern/sched_4bsd.c =================================================================== RCS file: /home/ncvs/src/sys/kern/sched_4bsd.c,v retrieving revision 1.115 diff -u -p -r1.115 sched_4bsd.c --- kern/sched_4bsd.c 10 Mar 2008 01:30:35 -0000 1.115 +++ kern/sched_4bsd.c 10 Mar 2008 01:36:42 -0000 @@ -799,12 +799,16 @@ sched_unlend_user_prio(struct thread *td } void -sched_sleep(struct thread *td) +sched_sleep(struct thread *td, u_char pri) { THREAD_LOCK_ASSERT(td, MA_OWNED); td->td_slptick = ticks; td->td_sched->ts_slptime = 0; + if (pri) + sched_prio(td, pri); + if (TD_IS_SUSPENDED(td) || pri <= PSOCK) + td->td_flags |= TDF_CANSWAP; } void @@ -922,6 +926,7 @@ sched_wakeup(struct thread *td) THREAD_LOCK_ASSERT(td, MA_OWNED); ts = td->td_sched; + td->td_flags &= ~TDF_CANSWAP; if (ts->ts_slptime > 1) { updatepri(td); resetpriority(td); Index: kern/sched_ule.c =================================================================== RCS file: /home/ncvs/src/sys/kern/sched_ule.c,v retrieving revision 1.227 diff -u -p -r1.227 sched_ule.c --- kern/sched_ule.c 10 Mar 2008 01:32:01 -0000 1.227 +++ kern/sched_ule.c 10 Mar 2008 01:36:43 -0000 @@ -186,6 +186,7 @@ static int preempt_thresh = PRI_MIN_KERN #else static int preempt_thresh = 0; #endif +static int static_boost = 0; /* * tdq - per processor runqs and statistics. All fields are protected by the @@ -1855,12 +1856,16 @@ sched_nice(struct proc *p, int nice) * Record the sleep time for the interactivity scorer. */ void -sched_sleep(struct thread *td) +sched_sleep(struct thread *td, u_char prio) { THREAD_LOCK_ASSERT(td, MA_OWNED); td->td_slptick = ticks; + if (TD_IS_SUSPENDED(td) || prio <= PSOCK) + td->td_flags |= TDF_CANSWAP; + if (static_boost && prio) + sched_prio(td, prio); } /* @@ -1875,6 +1880,7 @@ sched_wakeup(struct thread *td) THREAD_LOCK_ASSERT(td, MA_OWNED); ts = td->td_sched; + td->td_flags &= ~TDF_CANSWAP; /* * If we slept for more than a tick update our interactivity and * priority. @@ -2569,6 +2575,8 @@ SYSCTL_INT(_kern_sched, OID_AUTO, intera "Interactivity score threshold"); SYSCTL_INT(_kern_sched, OID_AUTO, preempt_thresh, CTLFLAG_RW, &preempt_thresh, 0,"Min priority for preemption, lower priorities have greater precedence"); +SYSCTL_INT(_kern_sched, OID_AUTO, static_boost, CTLFLAG_RW, &static_boost, + 0,"Controls whether static kernel priorities are assigned to sleeping threads."); #ifdef SMP SYSCTL_INT(_kern_sched, OID_AUTO, affinity, CTLFLAG_RW, &affinity, 0, "Number of hz ticks to keep thread affinity for"); Index: kern/subr_sleepqueue.c =================================================================== RCS file: /home/ncvs/src/sys/kern/subr_sleepqueue.c,v retrieving revision 1.45 diff -u -p -r1.45 subr_sleepqueue.c --- kern/subr_sleepqueue.c 13 Feb 2008 23:36:56 -0000 1.45 +++ kern/subr_sleepqueue.c 10 Mar 2008 01:36:43 -0000 @@ -272,7 +272,7 @@ sleepq_release(void *wchan) */ void sleepq_add(void *wchan, struct lock_object *lock, const char *wmesg, int flags, - int queue) + int queue, u_char pri) { struct sleepqueue_chain *sc; struct sleepqueue *sq; @@ -338,6 +338,7 @@ sleepq_add(void *wchan, struct lock_obje td->td_flags |= TDF_SINTR; td->td_flags &= ~TDF_SLEEPABORT; } + sched_sleep(td, pri); thread_unlock(td); } @@ -472,7 +473,6 @@ sleepq_switch(void *wchan) thread_lock_set(td, &sc->sc_lock); MPASS(td->td_sleepqueue == NULL); - sched_sleep(td); TD_SET_SLEEPING(td); SCHED_STAT_INC(switch_sleepq); mi_switch(SW_VOL, NULL); Index: vm/vm_glue.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_glue.c,v retrieving revision 1.226 diff -u -p -r1.226 vm_glue.c --- vm/vm_glue.c 5 Nov 2007 11:36:16 -0000 1.226 +++ vm/vm_glue.c 10 Mar 2008 01:36:43 -0000 @@ -917,8 +917,7 @@ retry: * This could be refined to support * swapping out a thread. */ - if ((td->td_priority) < PSOCK || - !thread_safetoswapout(td)) { + if (!thread_safetoswapout(td)) { thread_unlock(td); goto nextproc; } Index: vm/vm_meter.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_meter.c,v retrieving revision 1.96 diff -u -p -r1.96 vm_meter.c --- vm/vm_meter.c 27 Jul 2007 20:01:21 -0000 1.96 +++ vm/vm_meter.c 10 Mar 2008 01:36:43 -0000 @@ -95,7 +95,6 @@ SYSCTL_PROC(_vm, VM_LOADAVG, loadavg, CT static int vmtotal(SYSCTL_HANDLER_ARGS) { -/* XXXKSE almost completely broken */ struct proc *p; struct vmtotal total; vm_map_entry_t entry; @@ -139,25 +138,16 @@ vmtotal(SYSCTL_HANDLER_ARGS) break; default: FOREACH_THREAD_IN_PROC(p, td) { - /* Need new statistics XXX */ thread_lock(td); switch (td->td_state) { case TDS_INHIBITED: - /* - * XXX stats no longer synchronized. - */ - if (TD_ON_LOCK(td) || - (td->td_inhibitors == - TDI_SWAPPED)) { + if (TD_IS_SWAPPED(td)) total.t_sw++; - } else if (TD_IS_SLEEPING(td) || - TD_AWAITING_INTR(td) || - TD_IS_SUSPENDED(td)) { - if (td->td_priority <= PZERO) - total.t_dw++; - else - total.t_sl++; - } + else if (TD_IS_SLEEPING(td) && + td->td_priority <= PZERO) + total.t_dw++; + else + total.t_sl++; break; case TDS_CAN_RUN: