mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-29 04:09:39 +00:00
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>
This commit is contained in:
parent
8651a86c34
commit
2b1e315dd2
1 changed files with 5 additions and 20 deletions
|
@ -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)
|
static void yield_task_fair(struct rq *rq)
|
||||||
{
|
{
|
||||||
struct cfs_rq *cfs_rq = task_cfs_rq(rq->curr);
|
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 sched_entity *rightmost, *se = &rq->curr->se;
|
||||||
struct rb_node *parent;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Are we the only task in the tree?
|
* 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
|
* Dequeue and enqueue the task to update its
|
||||||
* position within the tree:
|
* position within the tree:
|
||||||
*/
|
*/
|
||||||
dequeue_entity(cfs_rq, se, 0);
|
update_curr(cfs_rq);
|
||||||
enqueue_entity(cfs_rq, se, 0);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Find the rightmost entry in the rbtree:
|
* Find the rightmost entry in the rbtree:
|
||||||
*/
|
*/
|
||||||
do {
|
rightmost = __pick_last_entity(cfs_rq);
|
||||||
parent = *link;
|
|
||||||
link = &parent->rb_right;
|
|
||||||
} while (*link);
|
|
||||||
|
|
||||||
rightmost = rb_entry(parent, struct sched_entity, run_node);
|
|
||||||
/*
|
/*
|
||||||
* Already in the rightmost position?
|
* Already in the rightmost position?
|
||||||
*/
|
*/
|
||||||
if (unlikely(rightmost == se))
|
if (unlikely(rightmost->vruntime < se->vruntime))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Minimally necessary key value to be last in the tree:
|
* 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;
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue