Heya, wakeup_n() has a "inline expansion" of setrunnable(), but it differs by always calling need_resched(), this sends an ipi for *every* wakeup channel.
It might have something to do with aja's problem. Index: kern_synch.c =================================================================== RCS file: /cvs/src/sys/kern/kern_synch.c,v retrieving revision 1.102 diff -d -u -p -r1.102 kern_synch.c --- kern_synch.c 10 Apr 2012 11:33:58 -0000 1.102 +++ kern_synch.c 10 Jul 2012 14:27:17 -0000 @@ -378,7 +378,9 @@ wakeup_n(const volatile void *ident, int p->p_stat = SRUN; p->p_cpu = sched_choosecpu(p); setrunqueue(p); - need_resched(p->p_cpu); + if (p->p_priority < + p->p_cpu->ci_schedstate.spc_curpriority) + need_resched(p->p_cpu); /* END INLINE EXPANSION */ }