Make sure we disable preemption in try_to_wake_up and when changing the cpu in set_cpus_allowed_ptr. Rework the change in rr_interval with number of cpus to not go up quite so quickly, scaling only by 50% every doubling of CPUs for better interactivity on multicore machines. Throughput did not appear to decrease measurably with this change. -ck --- include/linux/sched.h | 2 +- kernel/sched_bfs.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) Index: linux-2.6.31.14/include/linux/sched.h =================================================================== --- linux-2.6.31.14.orig/include/linux/sched.h 2010-08-29 16:50:46.000000000 +1000 +++ linux-2.6.31.14/include/linux/sched.h 2010-08-29 16:51:09.000000000 +1000 @@ -1384,7 +1384,7 @@ static inline void tsk_cpus_current(stru static inline void print_scheduler_version(void) { - printk(KERN_INFO"BFS CPU scheduler v0.316 by Con Kolivas.\n"); + printk(KERN_INFO"BFS CPU scheduler v0.318 by Con Kolivas.\n"); } static inline int iso_task(struct task_struct *p) Index: linux-2.6.31.14/kernel/sched_bfs.c =================================================================== --- linux-2.6.31.14.orig/kernel/sched_bfs.c 2010-08-29 16:50:46.000000000 +1000 +++ linux-2.6.31.14/kernel/sched_bfs.c 2010-08-29 16:51:09.341868703 +1000 @@ -1269,6 +1269,8 @@ static int try_to_wake_up(struct task_st int success = 0; struct rq *rq; + get_cpu(); + /* This barrier is undocumented, probably for p->state? くそ */ smp_wmb(); @@ -1301,6 +1303,8 @@ out_running: p->state = TASK_RUNNING; out_unlock: task_grq_unlock(&flags); + put_cpu(); + return success; } @@ -6101,7 +6105,7 @@ static int cache_cpu_idle(unsigned long void __init sched_init_smp(void) { struct sched_domain *sd; - int cpu; + int cpu, i, cpu_scale; cpumask_var_t non_isolated_cpus; @@ -6141,7 +6145,13 @@ void __init sched_init_smp(void) * allowing us to increase the base rr_interval, but in a non linear * fashion. */ - rr_interval *= 1 + ilog2(num_online_cpus()); + cpu_scale = ilog2(num_online_cpus()); + rr_interval *= 100; + for (i = 0; i < cpu_scale; i++) { + rr_interval *= 3; + rr_interval /= 2; + } + rr_interval /= 100; grq_lock_irq(); /*