--- v7
+++ v2
@@ -1,88 +1,105 @@
-This helper is only used with the dispatch trace log collection.
-A later patch will add Form2 affinity support and this change helps
-in keeping that simpler. Also add a comment explaining we don't expect
-the code to be called with FORM0
+The associativity details of the newly added resourced are collected from
+the hypervisor via "ibm,configure-connector" rtas call. Update the numa
+distance details of the newly added numa node after the above call. In
+later patch we will remove updating NUMA distance when we are looking
+for node id from associativity array.
-Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
- arch/powerpc/include/asm/topology.h | 4 ++--
- arch/powerpc/mm/numa.c | 10 +++++++++-
- arch/powerpc/platforms/pseries/lpar.c | 4 ++--
- 3 files changed, 13 insertions(+), 5 deletions(-)
+ arch/powerpc/mm/numa.c | 41 +++++++++++++++++++
+ arch/powerpc/platforms/pseries/hotplug-cpu.c | 2 +
+ .../platforms/pseries/hotplug-memory.c | 2 +
+ arch/powerpc/platforms/pseries/pseries.h | 1 +
+ 4 files changed, 46 insertions(+)
-diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
-index a6425a70c37b..a4712ecad3e9 100644
---- a/arch/powerpc/include/asm/topology.h
-+++ b/arch/powerpc/include/asm/topology.h
-@@ -36,7 +36,7 @@ static inline int pcibus_to_node(struct pci_bus *bus)
- cpu_all_mask : \
- cpumask_of_node(pcibus_to_node(bus)))
-
--extern int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc);
-+int cpu_relative_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc);
- extern int __node_distance(int, int);
- #define node_distance(a, b) __node_distance(a, b)
-
-@@ -84,7 +84,7 @@ static inline void sysfs_remove_device_from_node(struct device *dev,
-
- static inline void update_numa_cpu_lookup_table(unsigned int cpu, int node) {}
-
--static inline int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
-+static inline int cpu_relative_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
- {
- return 0;
- }
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
-index c695faf67d68..a244398a7766 100644
+index 0ec16999beef..645a95e3a7ea 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
-@@ -166,7 +166,7 @@ static void unmap_cpu_from_node(unsigned long cpu)
+@@ -287,6 +287,47 @@ int of_node_to_nid(struct device_node *device)
}
- #endif /* CONFIG_HOTPLUG_CPU || CONFIG_PPC_SPLPAR */
+ EXPORT_SYMBOL(of_node_to_nid);
--int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
-+static int __cpu_form1_relative_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
- {
- int dist = 0;
-
-@@ -182,6 +182,14 @@ int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
- return dist;
- }
-
-+int cpu_relative_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc)
++static void __initialize_form1_numa_distance(const __be32 *associativity)
+{
-+ /* We should not get called with FORM0 */
-+ VM_WARN_ON(affinity_form == FORM0_AFFINITY);
++ int i, nid;
+
-+ return __cpu_form1_relative_distance(cpu1_assoc, cpu2_assoc);
++ if (of_read_number(associativity, 1) >= primary_domain_index) {
++ nid = of_read_number(&associativity[primary_domain_index], 1);
++
++ for (i = 0; i < max_domain_index; i++) {
++ const __be32 *entry;
++
++ entry = &associativity[be32_to_cpu(distance_ref_points[i])];
++ distance_lookup_table[nid][i] = of_read_number(entry, 1);
++ }
++ }
+}
+
- /* must hold reference to node during call */
- static const __be32 *of_get_associativity(struct device_node *dev)
++static void initialize_form1_numa_distance(struct device_node *node)
++{
++ const __be32 *associativity;
++
++ associativity = of_get_associativity(node);
++ if (!associativity)
++ return;
++
++ __initialize_form1_numa_distance(associativity);
++ return;
++}
++
++/*
++ * Used to update distance information w.r.t newly added node.
++ */
++void update_numa_distance(struct device_node *node)
++{
++ if (affinity_form == FORM0_AFFINITY)
++ return;
++ else if (affinity_form == FORM1_AFFINITY) {
++ initialize_form1_numa_distance(node);
++ return;
++ }
++}
++
+ static int __init find_primary_domain_index(void)
{
-diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
-index dab356e3ff87..afefbdfe768d 100644
---- a/arch/powerpc/platforms/pseries/lpar.c
-+++ b/arch/powerpc/platforms/pseries/lpar.c
-@@ -261,7 +261,7 @@ static int cpu_relative_dispatch_distance(int last_disp_cpu, int cur_disp_cpu)
- if (!last_disp_cpu_assoc || !cur_disp_cpu_assoc)
- return -EIO;
+ int index;
+diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
+index 7e970f81d8ff..778b6ab35f0d 100644
+--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
++++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
+@@ -498,6 +498,8 @@ static ssize_t dlpar_cpu_add(u32 drc_index)
+ return saved_rc;
+ }
-- return cpu_distance(last_disp_cpu_assoc, cur_disp_cpu_assoc);
-+ return cpu_relative_distance(last_disp_cpu_assoc, cur_disp_cpu_assoc);
- }
++ update_numa_distance(dn);
++
+ rc = dlpar_online_cpu(dn);
+ if (rc) {
+ saved_rc = rc;
+diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
+index 8377f1f7c78e..0e602c3b01ea 100644
+--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
++++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
+@@ -180,6 +180,8 @@ static int update_lmb_associativity_index(struct drmem_lmb *lmb)
+ return -ENODEV;
+ }
- static int cpu_home_node_dispatch_distance(int disp_cpu)
-@@ -281,7 +281,7 @@ static int cpu_home_node_dispatch_distance(int disp_cpu)
- if (!disp_cpu_assoc || !vcpu_assoc)
- return -EIO;
++ update_numa_distance(lmb_node);
++
+ dr_node = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
+ if (!dr_node) {
+ dlpar_free_cc_nodes(lmb_node);
+diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
+index 1f051a786fb3..663a0859cf13 100644
+--- a/arch/powerpc/platforms/pseries/pseries.h
++++ b/arch/powerpc/platforms/pseries/pseries.h
+@@ -113,4 +113,5 @@ extern u32 pseries_security_flavor;
+ void pseries_setup_security_mitigations(void);
+ void pseries_lpar_read_hblkrm_characteristics(void);
-- return cpu_distance(disp_cpu_assoc, vcpu_assoc);
-+ return cpu_relative_distance(disp_cpu_assoc, vcpu_assoc);
- }
-
- static void update_vcpu_disp_stat(int disp_cpu)
++void update_numa_distance(struct device_node *node);
+ #endif /* _PSERIES_PSERIES_H */
--
2.31.1