--- kernel/sched_bfs.c | 25 +++++++++++++++++++++++++ kernel/sysctl.c | 10 ++++++++++ 2 files changed, 35 insertions(+) Index: linux-2.6.35.5-ck1/kernel/sched_bfs.c =================================================================== --- linux-2.6.35.5-ck1.orig/kernel/sched_bfs.c 2010-10-04 20:32:39.968671850 +1100 +++ linux-2.6.35.5-ck1/kernel/sched_bfs.c 2010-10-04 21:02:08.689577993 +1100 @@ -137,6 +137,14 @@ int rr_interval __read_mostly = 6; int sched_iso_cpu __read_mostly = 70; /* + * latency_bias is used to determine whether we should sacrifice throughput + * as load increases to try and keep latencies bound to rr_interval. It does + * not change the fairness, so heavy CPU users will still run slow (slower + * since throughput decreases dramatically the higher this is set to). + */ +int latency_bias __read_mostly = 2; + +/* * The relative length of deadline for each priority(nice) level. */ static int prio_ratios[PRIO_RANGE] __read_mostly; @@ -2062,6 +2070,23 @@ update_cpu_clock(struct rq *rq, struct t s64 time_diff = rq->clock - rq->rq_last_ran; niffy_diff(&time_diff, 1); + /* + * If we are overloaded, then shorten the effective timeslices + * to ensure latencies are kept as small as is possible by + * making them expire at a rate proportional to load/CPUs. Use + * latency_bias to determine the upper limit for how much to + * shorten the effective timeslice. + */ + if (latency_bias) { + int nr = nr_running(), nol = num_online_cpus(); + + if (nr > nol) { + time_diff /= nol; + if (nr > latency_bias * nol) + nr = latency_bias * nol; + time_diff *= nr; + } + } rq->rq_time_slice -= NS_TO_US(time_diff); } rq->rq_last_ran = rq->timekeep_clock = rq->clock; Index: linux-2.6.35.5-ck1/kernel/sysctl.c =================================================================== --- linux-2.6.35.5-ck1.orig/kernel/sysctl.c 2010-10-04 20:32:39.977671481 +1100 +++ linux-2.6.35.5-ck1/kernel/sysctl.c 2010-10-04 20:32:48.030341034 +1100 @@ -119,6 +119,7 @@ static int __maybe_unused one_hundred = #ifdef CONFIG_SCHED_BFS extern int rr_interval; extern int sched_iso_cpu; +extern int latency_bias; static int __read_mostly one_thousand = 1000; #endif #ifdef CONFIG_PRINTK @@ -802,6 +803,15 @@ static struct ctl_table kern_table[] = { .maxlen = sizeof (int), .mode = 0644, .proc_handler = &proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one_hundred, + }, + { + .procname = "latency_bias", + .data = &latency_bias, + .maxlen = sizeof (int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, .extra1 = &zero, .extra2 = &one_hundred, },