powerpc/numa: Invalidate numa_cpu_lookup_table on cpu remove
authorNathan Fontenot <nfont@linux.vnet.ibm.com>
Fri, 26 Jan 2018 19:41:59 +0000 (13:41 -0600)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 8 Feb 2018 12:56:10 +0000 (23:56 +1100)
When DLPAR removing a CPU, the unmapping of the cpu from a node in
unmap_cpu_from_node() should also invalidate the CPUs entry in the
numa_cpu_lookup_table. There is not a guarantee that on a subsequent
DLPAR add of the CPU the associativity will be the same and thus
could be in a different node. Invalidating the entry in the
numa_cpu_lookup_table causes the associativity to be read from the
device tree at the time of the add.

The current behavior of not invalidating the CPUs entry in the
numa_cpu_lookup_table can result in scenarios where the the topology
layout of CPUs in the partition does not match the device tree
or the topology reported by the HMC.

This bug looks like it was introduced in 2004 in the commit titled
"ppc64: cpu hotplug notifier for numa", which is 6b15e4e87e32 in the
linux-fullhist tree. Hence tag it for all stable releases.

Cc: stable@vger.kernel.org
Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Reviewed-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/topology.h
arch/powerpc/mm/numa.c
arch/powerpc/platforms/pseries/hotplug-cpu.c

index 88187c285c70d5d823ccdf0a572cb8a7e24a6341..1c02e6900f78511be78f864fbfbcf49391557bd1 100644 (file)
@@ -44,6 +44,11 @@ extern int sysfs_add_device_to_node(struct device *dev, int nid);
 extern void sysfs_remove_device_from_node(struct device *dev, int nid);
 extern int numa_update_cpu_topology(bool cpus_locked);
 
+static inline void update_numa_cpu_lookup_table(unsigned int cpu, int node)
+{
+       numa_cpu_lookup_table[cpu] = node;
+}
+
 static inline int early_cpu_to_node(int cpu)
 {
        int nid;
index 314d19ab9385e038a4f38c18a50364da4873eb86..edd8d0bc9364f2843688498b221d90f53647390d 100644 (file)
@@ -143,11 +143,6 @@ static void reset_numa_cpu_lookup_table(void)
                numa_cpu_lookup_table[cpu] = -1;
 }
 
-static void update_numa_cpu_lookup_table(unsigned int cpu, int node)
-{
-       numa_cpu_lookup_table[cpu] = node;
-}
-
 static void map_cpu_to_node(int cpu, int node)
 {
        update_numa_cpu_lookup_table(cpu, node);
index dceb51454d8d212a5cbc78ef891322bddf499800..f78fd2068d56a5497643a4ef8a2516eb3721d3dc 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/xics.h>
 #include <asm/xive.h>
 #include <asm/plpar_wrappers.h>
+#include <asm/topology.h>
 
 #include "pseries.h"
 #include "offline_states.h"
@@ -331,6 +332,7 @@ static void pseries_remove_processor(struct device_node *np)
                        BUG_ON(cpu_online(cpu));
                        set_cpu_present(cpu, false);
                        set_hard_smp_processor_id(cpu, -1);
+                       update_numa_cpu_lookup_table(cpu, -1);
                        break;
                }
                if (cpu >= nr_cpu_ids)