
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) -- 2.27.0