Index: kern/kern_kse.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_kse.c,v retrieving revision 1.223 diff -u -r1.223 kern_kse.c --- kern/kern_kse.c 22 Feb 2006 18:57:49 -0000 1.223 +++ kern/kern_kse.c 19 May 2006 14:19:17 -0000 @@ -1088,7 +1088,7 @@ /* Let the new thread become owner of the upcall */ ku->ku_owner = td2; td2->td_upcall = ku; - td2->td_flags = 0; + td2->td_flags = TDF_NEEDSUSPCHK; td2->td_pflags = TDP_SA|TDP_UPCALLING; td2->td_state = TDS_CAN_RUN; td2->td_inhibitors = 0; Index: kern/kern_sig.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_sig.c,v retrieving revision 1.331 diff -u -r1.331 kern_sig.c --- kern/kern_sig.c 12 May 2006 05:04:44 -0000 1.331 +++ kern/kern_sig.c 19 May 2006 14:19:21 -0000 @@ -2434,6 +2434,7 @@ mtx_assert(&sched_lock, MA_OWNED); FOREACH_THREAD_IN_PROC(p, td2) { + td2->td_flags |= TDF_NEEDSUSPCHK; if ((TD_IS_SLEEPING(td2) || TD_IS_SWAPPED(td2)) && (td2->td_flags & TDF_SINTR) && !TD_IS_SUSPENDED(td2)) { Index: kern/kern_thr.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_thr.c,v retrieving revision 1.43 diff -u -r1.43 kern_thr.c --- kern/kern_thr.c 17 Apr 2006 18:20:37 -0000 1.43 +++ kern/kern_thr.c 19 May 2006 14:19:22 -0000 @@ -246,6 +246,7 @@ if (linkkg) sched_fork_ksegrp(td, newkg); sched_fork_thread(td, newtd); + newtd->td_flags |= TDF_NEEDSUSPCHK; TD_SET_CAN_RUN(newtd); /* if ((flags & THR_SUSPENDED) == 0) */ setrunqueue(newtd, SRQ_BORING); Index: kern/kern_thread.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_thread.c,v retrieving revision 1.233 diff -u -r1.233 kern_thread.c --- kern/kern_thread.c 21 Mar 2006 10:05:15 -0000 1.233 +++ kern/kern_thread.c 19 May 2006 14:19:22 -0000 @@ -770,6 +770,7 @@ if (P_SHOULDSTOP(p) != P_STOPPED_SINGLE) goto stopme; FOREACH_THREAD_IN_PROC(p, td2) { + td2->td_flags |= TDF_NEEDSUSPCHK; if (td2 == td) continue; td2->td_flags |= TDF_ASTPENDING; @@ -901,6 +902,7 @@ p = td->td_proc; mtx_assert(&Giant, MA_NOTOWNED); PROC_LOCK_ASSERT(p, MA_OWNED); + mtx_lock_spin(&sched_lock); while (P_SHOULDSTOP(p) || ((p->p_flag & P_TRACED) && (td->td_flags & TDF_DBSUSPEND))) { if (P_SHOULDSTOP(p) == P_STOPPED_SINGLE) { @@ -912,22 +914,30 @@ * XXX Should be safe to access unlocked * as it can only be set to be true by us. */ - if (p->p_singlethread == td) + if (p->p_singlethread == td) { + mtx_unlock_spin(&sched_lock); return (0); /* Exempt from stopping. */ + } } - if ((p->p_flag & P_SINGLE_EXIT) && return_instead) + if ((p->p_flag & P_SINGLE_EXIT) && return_instead) { + mtx_unlock_spin(&sched_lock); return (EINTR); + } /* Should we goto user boundary if we didn't come from there? */ if (P_SHOULDSTOP(p) == P_STOPPED_SINGLE && - (p->p_flag & P_SINGLE_BOUNDARY) && return_instead) + (p->p_flag & P_SINGLE_BOUNDARY) && return_instead) { + mtx_unlock_spin(&sched_lock); return (ERESTART); + } /* If thread will exit, flush its pending signals */ - if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td)) + if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td)) { + mtx_unlock_spin(&sched_lock); sigqueue_flush(&td->td_sigqueue); + mtx_lock_spin(&sched_lock); + } - mtx_lock_spin(&sched_lock); thread_stopped(p); /* * If the process is waiting for us to exit, @@ -959,7 +969,10 @@ } mtx_unlock_spin(&sched_lock); PROC_LOCK(p); + mtx_lock_spin(&sched_lock); } + td->td_flags &= ~TDF_NEEDSUSPCHK; + mtx_unlock_spin(&sched_lock); return (0); } Index: kern/subr_sleepqueue.c =================================================================== RCS file: /home/ncvs/src/sys/kern/subr_sleepqueue.c,v retrieving revision 1.29 diff -u -r1.29 subr_sleepqueue.c --- kern/subr_sleepqueue.c 21 Apr 2006 20:40:43 -0000 1.29 +++ kern/subr_sleepqueue.c 19 May 2006 14:19:23 -0000 @@ -368,6 +368,18 @@ (void *)td, (long)p->p_pid, p->p_comm); MPASS(td->td_flags & TDF_SINTR); + + mtx_lock_spin(&sched_lock); + /* + * Check if there is suspension request, signal or KSE interrupt, + * if none of these events happened, just return, in most time, + * it is true, and we save lots of cycles. + */ + if (!(td->td_flags & (TDF_NEEDSUSPCHK|TDF_NEEDSIGCHK|TDF_INTERRUPT))) + return (0); /* return with scheduler lock held. */ + + /* Slow path, check every thing. */ + mtx_unlock_spin(&sched_lock); mtx_unlock_spin(&sc->sc_lock); /* See if there are any pending signals for this thread. */ Index: kern/subr_trap.c =================================================================== RCS file: /home/ncvs/src/sys/kern/subr_trap.c,v retrieving revision 1.286 diff -u -r1.286 subr_trap.c --- kern/subr_trap.c 10 Feb 2006 14:59:16 -0000 1.286 +++ kern/subr_trap.c 19 May 2006 14:19:23 -0000 @@ -188,8 +188,7 @@ if (p->p_sflag & PS_MACPEND) p->p_sflag &= ~PS_MACPEND; #endif - td->td_flags &= ~(TDF_ASTPENDING | TDF_NEEDSIGCHK | - TDF_NEEDRESCHED | TDF_INTERRUPT); + td->td_flags &= ~(TDF_ASTPENDING | TDF_NEEDRESCHED | TDF_INTERRUPT); cnt.v_soft++; mtx_unlock_spin(&sched_lock); @@ -264,6 +263,9 @@ #endif } if (flags & TDF_NEEDSIGCHK) { + mtx_lock_spin(&sched_lock); + td->td_flags &= ~TDF_NEEDSIGCHK; + mtx_unlock_spin(&sched_lock); PROC_LOCK(p); mtx_lock(&p->p_sigacts->ps_mtx); while ((sig = cursig(td)) != 0) Index: sys/proc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/proc.h,v retrieving revision 1.458 diff -u -r1.458 proc.h --- sys/proc.h 18 May 2006 08:43:46 -0000 1.458 +++ sys/proc.h 19 May 2006 14:19:33 -0000 @@ -351,7 +351,7 @@ #define TDF_TIMOFAIL 0x00001000 /* Timeout from sleep after we were awake. */ #define TDF_INTERRUPT 0x00002000 /* Thread is marked as interrupted. */ #define TDF_UNUSED14 0x00004000 /* --available -- */ -#define TDF_UNUSED15 0x00008000 /* --available -- */ +#define TDF_NEEDSUSPCHK 0x00008000 /* Thread should check job control flags. */ #define TDF_NEEDRESCHED 0x00010000 /* Thread needs to yield. */ #define TDF_NEEDSIGCHK 0x00020000 /* Thread may need signal delivery. */ #define TDF_XSIG 0x00040000 /* Thread is exchanging signal under trace */