--- include/linux/sched.h | 4 +++- kernel/sched_bfs.c | 30 +++++++++++++++++++++++++++--- kernel/sysctl.c | 10 ++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) Index: linux-2.6.36-ck1/include/linux/sched.h =================================================================== --- linux-2.6.36-ck1.orig/include/linux/sched.h 2010-10-22 10:09:05.278384735 +1100 +++ linux-2.6.36-ck1/include/linux/sched.h 2010-10-22 10:10:11.092400273 +1100 @@ -1186,7 +1186,9 @@ struct task_struct { int prio, static_prio, normal_prio; unsigned int rt_priority; #ifdef CONFIG_SCHED_BFS - int time_slice; + int time_slice, slice_divisions; + unsigned long deactivation_credits; + int deactivations; u64 deadline; struct list_head run_list; u64 last_ran; Index: linux-2.6.36-ck1/kernel/sched_bfs.c =================================================================== --- linux-2.6.36-ck1.orig/kernel/sched_bfs.c 2010-10-22 10:09:05.215385682 +1100 +++ linux-2.6.36-ck1/kernel/sched_bfs.c 2010-10-22 10:14:58.056226224 +1100 @@ -138,6 +138,8 @@ int rr_interval __read_mostly = 6; */ int sched_iso_cpu __read_mostly = 70; +int sleep_latency = 1; + /* * The relative length of deadline for each priority(nice) level. */ @@ -993,7 +995,7 @@ static void activate_task(struct task_st } /* - * deactivate_task - If it's running, it's not on the grq and we can just + * vate_task - If it's running, it's not on the grq and we can just * decrement the nr_running. Enter with grq locked. */ static inline void deactivate_task(struct task_struct *p) @@ -1597,6 +1599,7 @@ void sched_fork(struct task_struct *p, i * is always equal to current->deadline. */ rq = task_grq_lock_irq(curr); + p->deactivations = p->deactivation_credits = 0; if (likely(rq->rq_time_slice >= RESCHED_US * 2)) { rq->rq_time_slice /= 2; p->time_slice = rq->rq_time_slice; @@ -2545,8 +2548,28 @@ static inline int ms_longest_deadline_di */ static void time_slice_expired(struct task_struct *p) { - p->time_slice = timeslice(); - p->deadline = grq.niffies + task_deadline_diff(p); + u64 tdd = task_deadline_diff(p); + unsigned long ts = timeslice(); + + if (!p->deactivations) { + if (p->deactivation_credits) + p->deactivation_credits--; + else if (p->slice_divisions > 0) + p->slice_divisions--; + } else { + if (p->deactivations > 1 && + (ts >> p->slice_divisions) > RESCHED_US * 2) + p->slice_divisions++; + if (p->slice_divisions) + p->deactivation_credits++; + p->deactivations = 0; + } + if (sleep_latency) { + ts >>= p->slice_divisions; + tdd >>= p->slice_divisions; + } + p->time_slice = ts; + p->deadline = grq.niffies + tdd; } /* @@ -2753,6 +2776,7 @@ need_resched_nonpreemptible: try_to_wake_up_local(to_wakeup); } deactivate = 1; + prev->deactivations++; } switch_count = &prev->nvcsw; } Index: linux-2.6.36-ck1/kernel/sysctl.c =================================================================== --- linux-2.6.36-ck1.orig/kernel/sysctl.c 2010-10-22 10:09:05.202385879 +1100 +++ linux-2.6.36-ck1/kernel/sysctl.c 2010-10-22 10:10:11.879388574 +1100 @@ -121,6 +121,7 @@ static int __maybe_unused one_hundred = #ifdef CONFIG_SCHED_BFS extern int rr_interval; extern int sched_iso_cpu; +extern int sleep_latency; static int __read_mostly one_thousand = 1000; #endif #ifdef CONFIG_PRINTK @@ -834,6 +835,15 @@ static struct ctl_table kern_table[] = { .extra1 = &zero, .extra2 = &one_hundred, }, + { + .procname = "sleep_latency", + .data = &sleep_latency, + .maxlen = sizeof (int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .extra1 = &zero, + .extra2 = &one, + }, #endif #if defined(CONFIG_S390) && defined(CONFIG_SMP) {