Index: kern/sched_ule.c =================================================================== RCS file: /home/ncvs/src/sys/kern/sched_ule.c,v retrieving revision 1.223 diff -u -r1.223 sched_ule.c --- kern/sched_ule.c 23 Jan 2008 03:10:18 -0000 1.223 +++ kern/sched_ule.c 23 Jan 2008 23:04:51 -0000 @@ -240,6 +240,7 @@ static int pick_pri = 1; static int affinity; static int tryself = 1; +static int oldtryself = 0; static int steal_htt = 1; static int steal_idle = 1; static int steal_thresh = 2; @@ -677,6 +678,7 @@ * IPI the target cpu to force it to reschedule with the new * workload. */ + pcpu_find(TDQ_ID(low))->pc_curthread->td_owepreempt = 1; ipi_selected(1 << TDQ_ID(low), IPI_PREEMPT); } tdq_unlock_pair(high, low); @@ -845,7 +847,7 @@ if (pri > preempt_thresh) return; sendipi: - ctd->td_flags |= TDF_NEEDRESCHED; + ctd->td_owepreempt = 1; ipi_selected(1 << cpu, IPI_PREEMPT); } @@ -1118,6 +1120,11 @@ curthread->td_priority); return (self); } + if (oldtryself && pri < curthread->td_priority) { + CTR1(KTR_ULE, "tryself %d", + curthread->td_priority); + return (self); + } /* * Now search for the cpu running the lowest priority thread with * the least load. @@ -2676,6 +2683,7 @@ SYSCTL_INT(_kern_sched, OID_AUTO, affinity, CTLFLAG_RW, &affinity, 0, "Number of hz ticks to keep thread affinity for"); SYSCTL_INT(_kern_sched, OID_AUTO, tryself, CTLFLAG_RW, &tryself, 0, ""); +SYSCTL_INT(_kern_sched, OID_AUTO, oldtryself, CTLFLAG_RW, &oldtryself, 0, ""); SYSCTL_INT(_kern_sched, OID_AUTO, balance, CTLFLAG_RW, &rebalance, 0, "Enables the long-term load balancer"); SYSCTL_INT(_kern_sched, OID_AUTO, balance_interval, CTLFLAG_RW, Index: amd64/amd64/mp_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/amd64/amd64/mp_machdep.c,v retrieving revision 1.287 diff -u -r1.287 mp_machdep.c --- amd64/amd64/mp_machdep.c 2 Aug 2007 21:17:58 -0000 1.287 +++ amd64/amd64/mp_machdep.c 23 Jan 2008 23:04:51 -0000 @@ -964,9 +964,8 @@ if (ipi_bitmap & (1 << IPI_PREEMPT)) { struct thread *running_thread = curthread; thread_lock(running_thread); - if (running_thread->td_critnest > 1) - running_thread->td_owepreempt = 1; - else + if (running_thread->td_critnest == 1 && + running_thread->td_owepreempt) mi_switch(SW_INVOL | SW_PREEMPT, NULL); thread_unlock(running_thread); }