--- linux-2.6.0-test2-mm4-O12.3/kernel/sched.c 2003-08-05 01:30:27.000000000 +1000 +++ linux-2.6.0-test2-mm4-O13/kernel/sched.c 2003-08-05 01:36:20.000000000 +1000 @@ -78,7 +78,7 @@ #define MAX_TIMESLICE (200 * HZ / 1000) #define TIMESLICE_GRANULARITY (HZ/40 ?: 1) #define ON_RUNQUEUE_WEIGHT 30 -#define CHILD_PENALTY 90 +#define CHILD_PENALTY 95 #define PARENT_PENALTY 100 #define EXIT_WEIGHT 3 #define PRIO_BONUS_RATIO 25 @@ -365,6 +365,9 @@ static void recalc_task_prio(task_t *p, unsigned long long __sleep_time = now - p->timestamp; unsigned long sleep_time; + if (!p->sleep_avg) + p->interactive_credit--; + if (__sleep_time > NS_MAX_SLEEP_AVG) sleep_time = NS_MAX_SLEEP_AVG; else @@ -384,17 +387,19 @@ static void recalc_task_prio(task_t *p, JIFFIES_TO_NS(JUST_INTERACTIVE_SLEEP(p)); else { /* - * Tasks with interactive credits get boosted more - * rapidly if their bonus has dropped off. Other - * tasks are limited to one timeslice worth of - * sleep avg. + * 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. */ - if (p->interactive_credit > 0) - sleep_time *= (MAX_BONUS + 1 - + sleep_time *= (MAX_BONUS + 1 - (NS_TO_JIFFIES(p->sleep_avg) * MAX_BONUS / MAX_SLEEP_AVG)); - else if (sleep_time > JIFFIES_TO_NS(task_timeslice(p))) - sleep_time = JIFFIES_TO_NS(task_timeslice(p)); + + if (p->interactive_credit < 0 && + sleep_time > JIFFIES_TO_NS(task_timeslice(p))) + sleep_time = + JIFFIES_TO_NS(task_timeslice(p)); /* * This code gives a bonus to interactive tasks. @@ -435,20 +440,26 @@ static inline void activate_task(task_t recalc_task_prio(p, now); /* - * Tasks which were woken up by interrupts (ie. hw events) - * are most likely of interactive nature. So we give them - * the credit of extending their sleep time to the period - * of time they spend on the runqueue, waiting for execution - * on a CPU, first time around: + * This checks to make sure it's not an uninterruptible task + * that is now waking up. */ - if (in_interrupt()) - p->activated = 2; - else - /* - * Normal first-time wakeups get a credit too for on-runqueue time, - * but it will be weighted down: - */ - p->activated = 1; + if (!p->activated){ + /* + * Tasks which were woken up by interrupts (ie. hw events) + * are most likely of interactive nature. So we give them + * the credit of extending their sleep time to the period + * of time they spend on the runqueue, waiting for execution + * on a CPU, first time around: + */ + if (in_interrupt()) + p->activated = 2; + else + /* + * Normal first-time wakeups get a credit too for on-runqueue + * time, but it will be weighted down: + */ + p->activated = 1; + } p->timestamp = now; @@ -572,8 +583,15 @@ repeat_lock_task: task_rq_unlock(rq, &flags); goto repeat_lock_task; } - if (old_state == TASK_UNINTERRUPTIBLE) + if (old_state == TASK_UNINTERRUPTIBLE){ + /* + * Tasks on involuntary sleep don't earn + * sleep_avg + */ rq->nr_uninterruptible--; + p->timestamp = sched_clock(); + p->activated = -1; + } if (sync) __activate_task(p, rq); else { @@ -1326,7 +1344,6 @@ void scheduler_tick(int user_ticks, int p->prio = effective_prio(p); p->time_slice = task_timeslice(p); p->first_time_slice = 0; - p->interactive_credit--; if (!rq->expired_timestamp) rq->expired_timestamp = jiffies; @@ -1459,7 +1476,7 @@ pick_next_task: queue = array->queue + idx; next = list_entry(queue->next, task_t, run_list); - if (next->activated && next->interactive_credit > 0) { + if (next->activated > 0) { unsigned long long delta = now - next->timestamp; if (next->activated == 1)