diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 567c571d624f..94d1fe0aec5a 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -313,6 +313,7 @@ static inline bool list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq) * the list, this means to put the child at the tail * of the list that starts by parent. */ + WARN(cfs_rq->tg->parent->dead, "parent marked dead! (cfs_rq = %px, parent = %px)", cfs_rq, cfs_rq->tg->parent); list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list, &(cfs_rq->tg->parent->cfs_rq[cpu]->leaf_cfs_rq_list)); /* @@ -329,6 +330,7 @@ static inline bool list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq) * cfs rq without parent should be put * at the tail of the list. */ + WARN(cfs_rq->tg->dead, "tg marked dead! (cfs_rq = %px, tg = %px)", cfs_rq, cfs_rq->tg); list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list, &rq->leaf_cfs_rq_list); /* @@ -345,6 +347,7 @@ static inline bool list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq) * tmp_alone_branch points to the begin of the branch * where we will add parent. */ + WARN(cfs_rq->tg->dead, "tg marked dead! (cfs_rq = %px, tg = %px)", cfs_rq, cfs_rq->tg); list_add_rcu(&cfs_rq->leaf_cfs_rq_list, rq->tmp_alone_branch); /* * update tmp_alone_branch to points to the new begin @@ -3277,6 +3280,7 @@ static inline bool child_cfs_rq_on_list(struct cfs_rq *cfs_rq) prev = rq->tmp_alone_branch; } + BUG_ON(prev == LIST_POISON2); prev_cfs_rq = container_of(prev, struct cfs_rq, leaf_cfs_rq_list); return (prev_cfs_rq->tg->parent == cfs_rq->tg); @@ -11369,6 +11373,8 @@ void unregister_fair_sched_group(struct task_group *tg) struct rq *rq; int cpu; + WARN(tg->dead, "tg already dead! (tg = %px)", tg); + tg->dead = 1; for_each_possible_cpu(cpu) { if (tg->se[cpu]) remove_entity_load_avg(tg->se[cpu]); @@ -11386,6 +11392,10 @@ void unregister_fair_sched_group(struct task_group *tg) list_del_leaf_cfs_rq(tg->cfs_rq[cpu]); raw_spin_rq_unlock_irqrestore(rq, flags); } + + for_each_possible_cpu(cpu) { + WARN(tg->cfs_rq[cpu]->on_list, "found on_list cfs_rq! (cpu = %d, cfs_rq = %px, tg = %px)", cpu, tg->cfs_rq[cpu], tg); + } } void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq, diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index eaca971a3ee2..218dead1f4db 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -395,6 +395,7 @@ struct task_group { /* runqueue "owned" by this group on each CPU */ struct cfs_rq **cfs_rq; unsigned long shares; + unsigned char dead; #ifdef CONFIG_SMP /*