From: Peter Zijlstra <pet...@infradead.org> pick_next_entity() is passed curr == NULL during core-scheduling. Due to this, if the rbtree is empty, the 'left' variable is set to NULL within the function. This can cause crashes within the function.
This is not an issue if put_prev_task() is invoked on the currently running task before calling pick_next_entity(). However, in core scheduling, it is possible that a sibling CPU picks for another RQ in the core, via pick_task_fair(). This remote sibling would not get any opportunities to do a put_prev_task(). Fix it by refactoring pick_task_fair() such that pick_next_entity() is called with the cfs_rq->curr. This will prevent pick_next_entity() from crashing if its rbtree is empty. Also this fixes another possible bug where update_curr() would not be called on the cfs_rq hierarchy if the rbtree is empty. This could effect cross-cpu comparison of vruntime. Suggested-by: Vineeth Remanan Pillai <virem...@linux.microsoft.com> Signed-off-by: Peter Zijlstra <pet...@infradead.org> Signed-off-by: Joel Fernandes (Google) <j...@joelfernandes.org> --- kernel/sched/fair.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 12cf068eeec8..51483a00a755 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7029,15 +7029,10 @@ static struct task_struct *pick_task_fair(struct rq *rq) do { struct sched_entity *curr = cfs_rq->curr; - se = pick_next_entity(cfs_rq, NULL); - - if (curr) { - if (se && curr->on_rq) - update_curr(cfs_rq); + if (curr && curr->on_rq) + update_curr(cfs_rq); - if (!se || entity_before(curr, se)) - se = curr; - } + se = pick_next_entity(cfs_rq, curr); cfs_rq = group_cfs_rq(se); } while (cfs_rq); -- 2.29.2.299.gdc1121823c-goog