aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Adamushko <dmitry.adamushko@gmail.com>2007-10-15 11:00:12 -0400
committerIngo Molnar <mingo@elte.hu>2007-10-15 11:00:12 -0400
commit2b1e315dd2822c99793485f9e53a73459fb399c1 (patch)
treea24cc75606f9416e19bf6662949b880b6b20873a
parent8651a86c342ab79a956afec0c5971acaad38d3a1 (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>
-rw-r--r--kernel/sched_fair.c25
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)
739static void yield_task_fair(struct rq *rq) 739static 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/*