diff options
author | Dmitry Adamushko <dmitry.adamushko@gmail.com> | 2007-10-15 17:00:12 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2007-10-15 17:00:12 +0200 |
commit | 2b1e315dd2822c99793485f9e53a73459fb399c1 (patch) | |
tree | a24cc75606f9416e19bf6662949b880b6b20873a /kernel/sched_fair.c | |
parent | 8651a86c342ab79a956afec0c5971acaad38d3a1 (diff) | |
download | lwn-2b1e315dd2822c99793485f9e53a73459fb399c1.tar.gz lwn-2b1e315dd2822c99793485f9e53a73459fb399c1.zip |
sched: yield fix
fix yield bugs due to the current-not-in-rbtree changes: the task is
not in the rbtree so rbtree-removal is a no-no.
[ From: Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com>: build fix. ]
also, nice code size reduction:
kernel/sched.o:
text data bss dec hex filename
38323 3506 24 41853 a37d sched.o.before
38236 3506 24 41766 a326 sched.o.after
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Dmitry Adamushko <dmitry.adamushko@gmail.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/sched_fair.c')
-rw-r--r-- | kernel/sched_fair.c | 25 |
1 files changed, 5 insertions, 20 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 5384a977c9a7..fcd6900849b3 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -739,9 +739,7 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep) static void yield_task_fair(struct rq *rq) { struct cfs_rq *cfs_rq = task_cfs_rq(rq->curr); - struct rb_node **link = &cfs_rq->tasks_timeline.rb_node; struct sched_entity *rightmost, *se = &rq->curr->se; - struct rb_node *parent; /* * Are we the only task in the tree? @@ -755,39 +753,26 @@ static void yield_task_fair(struct rq *rq) * Dequeue and enqueue the task to update its * position within the tree: */ - dequeue_entity(cfs_rq, se, 0); - enqueue_entity(cfs_rq, se, 0); + update_curr(cfs_rq); return; } /* * Find the rightmost entry in the rbtree: */ - do { - parent = *link; - link = &parent->rb_right; - } while (*link); - - rightmost = rb_entry(parent, struct sched_entity, run_node); + rightmost = __pick_last_entity(cfs_rq); /* * Already in the rightmost position? */ - if (unlikely(rightmost == se)) + if (unlikely(rightmost->vruntime < se->vruntime)) return; /* * Minimally necessary key value to be last in the tree: + * Upon rescheduling, sched_class::put_prev_task() will place + * 'current' within the tree based on its new key value. */ se->vruntime = rightmost->vruntime + 1; - - if (cfs_rq->rb_leftmost == &se->run_node) - cfs_rq->rb_leftmost = rb_next(&se->run_node); - /* - * Relink the task to the rightmost position: - */ - rb_erase(&se->run_node, &cfs_rq->tasks_timeline); - rb_link_node(&se->run_node, parent, link); - rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline); } /* |