mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 18:09:56 +00:00
sched/topology: Refinement to topology_span_sane speedup
Simplify the topology_span_sane code further, removing the need to allocate an array and gotos used to make sure the array gets freed. This version is in a separate commit because it could return a different sanity result than the previous code, but only in odd circumstances that are not expected to actually occur; for example, when a CPU is not listed in its own mask. Signed-off-by: Steve Wahl <steve.wahl@hpe.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Valentin Schneider <vschneid@redhat.com> Reviewed-by: Madadi Vineeth Reddy <vineethr@linux.ibm.com> Tested-by: K Prateek Nayak <kprateek.nayak@amd.com> Tested-by: Valentin Schneider <vschneid@redhat.com> Tested-by: Madadi Vineeth Reddy <vineethr@linux.ibm.com> Link: https://lore.kernel.org/r/20250304160844.75373-3-steve.wahl@hpe.com
This commit is contained in:
committed by
Peter Zijlstra
parent
f55dac1daf
commit
ce29a7da84
@@ -2352,17 +2352,12 @@ static struct sched_domain *build_sched_domain(struct sched_domain_topology_leve
|
|||||||
static bool topology_span_sane(const struct cpumask *cpu_map)
|
static bool topology_span_sane(const struct cpumask *cpu_map)
|
||||||
{
|
{
|
||||||
struct sched_domain_topology_level *tl;
|
struct sched_domain_topology_level *tl;
|
||||||
const struct cpumask **masks;
|
struct cpumask *covered, *id_seen;
|
||||||
struct cpumask *covered;
|
int cpu;
|
||||||
int cpu, id;
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
lockdep_assert_held(&sched_domains_mutex);
|
lockdep_assert_held(&sched_domains_mutex);
|
||||||
covered = sched_domains_tmpmask;
|
covered = sched_domains_tmpmask;
|
||||||
|
id_seen = sched_domains_tmpmask2;
|
||||||
masks = kmalloc_array(nr_cpu_ids, sizeof(struct cpumask *), GFP_KERNEL);
|
|
||||||
if (!masks)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
for_each_sd_topology(tl) {
|
for_each_sd_topology(tl) {
|
||||||
|
|
||||||
@@ -2371,7 +2366,7 @@ static bool topology_span_sane(const struct cpumask *cpu_map)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
cpumask_clear(covered);
|
cpumask_clear(covered);
|
||||||
memset(masks, 0, nr_cpu_ids * sizeof(struct cpumask *));
|
cpumask_clear(id_seen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Non-NUMA levels cannot partially overlap - they must be either
|
* Non-NUMA levels cannot partially overlap - they must be either
|
||||||
@@ -2380,36 +2375,27 @@ static bool topology_span_sane(const struct cpumask *cpu_map)
|
|||||||
* breaks the linking done for an earlier span.
|
* breaks the linking done for an earlier span.
|
||||||
*/
|
*/
|
||||||
for_each_cpu(cpu, cpu_map) {
|
for_each_cpu(cpu, cpu_map) {
|
||||||
|
const struct cpumask *tl_cpu_mask = tl->mask(cpu);
|
||||||
|
int id;
|
||||||
|
|
||||||
/* lowest bit set in this mask is used as a unique id */
|
/* lowest bit set in this mask is used as a unique id */
|
||||||
id = cpumask_first(tl->mask(cpu));
|
id = cpumask_first(tl_cpu_mask);
|
||||||
|
|
||||||
/* zeroed masks cannot possibly collide */
|
if (cpumask_test_cpu(id, id_seen)) {
|
||||||
if (id >= nr_cpu_ids)
|
/* First CPU has already been seen, ensure identical spans */
|
||||||
continue;
|
if (!cpumask_equal(tl->mask(id), tl_cpu_mask))
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
/* First CPU hasn't been seen before, ensure it's a completely new span */
|
||||||
|
if (cpumask_intersects(tl_cpu_mask, covered))
|
||||||
|
return false;
|
||||||
|
|
||||||
/* if this mask doesn't collide with what we've already seen */
|
cpumask_or(covered, covered, tl_cpu_mask);
|
||||||
if (!cpumask_intersects(tl->mask(cpu), covered)) {
|
cpumask_set_cpu(id, id_seen);
|
||||||
/* this failing would be an error in this algorithm */
|
|
||||||
if (WARN_ON(masks[id]))
|
|
||||||
goto notsane;
|
|
||||||
|
|
||||||
/* record the mask we saw for this id */
|
|
||||||
masks[id] = tl->mask(cpu);
|
|
||||||
cpumask_or(covered, tl->mask(cpu), covered);
|
|
||||||
} else if ((!masks[id]) || !cpumask_equal(masks[id], tl->mask(cpu))) {
|
|
||||||
/*
|
|
||||||
* a collision with covered should have exactly matched
|
|
||||||
* a previously seen mask with the same id
|
|
||||||
*/
|
|
||||||
goto notsane;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = true;
|
return true;
|
||||||
|
|
||||||
notsane:
|
|
||||||
kfree(masks);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user