--- kernel/sched.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) Index: linux-2.6.20.2-rsdl/kernel/sched.c =================================================================== --- linux-2.6.20.2-rsdl.orig/kernel/sched.c 2007-03-12 10:46:56.000000000 +1100 +++ linux-2.6.20.2-rsdl/kernel/sched.c 2007-03-12 10:47:20.000000000 +1100 @@ -17,7 +17,7 @@ * 2003-09-03 Interactivity tuning by Con Kolivas. * 2004-04-02 Scheduler domains code by Nick Piggin * 2007-03-02 Rotating Staircase deadline scheduling policy by Con Kolivas - * RSDL v0.29 + * RSDL v0.30 */ #include @@ -85,10 +85,9 @@ * provided it is not a realtime comparison. */ #define TASK_PREEMPTS_CURR(p, curr) \ - (((p)->prio < (curr)->prio) || (((p)->prio == (curr)->prio) && \ + (((p)->prio < (curr)->prio) || (!rt_task(p) && \ ((p)->static_prio < (curr)->static_prio && \ - ((curr)->static_prio > (curr)->prio)) && \ - !rt_task(p))) + ((curr)->static_prio > (curr)->prio)))) /* * This is the time all tasks within the same priority round robin. @@ -3089,7 +3088,7 @@ static inline void major_prio_rotation(s */ static inline void rotate_runqueue_priority(struct rq *rq) { - int new_prio_level, remaining_quota; + int new_prio_level; struct prio_array *array; /* @@ -3100,7 +3099,6 @@ static inline void rotate_runqueue_prior if (unlikely(sched_find_first_bit(rq->dyn_bitmap) < rq->prio_level)) return; - remaining_quota = rq_quota(rq, rq->prio_level); array = rq->active; if (rq->prio_level > MAX_PRIO - 2) { /* Major rotation required */ @@ -3134,10 +3132,11 @@ static inline void rotate_runqueue_prior } rq->prio_level = new_prio_level; /* - * While we usually rotate with the rq quota being 0, it is possible - * to be negative so we subtract any deficit from the new level. + * As we are merging to a prio_level that may not have anything in + * its quota we add 1 to ensure the tasks get to run in schedule() to + * add their quota to it. */ - rq_quota(rq, new_prio_level) += remaining_quota; + rq_quota(rq, new_prio_level) += 1; } static void task_running_tick(struct rq *rq, struct task_struct *p) @@ -3163,12 +3162,11 @@ static void task_running_tick(struct rq if (!--p->time_slice) task_expired_entitlement(rq, p); /* - * The rq quota can become negative due to a task being queued in - * scheduler without any quota left at that priority level. It is - * cheaper to allow it to run till this scheduler tick and then - * subtract it from the quota of the merged queues. + * We only employ the deadline mechanism if we run over the quota. + * It allows aliasing problems around the scheduler_tick to be + * less harmful. */ - if (!rt_task(p) && --rq_quota(rq, rq->prio_level) <= 0) { + if (!rt_task(p) && --rq_quota(rq, rq->prio_level) < 0) { if (unlikely(p->first_time_slice)) p->first_time_slice = 0; rotate_runqueue_priority(rq);