Commit 7a6c6547 authored by David Rientjes's avatar David Rientjes Committed by Ingo Molnar

x86, numa: Fix cpu nodemasks for NUMA emulation and CONFIG_DEBUG_PER_CPU_MAPS

The cpu<->node mappings under CONFIG_DEBUG_PER_CPU_MAPS=y
when NUMA emulation is enabled is currently broken because it does
not iterate through every emulated node and bind cpus that have
affinity to it.

NUMA emulation should bind each cpu to every local node to
accurately represent the true NUMA topology of the underlying
machine.

debug_cpumask_set_cpu() needs to be fixed at the same time so
that the debugging information that it emits shows the new
cpumask of the node being assigned when the cpu is being added
or removed.

It can now take responsibility of setting or clearing the cpu
itself to remove the need for duplicate code.

Also change its last parameter, "enable", to have the correct bool
type since it can only be true or false.

 -v2: Fix the return statements, by Kosaki Motohiro
Acked-and-Tested-by: default avatarKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: default avatarDavid Rientjes <rientjes@google.com>
Cc: Andreas Herrmann <herrmann.der.user@googlemail.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Link: http://lkml.kernel.org/r/alpine.DEB.2.00.1104201918470.12634@chino.kir.corp.google.comSigned-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 37f8527d
...@@ -51,7 +51,7 @@ static inline void numa_remove_cpu(int cpu) { } ...@@ -51,7 +51,7 @@ static inline void numa_remove_cpu(int cpu) { }
#endif /* CONFIG_NUMA */ #endif /* CONFIG_NUMA */
#ifdef CONFIG_DEBUG_PER_CPU_MAPS #ifdef CONFIG_DEBUG_PER_CPU_MAPS
struct cpumask __cpuinit *debug_cpumask_set_cpu(int cpu, int enable); void debug_cpumask_set_cpu(int cpu, int node, bool enable);
#endif #endif
#endif /* _ASM_X86_NUMA_H */ #endif /* _ASM_X86_NUMA_H */
...@@ -213,53 +213,48 @@ int early_cpu_to_node(int cpu) ...@@ -213,53 +213,48 @@ int early_cpu_to_node(int cpu)
return per_cpu(x86_cpu_to_node_map, cpu); return per_cpu(x86_cpu_to_node_map, cpu);
} }
struct cpumask __cpuinit *debug_cpumask_set_cpu(int cpu, int enable) void debug_cpumask_set_cpu(int cpu, int node, bool enable)
{ {
int node = early_cpu_to_node(cpu);
struct cpumask *mask; struct cpumask *mask;
char buf[64]; char buf[64];
if (node == NUMA_NO_NODE) { if (node == NUMA_NO_NODE) {
/* early_cpu_to_node() already emits a warning and trace */ /* early_cpu_to_node() already emits a warning and trace */
return NULL; return;
} }
mask = node_to_cpumask_map[node]; mask = node_to_cpumask_map[node];
if (!mask) { if (!mask) {
pr_err("node_to_cpumask_map[%i] NULL\n", node); pr_err("node_to_cpumask_map[%i] NULL\n", node);
dump_stack(); dump_stack();
return NULL; return;
} }
if (enable)
cpumask_set_cpu(cpu, mask);
else
cpumask_clear_cpu(cpu, mask);
cpulist_scnprintf(buf, sizeof(buf), mask); cpulist_scnprintf(buf, sizeof(buf), mask);
printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n", printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n",
enable ? "numa_add_cpu" : "numa_remove_cpu", enable ? "numa_add_cpu" : "numa_remove_cpu",
cpu, node, buf); cpu, node, buf);
return mask; return;
} }
# ifndef CONFIG_NUMA_EMU # ifndef CONFIG_NUMA_EMU
static void __cpuinit numa_set_cpumask(int cpu, int enable) static void __cpuinit numa_set_cpumask(int cpu, bool enable)
{ {
struct cpumask *mask; debug_cpumask_set_cpu(cpu, early_cpu_to_node(cpu), enable);
mask = debug_cpumask_set_cpu(cpu, enable);
if (!mask)
return;
if (enable)
cpumask_set_cpu(cpu, mask);
else
cpumask_clear_cpu(cpu, mask);
} }
void __cpuinit numa_add_cpu(int cpu) void __cpuinit numa_add_cpu(int cpu)
{ {
numa_set_cpumask(cpu, 1); numa_set_cpumask(cpu, true);
} }
void __cpuinit numa_remove_cpu(int cpu) void __cpuinit numa_remove_cpu(int cpu)
{ {
numa_set_cpumask(cpu, 0); numa_set_cpumask(cpu, false);
} }
# endif /* !CONFIG_NUMA_EMU */ # endif /* !CONFIG_NUMA_EMU */
......
...@@ -454,10 +454,9 @@ void __cpuinit numa_remove_cpu(int cpu) ...@@ -454,10 +454,9 @@ void __cpuinit numa_remove_cpu(int cpu)
cpumask_clear_cpu(cpu, node_to_cpumask_map[i]); cpumask_clear_cpu(cpu, node_to_cpumask_map[i]);
} }
#else /* !CONFIG_DEBUG_PER_CPU_MAPS */ #else /* !CONFIG_DEBUG_PER_CPU_MAPS */
static void __cpuinit numa_set_cpumask(int cpu, int enable) static void __cpuinit numa_set_cpumask(int cpu, bool enable)
{ {
struct cpumask *mask; int nid, physnid;
int nid, physnid, i;
nid = early_cpu_to_node(cpu); nid = early_cpu_to_node(cpu);
if (nid == NUMA_NO_NODE) { if (nid == NUMA_NO_NODE) {
...@@ -467,28 +466,21 @@ static void __cpuinit numa_set_cpumask(int cpu, int enable) ...@@ -467,28 +466,21 @@ static void __cpuinit numa_set_cpumask(int cpu, int enable)
physnid = emu_nid_to_phys[nid]; physnid = emu_nid_to_phys[nid];
for_each_online_node(i) { for_each_online_node(nid) {
if (emu_nid_to_phys[nid] != physnid) if (emu_nid_to_phys[nid] != physnid)
continue; continue;
mask = debug_cpumask_set_cpu(cpu, enable); debug_cpumask_set_cpu(cpu, nid, enable);
if (!mask)
return;
if (enable)
cpumask_set_cpu(cpu, mask);
else
cpumask_clear_cpu(cpu, mask);
} }
} }
void __cpuinit numa_add_cpu(int cpu) void __cpuinit numa_add_cpu(int cpu)
{ {
numa_set_cpumask(cpu, 1); numa_set_cpumask(cpu, true);
} }
void __cpuinit numa_remove_cpu(int cpu) void __cpuinit numa_remove_cpu(int cpu)
{ {
numa_set_cpumask(cpu, 0); numa_set_cpumask(cpu, false);
} }
#endif /* !CONFIG_DEBUG_PER_CPU_MAPS */ #endif /* !CONFIG_DEBUG_PER_CPU_MAPS */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment