--- /home/rookie/perforce/smpng/attilio_smpng/kern/kern_intr.c Thu Jun 7 23:33:11 2007 +++ kern_intr.c Sat Sep 15 16:41:44 2007 @@ -669,6 +669,7 @@ struct thread *td; struct thread *ctd; struct proc *p; + u_char cpri, pri; /* * If no ithread or no handlers, then we have a stray interrupt. @@ -703,18 +704,28 @@ * put it on the runqueue. */ it->it_need = 1; + thread_lock(ctd); + cpri = ctd->td_priority; + thread_unlock(ctd); thread_lock(td); if (TD_AWAITING_INTR(td)) { CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid, p->p_comm); TD_CLR_IWAIT(td); - sched_add(td, SRQ_INTR); + if (cpri >= td->td_priority) + sched_add(td, SRQ_INTR); } else { CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d", __func__, p->p_pid, p->p_comm, it->it_need, td->td_state); } - thread_unlock(td); - + if (cpri < td->td_priority) { + td->td_vmfriend = ctd; + thread_unlock(td); + thread_lock(ctd); + cpu_switch(ctd, td, ctd->td_lock); + thread_unlock(ctd); + } else + thread_unlock(td); return (0); } #else --- /home/rookie/perforce/smpng/attilio_smpng/kern/kern_synch.c Thu Jun 7 23:33:13 2007 +++ kern_synch.c Sat Sep 15 20:25:34 2007 @@ -439,7 +439,18 @@ if ((flags & SW_VOL) && (td->td_proc->p_flag & P_SA)) newtd = thread_switchout(td, flags, newtd); #endif - sched_switch(td, newtd, flags); + if (td->td_vmfriend != NULL) { + KASSERT(td->td_pflags & TDP_ITHREAD, + ("%s: td_vmfriend set for %p (%s) non interrupt thread\n", + __func__, td, td->td_proc->p_comm)); + KASSERT(newtd == NULL, ("%s: newtd expected to be NULL here\n", + __func__)); + + newtd = td->td_vmfriend; + td->td_vmfriend = NULL; + cpu_switch(td, newtd, td->td_lock); + } else + sched_switch(td, newtd, flags); CTR3(KTR_SCHED, "mi_switch: running %p(%s) prio %d", td, td->td_proc->p_comm, td->td_priority); --- /home/rookie/perforce/smpng/attilio_smpng/sys/proc.h Wed Aug 1 17:43:29 2007 +++ proc.h Sat Sep 15 02:34:35 2007 @@ -261,6 +261,7 @@ u_long td_profil_addr; /* (k) Temporary addr until AST. */ u_int td_profil_ticks; /* (k) Temporary ticks until AST. */ char td_name[MAXCOMLEN + 1]; /* (*) Thread name. */ + struct thread *td_vmfriend; /* (t) */ #define td_endzero td_base_pri /* Copied during fork1() or thread_sched_upcall(). */