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>
This commit is contained in:
Peter Zijlstra 2016-05-09 10:37:57 +02:00 committed by Ingo Molnar
parent f39180efe5
commit 16f3ef4680
1 changed files with 11 additions and 7 deletions

View File

@ -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);
}
/*