diff options
author | Peter Zijlstra <peterz@infradead.org> | 2016-05-09 10:37:57 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-09-30 10:54:06 +0200 |
commit | 16f3ef46805a5ffc75549deac2ff6af08bdf590b (patch) | |
tree | 08ae64c54ddf97ea5b960d69e2ee993b28c2764f | |
parent | f39180efe5737af8467139bf8af7ca27057be87f (diff) |
sched/core: Restructure destroy_sched_domain()
There is no point in doing a call_rcu() for each domain, only do a
callback for the root sched domain and clean up the entire set in one
go.
Also make the entire call chain be called destroy_sched_domain*() to
remove confusion with the free_sched_domains() call, which does an
entirely different thing.
Both cpu_attach_domain() callers of destroy_sched_domain() can live
without the call_rcu() because at those points the sched_domain hasn't
been published yet.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | kernel/sched/core.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index b3cd5553ecbb..662d08d7b1df 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -5935,10 +5935,8 @@ static void free_sched_groups(struct sched_group *sg, int free_sgc) } while (sg != first); } -static void free_sched_domain(struct rcu_head *rcu) +static void destroy_sched_domain(struct sched_domain *sd) { - struct sched_domain *sd = container_of(rcu, struct sched_domain, rcu); - /* * If its an overlapping domain it has private groups, iterate and * nuke them all. @@ -5952,15 +5950,21 @@ static void free_sched_domain(struct rcu_head *rcu) kfree(sd); } -static void destroy_sched_domain(struct sched_domain *sd) +static void destroy_sched_domains_rcu(struct rcu_head *rcu) { - call_rcu(&sd->rcu, free_sched_domain); + struct sched_domain *sd = container_of(rcu, struct sched_domain, rcu); + + while (sd) { + struct sched_domain *parent = sd->parent; + destroy_sched_domain(sd); + sd = parent; + } } static void destroy_sched_domains(struct sched_domain *sd) { - for (; sd; sd = sd->parent) - destroy_sched_domain(sd); + if (sd) + call_rcu(&sd->rcu, destroy_sched_domains_rcu); } /* |