This follows Barry's approach, which yields fewer groups in the higher domains.
Signed-off-by: Valentin Schneider valentin.schneider@arm.com --- kernel/sched/topology.c | 42 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 23 deletions(-)
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index 0fa41aab74e0..e1bb97c06f53 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c @@ -949,20 +949,21 @@ static void init_overlap_sched_group(struct sched_domain *sd, sg->sgc->max_capacity = SCHED_CAPACITY_SCALE; }
-static struct sched_domain *find_node_domain(struct sched_domain *sd) +static struct sched_domain * +find_sibling_domain(struct sched_domain *sd, struct sched_domain *sibling) { - struct sched_domain *parent; - BUG_ON(!(sd->flags & SD_NUMA));
- /* Get to the level above NODE */ - while (sd && sd->child) { - parent = sd; - sd = sd->child; + /* Find a subset sibling */ + while (sibling->child && + !cpumask_subset(sched_domain_span(sibling->child), + sched_domain_span(sd))) + sibling = sibling->child; + + /* If the above loop was a no-op, we're done */ + if (sd->private == sibling->private) + return sibling;
- if (!(sd->flags & SD_NUMA)) - break; - } /* * We're going to create cross topology level sched_group_capacity * references. This can only work if the domains resulting from said @@ -972,16 +973,14 @@ static struct sched_domain *find_node_domain(struct sched_domain *sd) * * Of course, groups aren't available yet, so we can't call the usual * sd_degenerate(). Checking domain spans is the closest we get. - * Start from NODE's parent, and keep going up until we get a domain - * we're sure won't be degenerated. + * We can't go up as per the above subset check, so keep going down + * until we get a domain we're sure won't be degenerated. */ - while (sd->parent && - cpumask_equal(sched_domain_span(sd), sched_domain_span(parent))) { - sd = parent; - parent = sd->parent; - } + while (sibling->child && + cpumask_equal(sched_domain_span(sibling->child), sched_domain_span(sibling))) + sibling = sibling->child;
- return parent; + return sibling; }
static int @@ -1017,12 +1016,9 @@ build_overlap_sched_groups(struct sched_domain *sd, int cpu) if (!cpumask_test_cpu(i, sched_domain_span(sibling))) continue;
- /* - * Local group is child domain's span, as is tradition. - * Non-local groups will only span remote nodes. - */ + /* Ensure sibling domain's span is a subset of this domain */ if (first) - sibling = find_node_domain(sibling); + sibling = find_sibling_domain(sd, sibling);
sg = build_group_from_child_sched_domain(sibling, cpu); if (!sg)