aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Linton <jeremy.linton@arm.com>2018-06-06 12:38:46 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2018-06-07 12:42:11 -0400
commite156ab71a974737c279530e3b868131291fe677e (patch)
treeff1731e42a419d25b5a7caf04bc101fb6b5da8e2
parent2520e627dbeecf7ccccc50c969504b59e1a3294b (diff)
arm64: topology: Avoid checking numa mask for scheduler MC selection
The numa mask subset check can often lead to system hang or crash during CPU hotplug and system suspend operation if NUMA is disabled. This is mostly observed on HMP systems where the CPU compute capacities are different and ends up in different scheduler domains. Since cpumask_of_node is returned instead core_sibling, the scheduler is confused with incorrect cpumasks(e.g. one CPU in two different sched domains at the same time) on CPU hotplug. Lets disable the NUMA siblings checks for the time being, as NUMA in socket machines have LLC's that will assure that the scheduler topology isn't "borken". The NUMA check exists to assure that if a LLC within a socket crosses NUMA nodes/chiplets the scheduler domains remain consistent. This code will likely have to be re-enabled in the near future once the NUMA mask story is sorted. At the moment its not necessary because the NUMA in socket machines LLC's are contained within the NUMA domains. Further, as a defensive mechanism during hot-plug, lets assure that the LLC siblings are also masked. Reported-by: Geert Uytterhoeven <geert@linux-m68k.org> Reviewed-by: Sudeep Holla <sudeep.holla@arm.com> Tested-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--arch/arm64/kernel/topology.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 7415c166281f..f845a8617812 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -215,13 +215,8 @@ EXPORT_SYMBOL_GPL(cpu_topology);
215 215
216const struct cpumask *cpu_coregroup_mask(int cpu) 216const struct cpumask *cpu_coregroup_mask(int cpu)
217{ 217{
218 const cpumask_t *core_mask = cpumask_of_node(cpu_to_node(cpu)); 218 const cpumask_t *core_mask = &cpu_topology[cpu].core_sibling;
219 219
220 /* Find the smaller of NUMA, core or LLC siblings */
221 if (cpumask_subset(&cpu_topology[cpu].core_sibling, core_mask)) {
222 /* not numa in package, lets use the package siblings */
223 core_mask = &cpu_topology[cpu].core_sibling;
224 }
225 if (cpu_topology[cpu].llc_id != -1) { 220 if (cpu_topology[cpu].llc_id != -1) {
226 if (cpumask_subset(&cpu_topology[cpu].llc_siblings, core_mask)) 221 if (cpumask_subset(&cpu_topology[cpu].llc_siblings, core_mask))
227 core_mask = &cpu_topology[cpu].llc_siblings; 222 core_mask = &cpu_topology[cpu].llc_siblings;
@@ -239,8 +234,10 @@ static void update_siblings_masks(unsigned int cpuid)
239 for_each_possible_cpu(cpu) { 234 for_each_possible_cpu(cpu) {
240 cpu_topo = &cpu_topology[cpu]; 235 cpu_topo = &cpu_topology[cpu];
241 236
242 if (cpuid_topo->llc_id == cpu_topo->llc_id) 237 if (cpuid_topo->llc_id == cpu_topo->llc_id) {
243 cpumask_set_cpu(cpu, &cpuid_topo->llc_siblings); 238 cpumask_set_cpu(cpu, &cpuid_topo->llc_siblings);
239 cpumask_set_cpu(cpuid, &cpu_topo->llc_siblings);
240 }
244 241
245 if (cpuid_topo->package_id != cpu_topo->package_id) 242 if (cpuid_topo->package_id != cpu_topo->package_id)
246 continue; 243 continue;