diff options
author | Dmitry Adamushko <dmitry.adamushko@gmail.com> | 2007-10-15 11:00:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2007-10-15 11:00:12 -0400 |
commit | 2b1e315dd2822c99793485f9e53a73459fb399c1 (patch) | |
tree | a24cc75606f9416e19bf6662949b880b6b20873a /kernel/sched_fair.c | |
parent | 8651a86c342ab79a956afec0c5971acaad38d3a1 (diff) |
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) | |||
739 | static void yield_task_fair(struct rq *rq) | 739 | static void yield_task_fair(struct rq *rq) |
740 | { | 740 | { |
741 | struct cfs_rq *cfs_rq = task_cfs_rq(rq->curr); | 741 | struct cfs_rq *cfs_rq = task_cfs_rq(rq->curr); |
742 | struct rb_node **link = &cfs_rq->tasks_timeline.rb_node; | ||
743 | struct sched_entity *rightmost, *se = &rq->curr->se; | 742 | struct sched_entity *rightmost, *se = &rq->curr->se; |
744 | struct rb_node *parent; | ||
745 | 743 | ||
746 | /* | 744 | /* |
747 | * Are we the only task in the tree? | 745 | * Are we the only task in the tree? |
@@ -755,39 +753,26 @@ static void yield_task_fair(struct rq *rq) | |||
755 | * Dequeue and enqueue the task to update its | 753 | * Dequeue and enqueue the task to update its |
756 | * position within the tree: | 754 | * position within the tree: |
757 | */ | 755 | */ |
758 | dequeue_entity(cfs_rq, se, 0); | 756 | update_curr(cfs_rq); |
759 | enqueue_entity(cfs_rq, se, 0); | ||
760 | 757 | ||
761 | return; | 758 | return; |
762 | } | 759 | } |
763 | /* | 760 | /* |
764 | * Find the rightmost entry in the rbtree: | 761 | * Find the rightmost entry in the rbtree: |
765 | */ | 762 | */ |
766 | do { | 763 | rightmost = __pick_last_entity(cfs_rq); |
767 | parent = *link; | ||
768 | link = &parent->rb_right; | ||
769 | } while (*link); | ||
770 | |||
771 | rightmost = rb_entry(parent, struct sched_entity, run_node); | ||
772 | /* | 764 | /* |
773 | * Already in the rightmost position? | 765 | * Already in the rightmost position? |
774 | */ | 766 | */ |
775 | if (unlikely(rightmost == se)) | 767 | if (unlikely(rightmost->vruntime < se->vruntime)) |
776 | return; | 768 | return; |
777 | 769 | ||
778 | /* | 770 | /* |
779 | * Minimally necessary key value to be last in the tree: | 771 | * Minimally necessary key value to be last in the tree: |
772 | * Upon rescheduling, sched_class::put_prev_task() will place | ||
773 | * 'current' within the tree based on its new key value. | ||
780 | */ | 774 | */ |
781 | se->vruntime = rightmost->vruntime + 1; | 775 | se->vruntime = rightmost->vruntime + 1; |
782 | |||
783 | if (cfs_rq->rb_leftmost == &se->run_node) | ||
784 | cfs_rq->rb_leftmost = rb_next(&se->run_node); | ||
785 | /* | ||
786 | * Relink the task to the rightmost position: | ||
787 | */ | ||
788 | rb_erase(&se->run_node, &cfs_rq->tasks_timeline); | ||
789 | rb_link_node(&se->run_node, parent, link); | ||
790 | rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline); | ||
791 | } | 776 | } |
792 | 777 | ||
793 | /* | 778 | /* |