Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/numa: Online a node if PHB is attached.

In the current design, a numa-node is made online only if that node is
attached to cpu/memory. With this design, if any PCI/IO device is found
to be attached to a numa-node which is not online then the numa-node
id of the corresponding PCI/IO device is set to NUMA_NO_NODE(-1). This
design may negatively impact the performance of PCIe device if the
numa-node assigned to PCIe device is -1 because in such case we may not
be able to accurately calculate the distance between two nodes.

The multi-controller NVMe PCIe disk has an issue with calculating the
node distance if the PCIe NVMe controller is attached to a PCI host
bridge which has numa-node id value set to NUMA_NO_NODE. This patch
helps fix this ensuring that a cpu/memory less numa node is made online
if it's attached to PCI host bridge.

Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
Reviewed-by: Srikar Dronamraju <srikar@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20240517142531.3273464-3-nilay@linux.ibm.com

authored by

Nilay Shroff and committed by
Michael Ellerman
11981816 ff5163bb

+27 -1
+13 -1
arch/powerpc/mm/numa.c
··· 896 896 897 897 static int __init parse_numa_properties(void) 898 898 { 899 - struct device_node *memory; 899 + struct device_node *memory, *pci; 900 900 int default_nid = 0; 901 901 unsigned long i; 902 902 const __be32 *associativity; ··· 1008 1008 1009 1009 if (--ranges) 1010 1010 goto new_range; 1011 + } 1012 + 1013 + for_each_node_by_name(pci, "pci") { 1014 + int nid = NUMA_NO_NODE; 1015 + 1016 + associativity = of_get_associativity(pci); 1017 + if (associativity) { 1018 + nid = associativity_to_nid(associativity); 1019 + initialize_form1_numa_distance(associativity); 1020 + } 1021 + if (likely(nid >= 0) && !node_online(nid)) 1022 + node_set_online(nid); 1011 1023 } 1012 1024 1013 1025 /*
+14
arch/powerpc/platforms/pseries/pci_dlpar.c
··· 11 11 12 12 #include <linux/pci.h> 13 13 #include <linux/export.h> 14 + #include <linux/node.h> 14 15 #include <asm/pci-bridge.h> 15 16 #include <asm/ppc-pci.h> 16 17 #include <asm/firmware.h> ··· 22 21 struct pci_controller *init_phb_dynamic(struct device_node *dn) 23 22 { 24 23 struct pci_controller *phb; 24 + int nid; 25 25 26 26 pr_debug("PCI: Initializing new hotplug PHB %pOF\n", dn); 27 + 28 + nid = of_node_to_nid(dn); 29 + if (likely((nid) >= 0)) { 30 + if (!node_online(nid)) { 31 + if (__register_one_node(nid)) { 32 + pr_err("PCI: Failed to register node %d\n", nid); 33 + } else { 34 + update_numa_distance(dn); 35 + node_set_online(nid); 36 + } 37 + } 38 + } 27 39 28 40 phb = pcibios_alloc_controller(dn); 29 41 if (!phb)