Skip to content

Commit c47f892

Browse files
srikardmpe
authored andcommitted
powerpc/smp: Reintroduce cpu_core_mask
Daniel reported that with Commit 4ca234a ("powerpc/smp: Stop updating cpu_core_mask") QEMU was unable to set single NUMA node SMP topologies such as: -smp 8,maxcpus=8,cores=2,threads=2,sockets=2 i.e he expected 2 sockets in one NUMA node. The above commit helped to reduce boot time on Large Systems for example 4096 vCPU single socket QEMU instance. PAPR is silent on having more than one socket within a NUMA node. cpu_core_mask and cpu_cpu_mask for any CPU would be same unless the number of sockets is different from the number of NUMA nodes. One option is to reintroduce cpu_core_mask but use a slightly different method to arrive at the cpu_core_mask. Previously each CPU's chip-id would be compared with all other CPU's chip-id to verify if both the CPUs were related at the chip level. Now if a CPU 'A' is found related / (unrelated) to another CPU 'B', all the thread siblings of 'A' and thread siblings of 'B' are automatically marked as related / (unrelated). Also if a platform doesn't support ibm,chip-id property, i.e its cpu_to_chip_id returns -1, cpu_core_map holds a copy of cpu_cpu_mask(). Fixes: 4ca234a ("powerpc/smp: Stop updating cpu_core_mask") Reported-by: Daniel Henrique Barboza <[email protected]> Signed-off-by: Srikar Dronamraju <[email protected]> Tested-by: Daniel Henrique Barboza <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent e9e1691 commit c47f892

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

arch/powerpc/include/asm/smp.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ static inline struct cpumask *cpu_sibling_mask(int cpu)
121121
return per_cpu(cpu_sibling_map, cpu);
122122
}
123123

124+
static inline struct cpumask *cpu_core_mask(int cpu)
125+
{
126+
return per_cpu(cpu_core_map, cpu);
127+
}
128+
124129
static inline struct cpumask *cpu_l2_cache_mask(int cpu)
125130
{
126131
return per_cpu(cpu_l2_cache_map, cpu);

arch/powerpc/kernel/smp.c

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,17 +1057,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
10571057
local_memory_node(numa_cpu_lookup_table[cpu]));
10581058
}
10591059
#endif
1060-
/*
1061-
* cpu_core_map is now more updated and exists only since
1062-
* its been exported for long. It only will have a snapshot
1063-
* of cpu_cpu_mask.
1064-
*/
1065-
cpumask_copy(per_cpu(cpu_core_map, cpu), cpu_cpu_mask(cpu));
10661060
}
10671061

10681062
/* Init the cpumasks so the boot CPU is related to itself */
10691063
cpumask_set_cpu(boot_cpuid, cpu_sibling_mask(boot_cpuid));
10701064
cpumask_set_cpu(boot_cpuid, cpu_l2_cache_mask(boot_cpuid));
1065+
cpumask_set_cpu(boot_cpuid, cpu_core_mask(boot_cpuid));
10711066

10721067
if (has_coregroup_support())
10731068
cpumask_set_cpu(boot_cpuid, cpu_coregroup_mask(boot_cpuid));
@@ -1408,6 +1403,9 @@ static void remove_cpu_from_masks(int cpu)
14081403
set_cpus_unrelated(cpu, i, cpu_smallcore_mask);
14091404
}
14101405

1406+
for_each_cpu(i, cpu_core_mask(cpu))
1407+
set_cpus_unrelated(cpu, i, cpu_core_mask);
1408+
14111409
if (has_coregroup_support()) {
14121410
for_each_cpu(i, cpu_coregroup_mask(cpu))
14131411
set_cpus_unrelated(cpu, i, cpu_coregroup_mask);
@@ -1468,8 +1466,11 @@ static void update_coregroup_mask(int cpu, cpumask_var_t *mask)
14681466

14691467
static void add_cpu_to_masks(int cpu)
14701468
{
1469+
struct cpumask *(*submask_fn)(int) = cpu_sibling_mask;
14711470
int first_thread = cpu_first_thread_sibling(cpu);
1471+
int chip_id = cpu_to_chip_id(cpu);
14721472
cpumask_var_t mask;
1473+
bool ret;
14731474
int i;
14741475

14751476
/*
@@ -1485,12 +1486,36 @@ static void add_cpu_to_masks(int cpu)
14851486
add_cpu_to_smallcore_masks(cpu);
14861487

14871488
/* In CPU-hotplug path, hence use GFP_ATOMIC */
1488-
alloc_cpumask_var_node(&mask, GFP_ATOMIC, cpu_to_node(cpu));
1489+
ret = alloc_cpumask_var_node(&mask, GFP_ATOMIC, cpu_to_node(cpu));
14891490
update_mask_by_l2(cpu, &mask);
14901491

14911492
if (has_coregroup_support())
14921493
update_coregroup_mask(cpu, &mask);
14931494

1495+
if (chip_id == -1 || !ret) {
1496+
cpumask_copy(per_cpu(cpu_core_map, cpu), cpu_cpu_mask(cpu));
1497+
goto out;
1498+
}
1499+
1500+
if (shared_caches)
1501+
submask_fn = cpu_l2_cache_mask;
1502+
1503+
/* Update core_mask with all the CPUs that are part of submask */
1504+
or_cpumasks_related(cpu, cpu, submask_fn, cpu_core_mask);
1505+
1506+
/* Skip all CPUs already part of current CPU core mask */
1507+
cpumask_andnot(mask, cpu_online_mask, cpu_core_mask(cpu));
1508+
1509+
for_each_cpu(i, mask) {
1510+
if (chip_id == cpu_to_chip_id(i)) {
1511+
or_cpumasks_related(cpu, i, submask_fn, cpu_core_mask);
1512+
cpumask_andnot(mask, mask, submask_fn(i));
1513+
} else {
1514+
cpumask_andnot(mask, mask, cpu_core_mask(i));
1515+
}
1516+
}
1517+
1518+
out:
14941519
free_cpumask_var(mask);
14951520
}
14961521

0 commit comments

Comments
 (0)