Index: linux-2.6.31-bfs/kernel/sched_bfs.c =================================================================== --- linux-2.6.31-bfs.orig/kernel/sched_bfs.c 2009-09-10 23:19:43.345014392 +1000 +++ linux-2.6.31-bfs/kernel/sched_bfs.c 2009-09-10 23:30:12.113014668 +1000 @@ -996,11 +996,23 @@ preempt_enable(); } +#ifdef CONFIG_SMP +static int no_idle_cpus(void) +{ + return (cpus_empty(grq.cpu_idle_map)); +} +#else +static int no_idle_cpus(void) +{ + return 1; +} +#endif + /*** * try_to_wake_up - wake up a thread * @p: the to-be-woken-up thread * @state: the mask of task states that can be woken - * sync is ignored on bfs + * @sync: do a synchronous wakeup? * * Put it on the run-queue if it's not already there. The "current" * thread is always on the run-queue (except when the actual @@ -1010,7 +1022,7 @@ * * returns failure only if the task is already active. */ -static int try_to_wake_up(struct task_struct *p, unsigned int state) +static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync) { unsigned long flags; int success = 0; @@ -1026,7 +1038,14 @@ goto out_running; activate_task(p, rq); - try_preempt(p, rq); + /* + * Sync wakeups (i.e. those types of wakeups where the waker + * has indicated that it will leave the CPU in short order) + * don't trigger a preemption if there are no idle cpus, + * instead waiting for current to deschedule. + */ + if (!sync || (sync && !no_idle_cpus())) + try_preempt(p, rq); success = 1; out_running: @@ -1050,13 +1069,13 @@ */ int wake_up_process(struct task_struct *p) { - return try_to_wake_up(p, TASK_ALL); + return try_to_wake_up(p, TASK_ALL, 0); } EXPORT_SYMBOL(wake_up_process); int wake_up_state(struct task_struct *p, unsigned int state) { - return try_to_wake_up(p, state); + return try_to_wake_up(p, state, 0); } /* @@ -1124,18 +1143,6 @@ put_cpu(); } -#ifdef CONFIG_SMP -static int no_idle_cpus(void) -{ - return (cpus_empty(grq.cpu_idle_map)); -} -#else -static int no_idle_cpus(void) -{ - return 1; -} -#endif - /* * wake_up_new_task - wake up a newly created task for the first time. * @@ -2271,7 +2278,7 @@ int default_wake_function(wait_queue_t *curr, unsigned mode, int sync, void *key) { - return try_to_wake_up(curr->private, mode); + return try_to_wake_up(curr->private, mode, sync); } EXPORT_SYMBOL(default_wake_function);