Skip to content

Commit ce29a7d

Browse files
swahlhpePeter Zijlstra
authored andcommitted
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 <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Valentin Schneider <[email protected]> Reviewed-by: Madadi Vineeth Reddy <[email protected]> Tested-by: K Prateek Nayak <[email protected]> Tested-by: Valentin Schneider <[email protected]> Tested-by: Madadi Vineeth Reddy <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent f55dac1 commit ce29a7d

File tree

1 file changed

+19
-33
lines changed

1 file changed

+19
-33
lines changed

kernel/sched/topology.c

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2352,17 +2352,12 @@ static struct sched_domain *build_sched_domain(struct sched_domain_topology_leve
23522352
static bool topology_span_sane(const struct cpumask *cpu_map)
23532353
{
23542354
struct sched_domain_topology_level *tl;
2355-
const struct cpumask **masks;
2356-
struct cpumask *covered;
2357-
int cpu, id;
2358-
bool ret = false;
2355+
struct cpumask *covered, *id_seen;
2356+
int cpu;
23592357

23602358
lockdep_assert_held(&sched_domains_mutex);
23612359
covered = sched_domains_tmpmask;
2362-
2363-
masks = kmalloc_array(nr_cpu_ids, sizeof(struct cpumask *), GFP_KERNEL);
2364-
if (!masks)
2365-
return ret;
2360+
id_seen = sched_domains_tmpmask2;
23662361

23672362
for_each_sd_topology(tl) {
23682363

@@ -2371,7 +2366,7 @@ static bool topology_span_sane(const struct cpumask *cpu_map)
23712366
continue;
23722367

23732368
cpumask_clear(covered);
2374-
memset(masks, 0, nr_cpu_ids * sizeof(struct cpumask *));
2369+
cpumask_clear(id_seen);
23752370

23762371
/*
23772372
* Non-NUMA levels cannot partially overlap - they must be either
@@ -2380,36 +2375,27 @@ static bool topology_span_sane(const struct cpumask *cpu_map)
23802375
* breaks the linking done for an earlier span.
23812376
*/
23822377
for_each_cpu(cpu, cpu_map) {
2383-
/* lowest bit set in this mask is used as a unique id */
2384-
id = cpumask_first(tl->mask(cpu));
2378+
const struct cpumask *tl_cpu_mask = tl->mask(cpu);
2379+
int id;
23852380

2386-
/* zeroed masks cannot possibly collide */
2387-
if (id >= nr_cpu_ids)
2388-
continue;
2381+
/* lowest bit set in this mask is used as a unique id */
2382+
id = cpumask_first(tl_cpu_mask);
23892383

2390-
/* if this mask doesn't collide with what we've already seen */
2391-
if (!cpumask_intersects(tl->mask(cpu), covered)) {
2392-
/* this failing would be an error in this algorithm */
2393-
if (WARN_ON(masks[id]))
2394-
goto notsane;
2384+
if (cpumask_test_cpu(id, id_seen)) {
2385+
/* First CPU has already been seen, ensure identical spans */
2386+
if (!cpumask_equal(tl->mask(id), tl_cpu_mask))
2387+
return false;
2388+
} else {
2389+
/* First CPU hasn't been seen before, ensure it's a completely new span */
2390+
if (cpumask_intersects(tl_cpu_mask, covered))
2391+
return false;
23952392

2396-
/* record the mask we saw for this id */
2397-
masks[id] = tl->mask(cpu);
2398-
cpumask_or(covered, tl->mask(cpu), covered);
2399-
} else if ((!masks[id]) || !cpumask_equal(masks[id], tl->mask(cpu))) {
2400-
/*
2401-
* a collision with covered should have exactly matched
2402-
* a previously seen mask with the same id
2403-
*/
2404-
goto notsane;
2393+
cpumask_or(covered, covered, tl_cpu_mask);
2394+
cpumask_set_cpu(id, id_seen);
24052395
}
24062396
}
24072397
}
2408-
ret = true;
2409-
2410-
notsane:
2411-
kfree(masks);
2412-
return ret;
2398+
return true;
24132399
}
24142400

24152401
/*

0 commit comments

Comments
 (0)