diff options
author | Dmitry Adamushko <dmitry.adamushko@gmail.com> | 2007-10-15 11:00:13 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2007-10-15 11:00:13 -0400 |
commit | 08ec3df5109e0555da5b9deb4382fd29733c852c (patch) | |
tree | 4739cd8a9b37b9d5482f88db3c8cdc78b07a8a98 /kernel/sched_fair.c | |
parent | 647e7cac2d215fb8890f79252d7eaee3d6743d66 (diff) |
sched: fix __pick_next_entity()
The thing is that __pick_next_entity() must never be called when
first_fair(cfs_rq) == NULL. It wouldn't be a problem, should 'run_node'
be the very first field of 'struct sched_entity' (and it's the second).
The 'nr_running != 0' check is _not_ enough, due to the fact that
'current' is not within the tree. Generic paths are ok (e.g. schedule()
as put_prev_task() is called previously)... I'm more worried about e.g.
migration_call() -> CPU_DEAD_FROZEN -> migrate_dead_tasks()... if
'current' == rq->idle, no problems.. if it's one of the SCHED_NORMAL
tasks (or imagine, some other use-cases in the future -- i.e. we should
not make outer world dependent on internal details of sched_fair class)
-- it may be "Houston, we've got a problem" case.
it's +16 bytes to the ".text". Another variant is to make 'run_node' the
first data member of 'struct sched_entity' but an additional check (se !
= NULL) is still needed in pick_next_entity().
Signed-off-by: Dmitry Adamushko <dmitry.adamushko@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/sched_fair.c')
-rw-r--r-- | kernel/sched_fair.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 1f14b56d0d00..fa78686ec227 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -600,9 +600,12 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) | |||
600 | 600 | ||
601 | static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq) | 601 | static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq) |
602 | { | 602 | { |
603 | struct sched_entity *se = __pick_next_entity(cfs_rq); | 603 | struct sched_entity *se = NULL; |
604 | 604 | ||
605 | set_next_entity(cfs_rq, se); | 605 | if (first_fair(cfs_rq)) { |
606 | se = __pick_next_entity(cfs_rq); | ||
607 | set_next_entity(cfs_rq, se); | ||
608 | } | ||
606 | 609 | ||
607 | return se; | 610 | return se; |
608 | } | 611 | } |