This avoids the issue of having a system with a CLS SD but no MC SD. CLS should be sub-SD of MC. The cpumask under /sys/devices/system/cpu/cpu*/cache/index* and /sys/devices/system/cpu/cpu*/topology are not changed by this. Signed-off-by: Dietmar Eggemann <dietmar.eggemann@xxxxxxx> --- drivers/base/arch_topology.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 976154140f0b..9af90a5625c7 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -614,7 +614,7 @@ static int __init parse_dt_topology(void) struct cpu_topology cpu_topology[NR_CPUS]; EXPORT_SYMBOL_GPL(cpu_topology); -const struct cpumask *cpu_coregroup_mask(int cpu) +const struct cpumask *_cpu_coregroup_mask(int cpu) { const cpumask_t *core_mask = cpumask_of_node(cpu_to_node(cpu)); @@ -631,11 +631,37 @@ const struct cpumask *cpu_coregroup_mask(int cpu) return core_mask; } -const struct cpumask *cpu_clustergroup_mask(int cpu) +const struct cpumask *_cpu_clustergroup_mask(int cpu) { return &cpu_topology[cpu].cluster_sibling; } +static int +swap_masks(const cpumask_t *core_mask, const cpumask_t *cluster_mask) +{ + if (cpumask_weight(core_mask) == 1 && + cpumask_subset(core_mask, cluster_mask)) + return 1; + + return 0; +} + +const struct cpumask *cpu_coregroup_mask(int cpu) +{ + const cpumask_t *cluster_mask = _cpu_clustergroup_mask(cpu); + const cpumask_t *core_mask = _cpu_coregroup_mask(cpu); + + return swap_masks(core_mask, cluster_mask) ? cluster_mask : core_mask; +} + +const struct cpumask *cpu_clustergroup_mask(int cpu) +{ + const cpumask_t *cluster_mask = _cpu_clustergroup_mask(cpu); + const cpumask_t *core_mask = _cpu_coregroup_mask(cpu); + + return swap_masks(core_mask, cluster_mask) ? core_mask : cluster_mask; +} + void update_siblings_masks(unsigned int cpuid) { struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; -- 2.25.1