--- linux-2.6.0-test2-mm5-O13.1/kernel/sched.c 2003-08-08 22:47:08.000000000 +1000 +++ linux-2.6.0-test2-mm5/kernel/sched.c 2003-08-09 01:27:47.000000000 +1000 @@ -130,6 +130,15 @@ #define JUST_INTERACTIVE_SLEEP(p) \ (MAX_SLEEP_AVG - (DELTA(p) * AVG_TIMESLICE)) +#define HIGH_CREDIT(p) \ + ((p)->interactive_credit > MAX_SLEEP_AVG) + +#define LOW_CREDIT(p) \ + ((p)->interactive_credit < -MAX_SLEEP_AVG) + +#define VARYING_CREDIT(p) \ + (!(HIGH_CREDIT(p) || LOW_CREDIT(p))) + #define TASK_PREEMPTS_CURR(p, rq) \ ((p)->prio < (rq)->curr->prio || \ ((p)->prio == (rq)->curr->prio && \ @@ -364,7 +373,7 @@ static void recalc_task_prio(task_t *p, unsigned long long __sleep_time = now - p->timestamp; unsigned long sleep_time; - if (!p->sleep_avg) + if (!p->sleep_avg && VARYING_CREDIT(p)) p->interactive_credit--; if (__sleep_time > NS_MAX_SLEEP_AVG) @@ -373,7 +382,6 @@ static void recalc_task_prio(task_t *p, sleep_time = (unsigned long)__sleep_time; if (likely(sleep_time > 0)) { - /* * User tasks that sleep a long time are categorised as * idle and will get just interactive status to stay active & @@ -387,20 +395,38 @@ static void recalc_task_prio(task_t *p, else { /* * The lower the sleep avg a task has the more - * rapidly it will rise with sleep time. Tasks - * without interactive_credit are limited to - * one timeslice worth of sleep avg bonus. + * rapidly it will rise with sleep time. */ sleep_time *= (MAX_BONUS + 1 - (NS_TO_JIFFIES(p->sleep_avg) * MAX_BONUS / MAX_SLEEP_AVG)); - if (p->interactive_credit < 0 && + /* + * Tasks with low interactive_credit are limited to + * one timeslice worth of sleep avg bonus. + */ + if (LOW_CREDIT(p) && sleep_time > JIFFIES_TO_NS(task_timeslice(p))) sleep_time = JIFFIES_TO_NS(task_timeslice(p)); /* + * Non high_credit tasks waking from uninterruptible + * sleep are limited in their sleep_avg rise + */ + if (!HIGH_CREDIT(p) && p->activated == -1){ + if (p->sleep_avg >= + JIFFIES_TO_NS(JUST_INTERACTIVE_SLEEP(p))) + sleep_time = 0; + else if (p->sleep_avg + sleep_time >= + JIFFIES_TO_NS(JUST_INTERACTIVE_SLEEP(p))){ + p->sleep_avg = + JIFFIES_TO_NS(JUST_INTERACTIVE_SLEEP(p)); + sleep_time = 0; + } + } + + /* * This code gives a bonus to interactive tasks. * * The boost works by updating the 'average sleep time' @@ -418,7 +444,7 @@ static void recalc_task_prio(task_t *p, */ if (p->sleep_avg > NS_MAX_SLEEP_AVG){ p->sleep_avg = NS_MAX_SLEEP_AVG; - p->interactive_credit++; + p->interactive_credit += VARYING_CREDIT(p); } } } @@ -588,11 +614,7 @@ repeat_lock_task: * Tasks on involuntary sleep don't earn * sleep_avg beyond just interactive state. */ - if (NS_TO_JIFFIES(p->sleep_avg) >= - JUST_INTERACTIVE_SLEEP(p)){ - p->timestamp = sched_clock(); - p->activated = -1; - } + p->activated = -1; } if (sync) __activate_task(p, rq); @@ -1156,9 +1178,9 @@ skip_queue: * 3) are cache-hot on their current CPU. */ -#define CAN_MIGRATE_TASK(p,rq,this_cpu) \ - ((!idle || (((now - (p)->timestamp)>>10) > cache_decay_ticks)) &&\ - !task_running(rq, p) && \ +#define CAN_MIGRATE_TASK(p,rq,this_cpu) \ + ((!idle || (NS_TO_JIFFIES(now - (p)->timestamp) > \ + cache_decay_ticks)) && !task_running(rq, p) && \ cpu_isset(this_cpu, (p)->cpus_allowed)) curr = curr->prev; @@ -1366,13 +1388,23 @@ void scheduler_tick(int user_ticks, int * requeue this task to the end of the list on this priority * level, which is in essence a round-robin of tasks with * equal priority. + * + * This only applies to user tasks in the interactive + * delta range with at least MIN_TIMESLICE left. */ - if (p->mm && !((task_timeslice(p) - p->time_slice) % - TIMESLICE_GRANULARITY) && (p->time_slice > MIN_TIMESLICE) && + if (p->mm && TASK_INTERACTIVE(p) && !((task_timeslice(p) - + p->time_slice) % TIMESLICE_GRANULARITY) && + (p->time_slice > MIN_TIMESLICE) && (p->array == rq->active)) { dequeue_task(p, rq->active); set_tsk_need_resched(p); + /* + * Tasks with interactive credit get all their + * time waiting on the run queue credited as sleep + */ + if (HIGH_CREDIT(p)) + p->activated = 2; enqueue_task(p, rq->active); } } @@ -1426,7 +1458,7 @@ need_resched: * as their sleep_avg decreases to slow them losing their * priority bonus */ - if (prev->interactive_credit > 0) + if (HIGH_CREDIT(prev)) run_time /= (MAX_BONUS + 1 - (NS_TO_JIFFIES(prev->sleep_avg) * MAX_BONUS / MAX_SLEEP_AVG)); @@ -1484,12 +1516,12 @@ pick_next_task: if (next->activated == 1) delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128; - next->activated = 0; array = next->array; dequeue_task(next, array); recalc_task_prio(next, next->timestamp + delta); enqueue_task(next, array); } + next->activated = 0; switch_tasks: prefetch(next); clear_tsk_need_resched(prev);