Index: linux-2.6.30-bfs014/kernel/sched_bfs.c =================================================================== --- linux-2.6.30-bfs014.orig/kernel/sched_bfs.c 2009-08-25 16:16:30.826750871 +1000 +++ linux-2.6.30-bfs014/kernel/sched_bfs.c 2009-08-25 16:43:53.828049190 +1000 @@ -283,13 +283,6 @@ #endif } -static inline void time_lock_rq(struct rq *rq) - __acquires(grq.lock) -{ - spin_lock(&grq.lock); - update_rq_clock(rq); -} - static inline int task_running(struct task_struct *p) { return (!!p->oncpu); @@ -313,6 +306,13 @@ spin_lock_irq(&grq.lock); } +static inline void time_lock_rq(struct rq *rq) + __acquires(grq.lock) +{ + grq_lock(); + update_rq_clock(rq); +} + static inline void grq_unlock_irq(void) __releases(grq.lock) { @@ -491,14 +491,9 @@ sched_info_queued(p); } -/* - * Requeue a running task that's running. The position in the run list is - * irrelevant for SCHED_NORMAL tasks. RT tasks only need moving. - */ +/* No need to do anything, it happens on return_task */ static inline void requeue_task(struct task_struct *p) { - if (rt_task(p)) - list_move_tail(&p->run_list, grq.queue + p->prio); sched_info_queued(p); } @@ -1863,18 +1858,25 @@ #endif /* - * Deadline is "now" in jiffies + (offset by priority). + * Deadline is "now" in jiffies + (offset by priority). Setting the deadline + * is the key to everything. It distributes cpu fairly amongst tasks of the + * same nice value, it proportions cpu according to nice level, it means the + * task that last woke up the longest ago has the earliest deadline, thus + * ensuring that interactive tasks get low latency on wake up. */ -static inline void set_deadline(struct task_struct *p) +static inline void time_slice_expired(struct task_struct *p) { - if (p->time_slice > 0 || rt_task(p)) - return; - reset_first_time_slice(p); p->time_slice = timeslice(); p->deadline = jiffies + (prio_ratio(p) * rr_interval * HZ / 1000 / 100); } +static inline void check_deadline(struct task_struct *p) +{ + if (p->time_slice <= 0) + time_slice_expired(p); +} + static inline int longest_deadline(void) { return (prio_ratios[39] * rr_interval * HZ / 100) + 1; @@ -2034,7 +2036,7 @@ } if (prev != rq->idle) { - set_deadline(prev); + check_deadline(prev); return_task(prev, deactivate); } @@ -3191,12 +3193,12 @@ */ SYSCALL_DEFINE0(sched_yield) { - struct task_struct *p = current; + struct task_struct *p; grq_lock_irq(); + p = current; schedstat_inc(this_rq(), yld_count); - if (!rt_task(p)) - p->deadline = jiffies + longest_deadline(); + time_slice_expired(p); requeue_task(p); /*