arm64:numa: Add numa support for arm64 platforms.
Subsystems (2)
cover arm64:numa: Add numa support for arm64 platforms.
This is initial patch set to support numa on arm64 based platforms. Tested these patches on cavium's multinode(2 node topology) simulator. Tried all test-cases present in numactl-2.0.9 package.
In this patchset, defined dt bindings for numa mapping for memory nodes. The cpu to node mapping is derived from the existing cpu-map mapping as defined in topology binding.
thanks,
Ganapat
Ganapatrao Kulkarni (4):
arm64: defconfig: increase NR_CPUS range to 2-128 arm/arm64:dt:numa: adding numa node mapping for memory nodes. arm64:thunder: Add initial dts for Cavium Thunder SoC in 2 Node topology. arm64:numa: adding numa support for arm64 platforms.
Documentation/devicetree/bindings/arm/numa.txt | 60 ++ arch/arm64/Kconfig | 37 +- arch/arm64/boot/dts/thunder-88xx-2n.dts | 76 ++ arch/arm64/boot/dts/thunder-88xx-2n.dtsi | 990 +++++++++++++++++++++++++ arch/arm64/include/asm/mmzone.h | 32 + arch/arm64/include/asm/numa.h | 41 + arch/arm64/kernel/setup.c | 8 + arch/arm64/kernel/smp.c | 2 + arch/arm64/mm/Makefile | 1 + arch/arm64/mm/init.c | 33 +- arch/arm64/mm/numa.c | 471 ++++++++++++ 11 files changed, 1745 insertions(+), 6 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/numa.txt create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dts create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dtsi create mode 100644 arch/arm64/include/asm/mmzone.h create mode 100644 arch/arm64/include/asm/numa.h create mode 100644 arch/arm64/mm/numa.c
Signature · 1 line
1.8.1.4
RFC PATCH 1/4 arm64: defconfig: increase NR_CPUS range to 2-128
Raising the maximum limit to 128. This is needed for Cavium's Thunder systems that will have 96 cores on Multi-node system.
--- arch/arm64/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/Kconfig +2 -2
@@ -296,8 +296,8 @@ config SCHED_SMT places. If unsure say N here. config NR_CPUS - int "Maximum number of CPUs (2-64)" - range 2 64 + int "Maximum number of CPUs (2-128)" + range 2 128 depends on SMP # These have to remain sorted largest to smallest default "64"
Signature · 1 line
1.8.1.4
Mark Rutland
reviewerRFC PATCH 1/4 arm64: defconfig: increase NR_CPUS range to 2-128
Quoted 2 lines · Ganapatrao Kulkarni
Raising the maximum limit to 128. This is needed for Cavium's Thunder systems that will have 96 cores on Multi-node system.
Has this been tested on any such systems?
Mark.
Quoted 29 lines
Signed-off-by Ganapatrao Kulkarni <[email protected]>--- arch/arm64/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)arch/arm64/Kconfig +2
-2@@ -296,8 +296,8 @@ config SCHED_SMT places. If unsure say N here. config NR_CPUS - int "Maximum number of CPUs (2-64)" - range 2 64 + int "Maximum number of CPUs (2-128)" + range 2 128 depends on SMP # These have to remain sorted largest to smallest default "64"Signature · 6 lines
1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo at vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RFC PATCH 1/4 arm64: defconfig: increase NR_CPUS range to 2-128
Quoted 5 lines · Mark Rutland
Quoted 2 lines · Ganapatrao Kulkarni
Raising the maximum limit to 128. This is needed for Cavium's Thunder systems that will have 96 cores on Multi-node system.
Has this been tested on any such systems?
This is tested on Cavium's Thunder 2 Node Simulator with kernel 3.17-rc5. please let us know, if any specific configurations needs to be tested with the change.
Quoted 27 lines
Mark.
Quoted 24 lines
Signed-off-by Ganapatrao Kulkarni <[email protected]>--- arch/arm64/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)arch/arm64/Kconfig +2
-3@@ -296,8 +296,8 @@ config SCHED_SMT places. If unsure say N here. config NR_CPUS - int "Maximum number of CPUs (2-64)" - range 2 64 + int "Maximum number of CPUs (2-128)" + range 2 128 depends on SMP # These have to remain sorted largest to smallest default "64" --1.8.1.4
Quoted 5 lines
Quoted 5 lines
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
thanks
ganapat
RFC PATCH 2/4 arm/arm64:dt:numa: adding numa node mapping for memory nodes.
In reply to Ganapatrao KulkarniAdding Documentation for dt binding for memory to numa node mapping.
--- Documentation/devicetree/bindings/arm/numa.txt | 60 ++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
Documentation/devicetree/bindings/arm/numa.txt new file +60 -0
@@ -0,0 +1,60 @@ +======================================================== +ARM numa id binding description +======================================================== + +======================================================== +1 - Introduction +======================================================== + +The device node property nid (numa node id) can be added +to memory device node to map the range of memory addresses +as defined in property reg. The property nid maps the memory +range to the numa node id, which is used to find the local +and remote pages on numa aware systems. + +======================================================== +2 - nid property +======================================================== +nid is required property of memory device node for +numa enabled platforms. + +|------------------------------------------------------| +|Property Type | Usage | Value Type | Definition | +|------------------------------------------------------| +| nid | R | <u32> | Numa Node id | +| | | | for this memory | +|------------------------------------------------------| + +======================================================== +4 - Example memory nodes with numa information +======================================================== + +Example 1 (2 memory nodes, each mapped to a numa node.): + + memory at 00000000 { + device_type = "memory"; + reg = <0x0 0x00000000 0x0 0x80000000>; + nid = <0x0>; + }; + + memory at 10000000000 { + device_type = "memory"; + reg = <0x100 0x00000000 0x0 0x80000000>; + nid = <0x1>; + }; + +Example 2 (multiple memory ranges in each memory node and mapped to numa node): + + memory at 00000000 { + device_type = "memory"; + reg = <0x0 0x00000000 0x0 0x80000000>, + <0x1 0x00000000 0x0 0x80000000>; + nid = <0x0>; + }; + + memory at 10000000000 { + device_type = "memory"; + reg = <0x100 0x00000000 0x0 0x80000000>; + reg = <0x100 0x80000000 0x0 0x80000000>; + nid = <0x1>; + };
Signature · 1 line
1.8.1.4
Mark Rutland
reviewerRFC PATCH 2/4 arm/arm64:dt:numa: adding numa node mapping for memory nodes.
Quoted 1 line · Ganapatrao Kulkarni
Adding Documentation for dt binding for memory to numa node mapping.
As I previously commented [1], this binding doesn't specify what a nid maps to in terms of the CPU hierarchy, and is thus unusable. The binding absolutely must be explicit about this, and NAK until it is.
Given we're seeing systems with increasing numbers of CPUs and increasingly complex interconnect hierarchies, I would expect at minimum that we would refer to elements in the cpu-map to define the relationship between memory banks and CPUs.
What does the interconnect/memory hierarchy look like in your system?
Mark.
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-September/288263.html
Quoted 81 lines
Signed-off-by Ganapatrao Kulkarni <[email protected]>--- Documentation/devicetree/bindings/arm/numa.txt | 60 ++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/numa.txtDocumentation/devicetree/bindings/arm/numa.txt new file +60
-0@@ -0,0 +1,60 @@ +======================================================== +ARM numa id binding description +======================================================== + +======================================================== +1 - Introduction +======================================================== + +The device node property nid (numa node id) can be added +to memory device node to map the range of memory addresses +as defined in property reg. The property nid maps the memory +range to the numa node id, which is used to find the local +and remote pages on numa aware systems. + +======================================================== +2 - nid property +======================================================== +nid is required property of memory device node for +numa enabled platforms. + +|------------------------------------------------------| +|Property Type | Usage | Value Type | Definition | +|------------------------------------------------------| +| nid | R | <u32> | Numa Node id | +| | | | for this memory | +|------------------------------------------------------| + +======================================================== +4 - Example memory nodes with numa information +======================================================== + +Example 1 (2 memory nodes, each mapped to a numa node.): + + memory at 00000000 { + device_type = "memory"; + reg = <0x0 0x00000000 0x0 0x80000000>; + nid = <0x0>; + }; + + memory at 10000000000 { + device_type = "memory"; + reg = <0x100 0x00000000 0x0 0x80000000>; + nid = <0x1>; + }; + +Example 2 (multiple memory ranges in each memory node and mapped to numa node): + + memory at 00000000 { + device_type = "memory"; + reg = <0x0 0x00000000 0x0 0x80000000>, + <0x1 0x00000000 0x0 0x80000000>; + nid = <0x0>; + }; + + memory at 10000000000 { + device_type = "memory"; + reg = <0x100 0x00000000 0x0 0x80000000>; + reg = <0x100 0x80000000 0x0 0x80000000>; + nid = <0x1>; + };Signature · 6 lines
1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo at vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RFC PATCH 2/4 arm/arm64:dt:numa: adding numa node mapping for memory nodes.
Hi Mark,
Quoted 6 lines · Mark Rutland
Quoted 1 line · Ganapatrao Kulkarni
Adding Documentation for dt binding for memory to numa node mapping.
As I previously commented [1], this binding doesn't specify what a nid maps to in terms of the CPU hierarchy, and is thus unusable. The binding absolutely must be explicit about this, and NAK until it is.
The nid/numa node id is to map the each memory range/bank to numa node. IIUC, the numa manages the resources based on which node they are tide to. with nid, i am trying to map the memory range to a node.
Same follows for the all IO peripherals and for CPUs.
for cpus, i am using cluster-id as a node id to map all cpus to node. thunder has 2 nodes, in this patch, i have grouped all cpus which belongs to each node under cluster-id(cluster0, cluster1).
Quoted 7 lines
Given we're seeing systems with increasing numbers of CPUs and increasingly complex interconnect hierarchies, I would expect at minimum that we would refer to elements in the cpu-map to define the relationship between memory banks and CPUs.
What does the interconnect/memory hierarchy look like in your system?
In tunder, 2 SoCs (each has 48 cores and ram controllers and IOs) can be connected to form 2 node NUMA system.
in a SoC(within node) there is no hierarchy with respect to memory or IO access. However w.r.t GICv3,
48 cores are in each SoC/node are split in to 3 clusters each of 16 cores.
the MPIDR mapping for this topology is,
Aff0 is mapped to 16 cores within a cluster. Valid range is 0 to 0xf Aff1 is mapped to cluster number, valid values are 0,1 and 2. Aff2 is mapped to Socket-id/node id/SoC number. Valid values are 0 and 1.
Quoted 81 lines
Mark.
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-September/288263.html
Quoted 76 lines
Signed-off-by Ganapatrao Kulkarni <[email protected]>--- Documentation/devicetree/bindings/arm/numa.txt | 60 ++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/numa.txtDocumentation/devicetree/bindings/arm/numa.txt new file +60
-1@@ -0,0 +1,60 @@ +======================================================== +ARM numa id binding description +======================================================== + +======================================================== +1 - Introduction +======================================================== + +The device node property nid (numa node id) can be added +to memory device node to map the range of memory addresses +as defined in property reg. The property nid maps the memory +range to the numa node id, which is used to find the local +and remote pages on numa aware systems. + +======================================================== +2 - nid property +======================================================== +nid is required property of memory device node for +numa enabled platforms. + +|------------------------------------------------------| +|Property Type | Usage | Value Type | Definition | +|------------------------------------------------------| +| nid | R | <u32> | Numa Node id | +| | | | for this memory | +|------------------------------------------------------| + +======================================================== +4 - Example memory nodes with numa information +======================================================== + +Example 1 (2 memory nodes, each mapped to a numa node.): + + memory at 00000000 { + device_type = "memory"; + reg = <0x0 0x00000000 0x0 0x80000000>; + nid = <0x0>; + }; + + memory at 10000000000 { + device_type = "memory"; + reg = <0x100 0x00000000 0x0 0x80000000>; + nid = <0x1>; + }; + +Example 2 (multiple memory ranges in each memory node and mapped to numa node): + + memory at 00000000 { + device_type = "memory"; + reg = <0x0 0x00000000 0x0 0x80000000>, + <0x1 0x00000000 0x0 0x80000000>; + nid = <0x0>; + }; + + memory at 10000000000 { + device_type = "memory"; + reg = <0x100 0x00000000 0x0 0x80000000>; + reg = <0x100 0x80000000 0x0 0x80000000>; + nid = <0x1>; + }; --1.8.1.4
Quoted 5 lines
Quoted 5 lines
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
thanks
ganapat
Mark Rutland
reviewerRFC PATCH 2/4 arm/arm64:dt:numa: adding numa node mapping for memory nodes.
Quoted 10 lines · Ganapatrao Kulkarni
Hi Mark,
Quoted 6 lines · Mark Rutland
Quoted 1 line · Ganapatrao Kulkarni
Adding Documentation for dt binding for memory to numa node mapping.
As I previously commented [1], this binding doesn't specify what a nid maps to in terms of the CPU hierarchy, and is thus unusable. The binding absolutely must be explicit about this, and NAK until it is.
The nid/numa node id is to map the each memory range/bank to numa node.
The issue is what constitutes a "numa node" is not defined. Hence the mapping a memory banks to a "nid" is just a mapping to an arbitrary number -- the mapping of this number to CPUs isn't defined.
Quoted 4 lines
IIUC, the numa manages the resources based on which node they are tide to. with nid, i am trying to map the memory range to a node.
Same follows for the all IO peripherals and for CPUs.
for cpus, i am using cluster-id as a node id to map all cpus to node.
I strongly suspect that this is not going to work for very long. I don't think relying on a mapping of nid to a top-level cluster-id is a good idea, especially given we have the facility to be more explicit through use of the cpu-map.
We don't need to handle all the possible cases from the start, but I'd rather we consistently used the cou-map to explicitly define the relationship between CPUs and memory.
Quoted 16 lines
thunder has 2 nodes, in this patch, i have grouped all cpus which belongs to each node under cluster-id(cluster0, cluster1).
Quoted 6 lines
Given we're seeing systems with increasing numbers of CPUs and increasingly complex interconnect hierarchies, I would expect at minimum that we would refer to elements in the cpu-map to define the relationship between memory banks and CPUs.
What does the interconnect/memory hierarchy look like in your system?
In tunder, 2 SoCs (each has 48 cores and ram controllers and IOs) can be connected to form 2 node NUMA system.
in a SoC(within node) there is no hierarchy with respect to memory or IO access. However w.r.t GICv3,
48 cores are in each SoC/node are split in to 3 clusters each of 16 cores.
Quoted 4 lines
the MPIDR mapping for this topology is,
Aff0 is mapped to 16 cores within a cluster. Valid range is 0 to0xfAff1 is mapped to cluster number, valid values are 0,1 and 2. Aff2 is mapped to Socket-id/node id/SoC number. Valid values are 0 and 1.
Thanks for the information.
Mark.
RFC PATCH 2/4 arm/arm64:dt:numa: adding numa node mapping for memory nodes.
Quoted 21 lines · Mark Rutland
Quoted 10 lines · Ganapatrao Kulkarni
Hi Mark,
Quoted 6 lines · Mark Rutland
Quoted 1 line · Ganapatrao Kulkarni
Adding Documentation for dt binding for memory to numa node mapping.
As I previously commented [1], this binding doesn't specify what a nid maps to in terms of the CPU hierarchy, and is thus unusable. The binding absolutely must be explicit about this, and NAK until it is.
The nid/numa node id is to map the each memory range/bank to numa node.
The issue is what constitutes a "numa node" is not defined. Hence the mapping a memory banks to a "nid" is just a mapping to an arbitrary number -- the mapping of this number to CPUs isn't defined.
Quoted 4 lines
IIUC, the numa manages the resources based on which node they are tide to. with nid, i am trying to map the memory range to a node.
Same follows for the all IO peripherals and for CPUs.
for cpus, i am using cluster-id as a node id to map all cpus to node.
Quoted 8 lines
I strongly suspect that this is not going to work for very long. I don't think relying on a mapping of nid to a top-level cluster-id is a good idea, especially given we have the facility to be more explicit through use of the cpu-map.
We don't need to handle all the possible cases from the start, but I'd rather we consistently used the cou-map to explicitly define the relationship between CPUs and memory.
agreed, will implement nid mapping in cpu-map in v2 patchset.
Quoted 25 lines
Quoted 17 lines
thunder has 2 nodes, in this patch, i have grouped all cpus which belongs to each node under cluster-id(cluster0, cluster1).
Quoted 6 lines
Given we're seeing systems with increasing numbers of CPUs and increasingly complex interconnect hierarchies, I would expect at minimum that we would refer to elements in the cpu-map to define the relationship between memory banks and CPUs.
What does the interconnect/memory hierarchy look like in your system?
In tunder, 2 SoCs (each has 48 cores and ram controllers and IOs) can be connected to form 2 node NUMA system.
in a SoC(within node) there is no hierarchy with respect to memory or IO access. However w.r.t GICv3,
48 cores are in each SoC/node are split in to 3 clusters each of 16 cores.Quoted 4 lines
the MPIDR mapping for this topology is,
Aff0 is mapped to 16 cores within a cluster. Valid range is 0 to0xfAff1 is mapped to cluster number, valid values are 0,1 and 2. Aff2 is mapped to Socket-id/node id/SoC number. Valid values are 0 and 1.Thanks for the information.
Mark.
RFC PATCH 3/4 arm64:thunder: Add initial dts for Cavium Thunder SoC in 2 Node topology.
In reply to Ganapatrao Kulkarniadding devicetree definition for thunder's 2 node topology. Defined cpu-map for all 96 cores of 2 node system.
--- arch/arm64/boot/dts/thunder-88xx-2n.dts | 76 +++ arch/arm64/boot/dts/thunder-88xx-2n.dtsi | 990 +++++++++++++++++++++++++++++++ 2 files changed, 1066 insertions(+) create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dts create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dtsi
arch/arm64/boot/dts/thunder-88xx-2n.dts new file +76 -0
@@ -0,0 +1,76 @@ +/* + * Cavium Thunder DTS file - Thunder board description + * + * Copyright (C) 2014, Cavium Inc. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +/include/ "thunder-88xx-2n.dtsi" + +/ { + model = "Cavium ThunderX CN88XX board"; + compatible = "cavium,thunder-88xx"; + + aliases { + serial0 = &uaa0; + serial1 = &uaa1; + }; + + memory at 00000000 { + device_type = "memory"; + reg = <0x0 0x00000000 0x0 0x80000000>, + <0x1 0x00000000 0x0 0x80000000>; + nid = <0x0>; + }; + + memory at 10000000000 { + device_type = "memory"; + reg = <0x100 0x00000000 0x0 0x80000000>; + nid = <0x1>; + }; + +};
arch/arm64/boot/dts/thunder-88xx-2n.dtsi new file +990 -0
990 lines not on this page · raw message
Signature · 1 line
1.8.1.4
Mark Rutland
reviewerRFC PATCH 3/4 arm64:thunder: Add initial dts for Cavium Thunder SoC in 2 Node topology.
Quoted 2 lines · Ganapatrao Kulkarni
adding devicetree definition for thunder's 2 node topology. Defined cpu-map for all 96 cores of 2 node system.
[...]
Review
Quoted 12 lines
(quoted diff) +12
-0+ CPU0: cpu at 000 { + device_type = "cpu"; + compatible = "cavium,thunder", "arm,armv8"; + reg = <0x0 0x000>; + enable-method = "psci"; + }; + CPU1: cpu at 001 { + device_type = "cpu"; + compatible = "cavium,thunder", "arm,armv8"; + reg = <0x0 0x001>; + enable-method = "psci"; + };
This is going to take up an awful lot of space. Perhaps we should follwo ePAPR and allow for common properties to go in /cpus (as I believe we do for arm). We might not be able to do that for device_type given how we detect CPU nodes at present, but we could certainly do it for the enable-method:
---->8----
arch/arm64/kernel/cpu_ops.c +12 -1
@@ -54,7 +54,18 @@ static const struct cpu_operations * __init cpu_get_ops(const char *name)*/ int __init cpu_read_ops (struct device_node *dn,int cpu) { -const char *enable_method =of_get_property (dn,"enable-method" ,NULL ); +const char *enable_method =NULL ; +of_property_read_string (dn,"enable-method" , &enable_method); + +if (!enable_method) { +/* +* Perhaps we have a common /cpus/enable-method +*/ +struct device_node *cpus =of_get_parent (dn); +of_property_read_string (cpus,"enable-method" , &enable_method); +of_node_put (cpus); + } +if (!enable_method) {/* * The boot CPU may not have an enable method (e.g. when
---->8----
I don't believe we check the compatible string at the moment, so that should be safe to make common too.
Mark.
RFC PATCH 4/4 arm64:numa: adding numa support for arm64 platforms.
In reply to Ganapatrao KulkarniAdding numa support for arm64 based platforms.
This version creates numa mapping by parsing the dt table. cpu to node id mapping is derived from cluster_id as defined in cpu-map. memory to node id mapping is derived from nid property of memory node.
--- arch/arm64/Kconfig | 33 +++ arch/arm64/include/asm/mmzone.h | 32 +++ arch/arm64/include/asm/numa.h | 41 ++++ arch/arm64/kernel/setup.c | 8 + arch/arm64/kernel/smp.c | 2 + arch/arm64/mm/Makefile | 1 + arch/arm64/mm/init.c | 33 ++- arch/arm64/mm/numa.c | 471 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 617 insertions(+), 4 deletions(-) create mode 100644 arch/arm64/include/asm/mmzone.h create mode 100644 arch/arm64/include/asm/numa.h create mode 100644 arch/arm64/mm/numa.c
arch/arm64/Kconfig +33 -0
@@ -142,6 +142,7 @@ config ARCH_THUNDER select NET_VENDOR_CAVIUM select SATA_AHCI select SATA_AHCI_PLATFORM + select HAVE_MEMBLOCK_NODE_MAP if NUMA config ARCH_VEXPRESS bool "ARMv8 software model (Versatile Express)"
@@ -309,6 +310,38 @@ config HOTPLUG_CPU Say Y here to experiment with turning CPUs off and on. CPUs can be controlled through /sys/devices/system/cpu. +# Common NUMA Features +config NUMA + bool "Numa Memory Allocation and Scheduler Support" + depends on SMP + ---help--- + Enable NUMA (Non Uniform Memory Access) support. + + The kernel will try to allocate memory used by a CPU on the + local memory controller of the CPU and add some more + NUMA awareness to the kernel. + +config ARM64_DT_NUMA + def_bool y + prompt "DT NUMA detection" + depends on ARM64 && NUMA && DTC + ---help--- + Enable DT based numa. + +config NODES_SHIFT + int "Maximum NUMA Nodes (as a power of 2)" + range 1 10 + default "2" + depends on NEED_MULTIPLE_NODES + ---help--- + Specify the maximum number of NUMA Nodes available on the target + system. Increases memory reserved to accommodate various tables. + +config USE_PERCPU_NUMA_NODE_ID + def_bool y + depends on NUMA + + source kernel/Kconfig.preempt config HZ
arch/arm64/include/asm/mmzone.h new file +32 -0
@@ -0,0 +1,32 @@ +#ifndef __ASM_ARM64_MMZONE_H_ +#define __ASM_ARM64_MMZONE_H_ + +#ifdef CONFIG_NUMA + +#include <linux/mmdebug.h> +#include <asm/smp.h> +#include <linux/types.h> +#include <asm/numa.h> + +extern struct pglist_data *node_data[]; + +#define NODE_DATA (nid) (node_data[nid]) + + +struct numa_memblk { +u64 start; +u64 end; +int nid; +}; + +struct numa_meminfo { +int nr_blks; +struct numa_memblk blk[NR_NODE_MEMBLKS ]; +}; + +void __init numa_remove_memblk_from (int idx,struct numa_meminfo *mi); +int __init numa_cleanup_meminfo (struct numa_meminfo *mi); +void __init numa_reset_distance (void ); + +#endif /* CONFIG_NUMA */ +#endif /* __ASM_ARM64_MMZONE_H_ */
arch/arm64/include/asm/numa.h new file +41 -0
41 lines not on this page · raw message
arch/arm64/kernel/setup.c +8 -0
@@ -424,6 +424,9 @@ static int __init topology_init(void) {int i; +for_each_online_node (i) +register_one_node (i); +for_each_possible_cpu (i) {struct cpu *cpu = &per_cpu (cpu_data.cpu, i); cpu->hotpluggable =1 ;
@@ -460,7 +463,12 @@ static int c_show(struct seq_file *m, void *v)* "processor". Give glibc what it expects. */ #ifdef CONFIG_SMP +if (IS_ENABLED (CONFIG_NUMA )) { +seq_printf (m,"processor\t: %d" , i); +seq_printf (m," [nid: %d]\n" ,cpu_to_node (i)); + }else {seq_printf (m,"processor\t: %d\n" , i); + }#endif }
arch/arm64/kernel/smp.c +2 -0
@@ -50,6 +50,7 @@#include <asm/sections.h> #include <asm/tlbflush.h> #include <asm/ptrace.h> +#include <asm/numa.h> #define CREATE_TRACE_POINTS #include <trace/events/ipi.h>
@@ -123,6 +124,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)static void smp_store_cpu_info (unsigned int cpuid) {store_cpu_topology (cpuid); +numa_store_cpu_info (cpuid); }/*
arch/arm64/mm/Makefile +1 -0
@@ -3,3 +3,4 @@ obj-y := dma-mapping.o extable.o fault.o init.o \ ioremap.o mmap.o pgd.o mmu.o \ context.o proc.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o +obj-$(CONFIG_NUMA) += numa.o
arch/arm64/mm/init.c +29 -4
@@ -39,6 +39,7 @@#include <asm/setup.h> #include <asm/sizes.h> #include <asm/tlb.h> +#include <asm/numa.h> #include "mm.h"
@@ -73,6 +74,20 @@ static phys_addr_t max_zone_dma_phys(void)return min (offset + (1ULL <<32 ),memblock_end_of_DRAM ()); } +#ifdef CONFIG_NUMA +static void __init zone_sizes_init (unsigned long min,unsigned long max) +{ +unsigned long max_zone_pfns[MAX_NR_ZONES ]; + +memset (max_zone_pfns,0 ,sizeof (max_zone_pfns)); +if (IS_ENABLED (CONFIG_ZONE_DMA )) + max_zone_pfns[ZONE_DMA ] =PFN_DOWN (max_zone_dma_phys ()); + max_zone_pfns[ZONE_NORMAL ] = max; + +free_area_init_nodes (max_zone_pfns); +} + +#else static void __init zone_sizes_init (unsigned long min,unsigned long max) {struct memblock_region *reg;
@@ -111,6 +126,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) free_area_init_node(0, zone_size, min, zhole_size); } +#endif /* CONFIG_NUMA */ #ifdef CONFIG_HAVE_ARCH_PFN_VALID int pfn_valid (unsigned long pfn)
@@ -129,9 +145,16 @@ static void arm64_memory_present(void) {struct memblock_region *reg; -for_each_memblock (memory, reg) +for_each_memblock (memory, reg) { +#ifdef CONFIG_NUMA +memory_present (reg->nid, +memblock_region_memory_base_pfn (reg), +memblock_region_memory_end_pfn (reg)); +#else memory_present (0 ,memblock_region_memory_base_pfn (reg),memblock_region_memory_end_pfn (reg)); +#endif + } }#endif
@@ -168,6 +191,11 @@ void __init bootmem_init(void) min =PFN_UP (memblock_start_of_DRAM ()); max =PFN_DOWN (memblock_end_of_DRAM ()); + high_memory =__va ((max <<PAGE_SHIFT ) -1 ) +1 ; + max_pfn = max_low_pfn = max; + +if (IS_ENABLED (CONFIG_NUMA )) +arm64_numa_init ();/* * Sparsemem tries to allocate bootmem in memory_present(), so must be * done after the fixed reservations.
@@ -176,9 +204,6 @@ void __init bootmem_init(void)sparse_init ();zone_sizes_init (min, max); - - high_memory =__va ((max <<PAGE_SHIFT ) -1 ) +1 ; - max_pfn = max_low_pfn = max; }#ifndef CONFIG_SPARSEMEM_VMEMMAP
arch/arm64/mm/numa.c new file +469 -0
469 lines not on this page · raw message
Signature · 1 line
1.8.1.4
Mark Rutland
reviewerRFC PATCH 4/4 arm64:numa: adding numa support for arm64 platforms.
Quoted 4 lines · Ganapatrao Kulkarni
Adding numa support for arm64 based platforms.
This version creates numa mapping by parsing the dt table. cpu to node id mapping is derived fromcluster_idas defined in cpu-map. memory to node id mapping is derived from nid property of memory node.
[...]
arch/arm64/include/asm/numa.h line 17
Quoted 6 lines
arch/arm64/include/asm/numa.h new file +6
-0+/* +* Too small node sizes may confuse the VM badly. Usually they +* result from BIOS bugs. So dont recognize nodes as standalone +* NUMA entities that have less than this amount of RAM listed: +*/ +#define NODE_MIN_SIZE (4*1024*1024)
Why do these confuse the VM? what does BIOS have to do with arm64?
Review
Quoted 2 lines
(quoted diff) +2
-0+ +#define parent_node(node) (node)
Huh?
[...]
arch/arm64/mm/init.c void __init bootmem_init(void) · line 198
Quoted 9 lines
arch/arm64/mm/init.c +5
-0@@ -168,6 +191,11 @@ void __init bootmem_init(void) min =PFN_UP (memblock_start_of_DRAM ()); max =PFN_DOWN (memblock_end_of_DRAM ()); + high_memory =__va ((max <<PAGE_SHIFT ) -1 ) +1 ; + max_pfn = max_low_pfn = max; + +if (IS_ENABLED (CONFIG_NUMA )) +arm64_numa_init ();
Is this function defined if !CONFIG_NUMA? Surely it must do nothing in that case anyway?
[...]
arch/arm64/mm/numa.c line 117
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+/* +* Set the cpu to node and mem mapping +*/ +void numa_store_cpu_info (cpu ) +{ + cpu_to_node_map[cpu] = cpu_topology[cpu].cluster_id; +cpumask_set_cpu (cpu, node_to_cpumask_map[cpu_to_node_map[cpu]]); +set_numa_node (cpu_to_node_map[cpu]); +set_numa_mem (local_memory_node (cpu_to_node_map[cpu])); +}
I don't like this. I think we need to be more explicit in the DT w.r.t. the relationship between memory and the CPU hierarchy.
I can imagine that we might end up with systems with multiple levels of NUMA hierarchy (using MPIDR_EL1.Aff{3,2}), and I'd rather that we were explcit as possible from the start w.r.t. the relationship between memory and groups of CPUs such that we don't end up with multiple ways of specifying said relationship, and horrible edge cases around implicit definitions (e.g. the nid to cluster mapping).
arch/arm64/mm/numa.c line 386
Quoted 13 lines
arch/arm64/mm/numa.c new file +13
-0+/** +* dummy_numa_init - Fallback dummy NUMA init +* +* Used if there's no underlying NUMA architecture, NUMA initialization +* fails, or NUMA is disabled on the command line. +* +* Must online at least one node and add memory blocks that cover all +* allowed memory. This function must not fail. +*/ +static int __init dummy_numa_init (void ) +{ +pr_info ("%s\n" , + numa_off ?"NUMA turned off" :"No NUMA configuration found" );
Why not print "NUMA turned off" in numa_setup?
Quoted 17 lines
arch/arm64/mm/numa.c new file +17
-0+pr_info ("Faking a node at [mem %#018Lx-%#018Lx]\n" , +0LLU ,PFN_PHYS (max_pfn) -1 ); + +node_set (0 , numa_nodes_parsed); +numa_add_memblk (0 ,0 ,PFN_PHYS (max_pfn)); + +return 0 ; +} + +/** +* early_init_dt_scan_numa_map - parse memory node and map nid to memory range. +*/ +int __init early_init_dt_scan_numa_map (unsigned long node,const char *uname, +int depth,void *data) +{ +const char *type =of_get_flat_dt_prop (node,"device_type" ,NULL ); +const __be32 *reg, *endp, *nid_prop;
arch/arm64/mm/numa.c line 413
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+int l, nid; + +/* We are scanning "memory" nodes only */ +if (type ==NULL ) { +/* +* The longtrail doesn't have a device_type on the +* /memory node, so look for the node called /memory at 0. +*/ +if (depth !=1 ||strcmp (uname,"memory at 0" ) !=0 ) +return 0 ;
This has no place on arm64.
We limited to longtrail workaround in the core memory parsing to PPC32 only in commit b44aa25d20e2ef6b (of: Handle memory at 0 node on PPC32 only). This code doesn't need it enabled ever.
Are you booting using UEFI? This isn't going to work when the memory map comes from UEFI and we have no memory nodes in the DTB.
Mark.
RFC PATCH 4/4 arm64:numa: adding numa support for arm64 platforms.
Hi Mark,
Quoted 8 lines · Mark Rutland
Quoted 4 lines · Ganapatrao Kulkarni
Adding numa support for arm64 based platforms.
This version creates numa mapping by parsing the dt table. cpu to node id mapping is derived fromcluster_idas defined in cpu-map. memory to node id mapping is derived from nid property of memory node.[...]
Quoted 8 lines
arch/arm64/include/asm/numa.h line 17
Quoted 6 lines
arch/arm64/include/asm/numa.h new file +6
-0+/* +* Too small node sizes may confuse the VM badly. Usually they +* result from BIOS bugs. So dont recognize nodes as standalone +* NUMA entities that have less than this amount of RAM listed: +*/ +#define NODE_MIN_SIZE (4*1024*1024)Why do these confuse the VM? what does BIOS have to do with arm64?
sneaked in from x86, will remove this.
Quoted 5 lines
Review
Quoted 3 lines
(quoted diff) +2
-0+ +#define parent_node(node) (node)Huh?
for thunder, no hierarchy at numa nodes. shall i put under ifdef or separate header file?
Quoted 7 lines
[...]
Quoted 4 lines
arch/arm64/mm/init.c +0
-0@@ -168,6 +191,11 @@ void __init bootmem_init(void) min =PFN_UP (memblock_start_of_DRAM ()); max =PFN_DOWN (memblock_end_of_DRAM ());
Quoted 8 lines
arch/arm64/mm/init.c void __init bootmem_init(void) · line 198
Quoted 5 lines
arch/arm64/mm/init.c +5
-0+ high_memory =__va ((max <<PAGE_SHIFT ) -1 ) +1 ; + max_pfn = max_low_pfn = max; + +if (IS_ENABLED (CONFIG_NUMA )) +arm64_numa_init ();Is this function defined if !CONFIG_NUMA? Surely it must do nothing in that case anyway?
yes, if is not required, will remove it.
Quoted 17 lines
[...]
arch/arm64/mm/numa.c line 117
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+/* +* Set the cpu to node and mem mapping +*/ +void numa_store_cpu_info (cpu ) +{ + cpu_to_node_map[cpu] = cpu_topology[cpu].cluster_id; +cpumask_set_cpu (cpu, node_to_cpumask_map[cpu_to_node_map[cpu]]); +set_numa_node (cpu_to_node_map[cpu]); +set_numa_mem (local_memory_node (cpu_to_node_map[cpu])); +}I don't like this. I think we need to be more explicit in the DT w.r.t. the relationship between memory and the CPU hierarchy.
Quoted 6 lines
I can imagine that we might end up with systems with multiple levels of NUMA hierarchy (using MPIDR_EL1.Aff{3,2}), and I'd rather that we were explcit as possible from the start w.r.t. the relationship between memory and groups of CPUs such that we don't end up with multiple ways of specifying said relationship, and horrible edge cases around implicit definitions (e.g. the nid to cluster mapping).
are you recomending to have explicit nid attribute to each cpu device node?
Quoted 16 lines
Quoted 4 lines
arch/arm64/mm/numa.c new file +3
-0+/** +* dummy_numa_init - Fallback dummy NUMA init +* arch/arm64/mm/numa.c line 386
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+* Used if there's no underlying NUMA architecture, NUMA initialization +* fails, or NUMA is disabled on the command line. +* +* Must online at least one node and add memory blocks that cover all +* allowed memory. This function must not fail. +*/ +static int __init dummy_numa_init (void ) +{ +pr_info ("%s\n" , + numa_off ?"NUMA turned off" :"No NUMA configuration found" );Why not print "NUMA turned off" in
numa_setup?
enters this function only when, numa is turned off or the DT/ACPI based numa init fails.
Quoted 22 lines
Quoted 22 lines
arch/arm64/mm/numa.c new file +21
-0+pr_info ("Faking a node at [mem %#018Lx-%#018Lx]\n" , +0LLU ,PFN_PHYS (max_pfn) -1 ); + +node_set (0 , numa_nodes_parsed); +numa_add_memblk (0 ,0 ,PFN_PHYS (max_pfn)); + +return 0 ; +} + +/** +* early_init_dt_scan_numa_map - parse memory node and map nid to memory range. +*/ +int __init early_init_dt_scan_numa_map (unsigned long node,const char *uname, +int depth,void *data) +{ +const char *type =of_get_flat_dt_prop (node,"device_type" ,NULL ); +const __be32 *reg, *endp, *nid_prop; +int l, nid; + +/* We are scanning "memory" nodes only */ +if (type ==NULL ) {
Quoted 8 lines
arch/arm64/mm/numa.c line 413
Quoted 6 lines
arch/arm64/mm/numa.c new file +6
-0+/* +* The longtrail doesn't have a device_type on the +* /memory node, so look for the node called /memory at 0. +*/ +if (depth !=1 ||strcmp (uname,"memory at 0" ) !=0 ) +return 0 ;This has no place on arm64.
i am not sure that we can move to driver/of, at this moment this is arm64 specific binding.
Quoted 6 lines
We limited to longtrail workaround in the core memory parsing to PPC32 only in commit
b44aa25d20e2ef6b(of: Handle memory at 0 node on PPC32 only). This code doesn't need it enabled ever.Are you booting using UEFI? This isn't going to work when the memory map
tried with bootwrapper, working on to boot from UEFI.
Quoted 1 line
comes from UEFI and we have no memory nodes in the DTB.
yes, there is issue with UEFI boot, since memory node is removed. i request UEFI stub dev-team to suggest the possible ways to address this.
Quoted 2 lines
Mark.
thanks
ganapat
Mark Rutland
reviewerRFC PATCH 4/4 arm64:numa: adding numa support for arm64 platforms.
Quoted 19 lines · Ganapatrao Kulkarni
Hi Mark,
Quoted 8 lines · Mark Rutland
Quoted 4 lines · Ganapatrao Kulkarni
Adding numa support for arm64 based platforms.
This version creates numa mapping by parsing the dt table. cpu to node id mapping is derived fromcluster_idas defined in cpu-map. memory to node id mapping is derived from nid property of memory node.[...]
Quoted 8 lines
arch/arm64/include/asm/numa.h line 17
Quoted 6 lines
arch/arm64/include/asm/numa.h new file +6
-0+/* +* Too small node sizes may confuse the VM badly. Usually they +* result from BIOS bugs. So dont recognize nodes as standalone +* NUMA entities that have less than this amount of RAM listed: +*/ +#define NODE_MIN_SIZE (4*1024*1024)Why do these confuse the VM? what does BIOS have to do with arm64?
Quoted 8 lines
sneaked in from x86, will remove this.
Quoted 5 lines
Review
Quoted 3 lines
(quoted diff) +2
-0+ +#define parent_node(node) (node)Huh?
for thunder, no hierarchy at numa nodes. shall i put under ifdef or separate header file?
I was confused by a node being its own parent, but that seems to be the case elsewhere for parent_node() implementations. Please at least have a comment that we're assuming a flat hierarchy (for now).
Quoted 33 lines
Quoted 7 lines
[...]
Quoted 4 lines
arch/arm64/mm/init.c +0
-0@@ -168,6 +191,11 @@ void __init bootmem_init(void) min =PFN_UP (memblock_start_of_DRAM ()); max =PFN_DOWN (memblock_end_of_DRAM ());Quoted 8 lines
arch/arm64/mm/init.c void __init bootmem_init(void) · line 198
Quoted 5 lines
arch/arm64/mm/init.c +5
-0+ high_memory =__va ((max <<PAGE_SHIFT ) -1 ) +1 ; + max_pfn = max_low_pfn = max; + +if (IS_ENABLED (CONFIG_NUMA )) +arm64_numa_init ();Is this function defined if !CONFIG_NUMA? Surely it must do nothing in that case anyway?
yes, if is not required, will remove it.
Quoted 17 lines
[...]
arch/arm64/mm/numa.c line 117
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+/* +* Set the cpu to node and mem mapping +*/ +void numa_store_cpu_info (cpu ) +{ + cpu_to_node_map[cpu] = cpu_topology[cpu].cluster_id; +cpumask_set_cpu (cpu, node_to_cpumask_map[cpu_to_node_map[cpu]]); +set_numa_node (cpu_to_node_map[cpu]); +set_numa_mem (local_memory_node (cpu_to_node_map[cpu])); +}I don't like this. I think we need to be more explicit in the DT w.r.t. the relationship between memory and the CPU hierarchy.
Quoted 7 lines
Quoted 6 lines
I can imagine that we might end up with systems with multiple levels of NUMA hierarchy (using MPIDR_EL1.Aff{3,2}), and I'd rather that we were explcit as possible from the start w.r.t. the relationship between memory and groups of CPUs such that we don't end up with multiple ways of specifying said relationship, and horrible edge cases around implicit definitions (e.g. the nid to cluster mapping).
are you recomending to have explicit nid attribute to each cpu device node?
I am recommending that we make the relationship explicit. If anything, using the cpu-map (with phandles) seems like a better approach.
Quoted 15 lines
Quoted 7 lines
Quoted 7 lines
+/**
+ *dummy_numa_init- Fallback dummy NUMA init
+ *
+ * Used if there's no underlying NUMA architecture, NUMA initialization
+ * fails, or NUMA is disabled on the command line.
+ *
+ * Must online at least one node and add memory blocks that cover allQuoted 8 lines
arch/arm64/mm/numa.c line 386
Quoted 6 lines
+ * allowed memory. This function must not fail.
+ */arch/arm64/mm/numa.c new file +4
-0+static int __init dummy_numa_init (void ) +{ +pr_info ("%s\n" , + numa_off ?"NUMA turned off" :"No NUMA configuration found" );Why not print "NUMA turned off" in
numa_setup?
Quoted 2 lines
enters this function only when, numa is turned off or the DT/ACPI based numa init fails.
Sure. Moving the "NUMA turned off" print into numa_setup would mean you could just print "Using dummy NUMA layout" or something to that effect here -- the function has no need to care about the value of numa_off.
Quoted 30 lines
Quoted 22 lines
Quoted 22 lines
arch/arm64/mm/numa.c new file +21
-0+pr_info ("Faking a node at [mem %#018Lx-%#018Lx]\n" , +0LLU ,PFN_PHYS (max_pfn) -1 ); + +node_set (0 , numa_nodes_parsed); +numa_add_memblk (0 ,0 ,PFN_PHYS (max_pfn)); + +return 0 ; +} + +/** +* early_init_dt_scan_numa_map - parse memory node and map nid to memory range. +*/ +int __init early_init_dt_scan_numa_map (unsigned long node,const char *uname, +int depth,void *data) +{ +const char *type =of_get_flat_dt_prop (node,"device_type" ,NULL ); +const __be32 *reg, *endp, *nid_prop; +int l, nid; + +/* We are scanning "memory" nodes only */ +if (type ==NULL ) {Quoted 8 lines
arch/arm64/mm/numa.c line 413
Quoted 6 lines
arch/arm64/mm/numa.c new file +6
-0+/* +* The longtrail doesn't have a device_type on the +* /memory node, so look for the node called /memory at 0. +*/ +if (depth !=1 ||strcmp (uname,"memory at 0" ) !=0 ) +return 0 ;This has no place on arm64.
Quoted 2 lines
i am not sure that we can move to driver/of, at this moment this is arm64 specific binding.
I meant the longtrail workaround, hence my comments on that below.
Quoted 9 lines
Quoted 5 lines
We limited to longtrail workaround in the core memory parsing to PPC32 only in commit
b44aa25d20e2ef6b(of: Handle memory at 0 node on PPC32 only). This code doesn't need it enabled ever.Are you booting using UEFI? This isn't going to work when the memory map
tried with bootwrapper, working on to boot from UEFI.
Quoted 1 line
comes from UEFI and we have no memory nodes in the DTB.
yes, there is issue with UEFI boot, since memory node is removed. i request UEFI stub dev-team to suggest the possible ways to address this.
I've Cc'd a few people who have worked on the stub and/or EFI memory map stuff. It would be worth keeping them on Cc so as to keep them informed.
I believe that the EFI stub is doing the right thing by ensuring that the EFI memory map is used, so this is just another configuration that your binding has to consider.
Mark.
RFC PATCH 4/4 arm64:numa: adding numa support for arm64 platforms.
Quoted 26 lines · Mark Rutland
Quoted 25 lines · Ganapatrao Kulkarni
Hi Mark,
Quoted 8 lines · Mark Rutland
Quoted 4 lines · Ganapatrao Kulkarni
Adding numa support for arm64 based platforms.
This version creates numa mapping by parsing the dt table. cpu to node id mapping is derived fromcluster_idas defined in cpu-map. memory to node id mapping is derived from nid property of memory node.[...]
Quoted 8 lines
arch/arm64/include/asm/numa.h line 17
Quoted 6 lines
arch/arm64/include/asm/numa.h new file +6
-0+/* +* Too small node sizes may confuse the VM badly. Usually they +* result from BIOS bugs. So dont recognize nodes as standalone +* NUMA entities that have less than this amount of RAM listed: +*/ +#define NODE_MIN_SIZE (4*1024*1024)Why do these confuse the VM? what does BIOS have to do with arm64?
sneaked in from x86, will remove this.
Quoted 5 lines
Review
Quoted 3 lines
(quoted diff) +2
-0+ +#define parent_node(node) (node)Huh?
Quoted 6 lines
Quoted 2 lines
for thunder, no hierarchy at numa nodes. shall i put under ifdef or separate header file?
I was confused by a node being its own parent, but that seems to be the case elsewhere for
parent_node()implementations. Please at least have a comment that we're assuming a flat hierarchy (for now).
sure, will add the required comments.
Quoted 40 lines
Quoted 40 lines
Quoted 8 lines
[...]
Quoted 4 lines
arch/arm64/mm/init.c +0
-0@@ -168,6 +191,11 @@ void __init bootmem_init(void) min =PFN_UP (memblock_start_of_DRAM ()); max =PFN_DOWN (memblock_end_of_DRAM ());Quoted 8 lines
arch/arm64/mm/init.c void __init bootmem_init(void) · line 198
Quoted 5 lines
arch/arm64/mm/init.c +5
-0+ high_memory =__va ((max <<PAGE_SHIFT ) -1 ) +1 ; + max_pfn = max_low_pfn = max; + +if (IS_ENABLED (CONFIG_NUMA )) +arm64_numa_init ();Is this function defined if !CONFIG_NUMA? Surely it must do nothing in that case anyway?
yes, if is not required, will remove it.
Quoted 23 lines
[...]
arch/arm64/mm/numa.c line 117
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+/* +* Set the cpu to node and mem mapping +*/ +void numa_store_cpu_info (cpu ) +{ + cpu_to_node_map[cpu] = cpu_topology[cpu].cluster_id; +cpumask_set_cpu (cpu, node_to_cpumask_map[cpu_to_node_map[cpu]]); +set_numa_node (cpu_to_node_map[cpu]); +set_numa_mem (local_memory_node (cpu_to_node_map[cpu])); +}I don't like this. I think we need to be more explicit in the DT w.r.t. the relationship between memory and the CPU hierarchy.
I can imagine that we might end up with systems with multiple levels of NUMA hierarchy (using MPIDR_EL1.Aff{3,2}), and I'd rather that we were explcit as possible from the start w.r.t. the relationship between memory and groups of CPUs such that we don't end up with multiple ways of specifying said relationship, and horrible edge cases around implicit definitions (e.g. the nid to cluster mapping).
Quoted 4 lines
Quoted 1 line
are you recomending to have explicit nid attribute to each cpu device node?
I am recommending that we make the relationship explicit. If anything, using the cpu-map (with phandles) seems like a better approach.
yes, will add the mapping.
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
Quoted 4 lines
arch/arm64/mm/numa.c new file +3
-0+/** +* dummy_numa_init - Fallback dummy NUMA init +* arch/arm64/mm/numa.c line 386
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+* Used if there's no underlying NUMA architecture, NUMA initialization +* fails, or NUMA is disabled on the command line. +* +* Must online at least one node and add memory blocks that cover all +* allowed memory. This function must not fail. +*/ +static int __init dummy_numa_init (void ) +{ +pr_info ("%s\n" , + numa_off ?"NUMA turned off" :"No NUMA configuration found" );Why not print "NUMA turned off" in
numa_setup?
Quoted 6 lines
Quoted 2 lines
enters this function only when, numa is turned off or the DT/ACPI based numa init fails.
Sure. Moving the "NUMA turned off" print into
numa_setupwould mean you could just print "Using dummy NUMA layout" or something to that effect here -- the function has no need to care about the value ofnuma_off.
agreed.
Quoted 31 lines
Quoted 31 lines
Quoted 31 lines
Quoted 19 lines
arch/arm64/mm/numa.c new file +17
-0+pr_info ("Faking a node at [mem %#018Lx-%#018Lx]\n" , +0LLU ,PFN_PHYS (max_pfn) -1 ); + +node_set (0 , numa_nodes_parsed); +numa_add_memblk (0 ,0 ,PFN_PHYS (max_pfn)); + +return 0 ; +} + +/** +* early_init_dt_scan_numa_map - parse memory node and map nid to memory range. +*/ +int __init early_init_dt_scan_numa_map (unsigned long node,const char *uname, +int depth,void *data) +{ +const char *type =of_get_flat_dt_prop (node,"device_type" ,NULL ); +const __be32 *reg, *endp, *nid_prop;arch/arm64/mm/numa.c line 413
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+int l, nid; + +/* We are scanning "memory" nodes only */ +if (type ==NULL ) { +/* +* The longtrail doesn't have a device_type on the +* /memory node, so look for the node called /memory at 0. +*/ +if (depth !=1 ||strcmp (uname,"memory at 0" ) !=0 ) +return 0 ;This has no place on arm64.
Quoted 4 lines
Quoted 2 lines
i am not sure that we can move to driver/of, at this moment this is arm64 specific binding.
I meant the longtrail workaround, hence my comments on that below.
oh! thanks, will remove this.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
We limited to longtrail workaround in the core memory parsing to PPC32 only in commit
b44aa25d20e2ef6b(of: Handle memory at 0 node on PPC32 only). This code doesn't need it enabled ever.
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
Are you booting using UEFI? This isn't going to work when the memory map
tried with bootwrapper, working on to boot from UEFI.
Quoted 1 line
comes from UEFI and we have no memory nodes in the DTB.
yes, there is issue with UEFI boot, since memory node is removed. i request UEFI stub dev-team to suggest the possible ways to address this.
I've Cc'd a few people who have worked on the stub and/or EFI memory map stuff. It would be worth keeping them on Cc so as to keep them informed.
thanks.
Quoted 4 lines
I believe that the EFI stub is doing the right thing by ensuring that the EFI memory map is used, so this is just another configuration that your binding has to consider.
going through EFI stub, next is to boot numa kernel using UEFI, will include UEFI boot support in v2 patch.
Quoted 2 lines
Mark.
RFC PATCH 4/4 arm64:numa: adding numa support for arm64 platforms.
Hi All,
Quoted 151 lines · Ganapatrao Kulkarni
Quoted 26 lines · Mark Rutland
Quoted 25 lines · Ganapatrao Kulkarni
Hi Mark,
Quoted 8 lines · Mark Rutland
Quoted 4 lines · Ganapatrao Kulkarni
Adding numa support for arm64 based platforms.
This version creates numa mapping by parsing the dt table. cpu to node id mapping is derived fromcluster_idas defined in cpu-map. memory to node id mapping is derived from nid property of memory node.[...]
Quoted 8 lines
arch/arm64/include/asm/numa.h line 17
Quoted 6 lines
arch/arm64/include/asm/numa.h new file +6
-0+/* +* Too small node sizes may confuse the VM badly. Usually they +* result from BIOS bugs. So dont recognize nodes as standalone +* NUMA entities that have less than this amount of RAM listed: +*/ +#define NODE_MIN_SIZE (4*1024*1024)Why do these confuse the VM? what does BIOS have to do with arm64?
sneaked in from x86, will remove this.
Quoted 5 lines
Review
Quoted 3 lines
(quoted diff) +2
-0+ +#define parent_node(node) (node)Huh?
Quoted 6 lines
Quoted 2 lines
for thunder, no hierarchy at numa nodes. shall i put under ifdef or separate header file?
I was confused by a node being its own parent, but that seems to be the case elsewhere for
parent_node()implementations. Please at least have a comment that we're assuming a flat hierarchy (for now).sure, will add the required comments.
Quoted 40 lines
Quoted 40 lines
Quoted 8 lines
[...]
Quoted 4 lines
arch/arm64/mm/init.c +0
-0@@ -168,6 +191,11 @@ void __init bootmem_init(void) min =PFN_UP (memblock_start_of_DRAM ()); max =PFN_DOWN (memblock_end_of_DRAM ());Quoted 8 lines
arch/arm64/mm/init.c void __init bootmem_init(void) · line 198
Quoted 5 lines
arch/arm64/mm/init.c +5
-0+ high_memory =__va ((max <<PAGE_SHIFT ) -1 ) +1 ; + max_pfn = max_low_pfn = max; + +if (IS_ENABLED (CONFIG_NUMA )) +arm64_numa_init ();Is this function defined if !CONFIG_NUMA? Surely it must do nothing in that case anyway?
yes, if is not required, will remove it.
Quoted 23 lines
[...]
arch/arm64/mm/numa.c line 117
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+/* +* Set the cpu to node and mem mapping +*/ +void numa_store_cpu_info (cpu ) +{ + cpu_to_node_map[cpu] = cpu_topology[cpu].cluster_id; +cpumask_set_cpu (cpu, node_to_cpumask_map[cpu_to_node_map[cpu]]); +set_numa_node (cpu_to_node_map[cpu]); +set_numa_mem (local_memory_node (cpu_to_node_map[cpu])); +}I don't like this. I think we need to be more explicit in the DT w.r.t. the relationship between memory and the CPU hierarchy.
I can imagine that we might end up with systems with multiple levels of NUMA hierarchy (using MPIDR_EL1.Aff{3,2}), and I'd rather that we were explcit as possible from the start w.r.t. the relationship between memory and groups of CPUs such that we don't end up with multiple ways of specifying said relationship, and horrible edge cases around implicit definitions (e.g. the nid to cluster mapping).
Quoted 4 lines
Quoted 1 line
are you recomending to have explicit nid attribute to each cpu device node?
I am recommending that we make the relationship explicit. If anything, using the cpu-map (with phandles) seems like a better approach.
yes, will add the mapping.
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
Quoted 4 lines
arch/arm64/mm/numa.c new file +3
-0+/** +* dummy_numa_init - Fallback dummy NUMA init +* arch/arm64/mm/numa.c line 386
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+* Used if there's no underlying NUMA architecture, NUMA initialization +* fails, or NUMA is disabled on the command line. +* +* Must online at least one node and add memory blocks that cover all +* allowed memory. This function must not fail. +*/ +static int __init dummy_numa_init (void ) +{ +pr_info ("%s\n" , + numa_off ?"NUMA turned off" :"No NUMA configuration found" );Why not print "NUMA turned off" in
numa_setup?Quoted 6 lines
Quoted 2 lines
enters this function only when, numa is turned off or the DT/ACPI based numa init fails.
Sure. Moving the "NUMA turned off" print into
numa_setupwould mean you could just print "Using dummy NUMA layout" or something to that effect here -- the function has no need to care about the value ofnuma_off.agreed.
Quoted 31 lines
Quoted 31 lines
Quoted 31 lines
Quoted 19 lines
arch/arm64/mm/numa.c new file +17
-0+pr_info ("Faking a node at [mem %#018Lx-%#018Lx]\n" , +0LLU ,PFN_PHYS (max_pfn) -1 ); + +node_set (0 , numa_nodes_parsed); +numa_add_memblk (0 ,0 ,PFN_PHYS (max_pfn)); + +return 0 ; +} + +/** +* early_init_dt_scan_numa_map - parse memory node and map nid to memory range. +*/ +int __init early_init_dt_scan_numa_map (unsigned long node,const char *uname, +int depth,void *data) +{ +const char *type =of_get_flat_dt_prop (node,"device_type" ,NULL ); +const __be32 *reg, *endp, *nid_prop;arch/arm64/mm/numa.c line 413
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+int l, nid; + +/* We are scanning "memory" nodes only */ +if (type ==NULL ) { +/* +* The longtrail doesn't have a device_type on the +* /memory node, so look for the node called /memory at 0. +*/ +if (depth !=1 ||strcmp (uname,"memory at 0" ) !=0 ) +return 0 ;This has no place on arm64.
Quoted 4 lines
Quoted 2 lines
i am not sure that we can move to driver/of, at this moment this is arm64 specific binding.
I meant the longtrail workaround, hence my comments on that below.
oh! thanks, will remove this.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
We limited to longtrail workaround in the core memory parsing to PPC32 only in commit
b44aa25d20e2ef6b(of: Handle memory at 0 node on PPC32 only). This code doesn't need it enabled ever.Quoted 8 lines
Quoted 5 lines
Quoted 1 line
Are you booting using UEFI? This isn't going to work when the memory map
tried with bootwrapper, working on to boot from UEFI.
Quoted 1 line
comes from UEFI and we have no memory nodes in the DTB.
yes, there is issue with UEFI boot, since memory node is removed. i request UEFI stub dev-team to suggest the possible ways to address this.
I've Cc'd a few people who have worked on the stub and/or EFI memory map stuff. It would be worth keeping them on Cc so as to keep them informed.
Quoted 9 lines
thanks.
Quoted 4 lines
I believe that the EFI stub is doing the right thing by ensuring that the EFI memory map is used, so this is just another configuration that your binding has to consider.
going through EFI stub, next is to boot numa kernel using UEFI, will include UEFI boot support in v2 patch.
Quoted 2 lines
Mark.
Below is the example for the proposal of numa bindings in DT. This covers cpu to node mapping, memory ranges to node mapping. Also defines proximity distance matrix of nodes to each other. please let me know your comments to go ahead with the implementation.
numa-map{
/* Address cells used for memory range base address in mem-map.
For all others, size-cells is used.
Node-count tells the number of numa nodes in the system.
*/
#address-cells = <2>;
#size-cells = <1>;
#node-count = <4>;
/* Memmap for memory ranges on each node>
mem-map = <0x0 0x00c00000 0>,
<0x1 0x00000000 1>,
<0x100 0x00000000 2>,
<0x200 0x00000000 3>;
/* CPU to node map for 4 NODE and 16 CPUs system
< first-cpu last-cpu node belongs>
*/
cpu-map = <0 3 0>,
<4 7 1>,
<8 11 2>,
<12 16 3>;
/*Proximity Distance matrix for 4Node system
<from-node to-node distance>
*/
node-matrix= <0 0 10>,
<0 1 20>,
<0 2 30>,
<0 3 10>,
<1 0 20>,
<1 1 10>,
<1 2 30>,
<1 3 10>,
<2 0 30>,
<2 1 20>,
<2 2 10>,
<2 3 10>,
<3 0 10>,
<3 1 20>,
<3 2 30>,
<3 3 10>,}
thanks
Ganapat
RFC PATCH 4/4 arm64:numa: adding numa support for arm64 platforms.
Quoted 212 lines · Ganapatrao Kulkarni
Hi All,
Quoted 151 lines · Ganapatrao Kulkarni
Quoted 26 lines · Mark Rutland
Quoted 25 lines · Ganapatrao Kulkarni
Hi Mark,
Quoted 8 lines · Mark Rutland
Quoted 4 lines · Ganapatrao Kulkarni
Adding numa support for arm64 based platforms.
This version creates numa mapping by parsing the dt table. cpu to node id mapping is derived fromcluster_idas defined in cpu-map. memory to node id mapping is derived from nid property of memory node.[...]
Quoted 8 lines
arch/arm64/include/asm/numa.h line 17
Quoted 6 lines
arch/arm64/include/asm/numa.h new file +6
-0+/* +* Too small node sizes may confuse the VM badly. Usually they +* result from BIOS bugs. So dont recognize nodes as standalone +* NUMA entities that have less than this amount of RAM listed: +*/ +#define NODE_MIN_SIZE (4*1024*1024)Why do these confuse the VM? what does BIOS have to do with arm64?
sneaked in from x86, will remove this.
Quoted 5 lines
Review
Quoted 3 lines
(quoted diff) +2
-0+ +#define parent_node(node) (node)Huh?
Quoted 6 lines
Quoted 2 lines
for thunder, no hierarchy at numa nodes. shall i put under ifdef or separate header file?
I was confused by a node being its own parent, but that seems to be the case elsewhere for
parent_node()implementations. Please at least have a comment that we're assuming a flat hierarchy (for now).sure, will add the required comments.
Quoted 40 lines
Quoted 40 lines
Quoted 8 lines
[...]
Quoted 4 lines
arch/arm64/mm/init.c +0
-0@@ -168,6 +191,11 @@ void __init bootmem_init(void) min =PFN_UP (memblock_start_of_DRAM ()); max =PFN_DOWN (memblock_end_of_DRAM ());Quoted 8 lines
arch/arm64/mm/init.c void __init bootmem_init(void) · line 198
Quoted 5 lines
arch/arm64/mm/init.c +5
-0+ high_memory =__va ((max <<PAGE_SHIFT ) -1 ) +1 ; + max_pfn = max_low_pfn = max; + +if (IS_ENABLED (CONFIG_NUMA )) +arm64_numa_init ();Is this function defined if !CONFIG_NUMA? Surely it must do nothing in that case anyway?
yes, if is not required, will remove it.
Quoted 23 lines
[...]
arch/arm64/mm/numa.c line 117
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+/* +* Set the cpu to node and mem mapping +*/ +void numa_store_cpu_info (cpu ) +{ + cpu_to_node_map[cpu] = cpu_topology[cpu].cluster_id; +cpumask_set_cpu (cpu, node_to_cpumask_map[cpu_to_node_map[cpu]]); +set_numa_node (cpu_to_node_map[cpu]); +set_numa_mem (local_memory_node (cpu_to_node_map[cpu])); +}I don't like this. I think we need to be more explicit in the DT w.r.t. the relationship between memory and the CPU hierarchy.
I can imagine that we might end up with systems with multiple levels of NUMA hierarchy (using MPIDR_EL1.Aff{3,2}), and I'd rather that we were explcit as possible from the start w.r.t. the relationship between memory and groups of CPUs such that we don't end up with multiple ways of specifying said relationship, and horrible edge cases around implicit definitions (e.g. the nid to cluster mapping).
Quoted 4 lines
Quoted 1 line
are you recomending to have explicit nid attribute to each cpu device node?
I am recommending that we make the relationship explicit. If anything, using the cpu-map (with phandles) seems like a better approach.
yes, will add the mapping.
Quoted 16 lines
Quoted 16 lines
Quoted 16 lines
Quoted 4 lines
arch/arm64/mm/numa.c new file +3
-0+/** +* dummy_numa_init - Fallback dummy NUMA init +* arch/arm64/mm/numa.c line 386
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+* Used if there's no underlying NUMA architecture, NUMA initialization +* fails, or NUMA is disabled on the command line. +* +* Must online at least one node and add memory blocks that cover all +* allowed memory. This function must not fail. +*/ +static int __init dummy_numa_init (void ) +{ +pr_info ("%s\n" , + numa_off ?"NUMA turned off" :"No NUMA configuration found" );Why not print "NUMA turned off" in
numa_setup?Quoted 6 lines
Quoted 2 lines
enters this function only when, numa is turned off or the DT/ACPI based numa init fails.
Sure. Moving the "NUMA turned off" print into
numa_setupwould mean you could just print "Using dummy NUMA layout" or something to that effect here -- the function has no need to care about the value ofnuma_off.agreed.
Quoted 31 lines
Quoted 31 lines
Quoted 31 lines
Quoted 19 lines
arch/arm64/mm/numa.c new file +17
-0+pr_info ("Faking a node at [mem %#018Lx-%#018Lx]\n" , +0LLU ,PFN_PHYS (max_pfn) -1 ); + +node_set (0 , numa_nodes_parsed); +numa_add_memblk (0 ,0 ,PFN_PHYS (max_pfn)); + +return 0 ; +} + +/** +* early_init_dt_scan_numa_map - parse memory node and map nid to memory range. +*/ +int __init early_init_dt_scan_numa_map (unsigned long node,const char *uname, +int depth,void *data) +{ +const char *type =of_get_flat_dt_prop (node,"device_type" ,NULL ); +const __be32 *reg, *endp, *nid_prop;arch/arm64/mm/numa.c line 413
Quoted 10 lines
arch/arm64/mm/numa.c new file +10
-0+int l, nid; + +/* We are scanning "memory" nodes only */ +if (type ==NULL ) { +/* +* The longtrail doesn't have a device_type on the +* /memory node, so look for the node called /memory at 0. +*/ +if (depth !=1 ||strcmp (uname,"memory at 0" ) !=0 ) +return 0 ;This has no place on arm64.
Quoted 4 lines
Quoted 2 lines
i am not sure that we can move to driver/of, at this moment this is arm64 specific binding.
I meant the longtrail workaround, hence my comments on that below.
oh! thanks, will remove this.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
We limited to longtrail workaround in the core memory parsing to PPC32 only in commit
b44aa25d20e2ef6b(of: Handle memory at 0 node on PPC32 only). This code doesn't need it enabled ever.Quoted 8 lines
Quoted 5 lines
Quoted 1 line
Are you booting using UEFI? This isn't going to work when the memory map
tried with bootwrapper, working on to boot from UEFI.
Quoted 1 line
comes from UEFI and we have no memory nodes in the DTB.
yes, there is issue with UEFI boot, since memory node is removed. i request UEFI stub dev-team to suggest the possible ways to address this.
I've Cc'd a few people who have worked on the stub and/or EFI memory map stuff. It would be worth keeping them on Cc so as to keep them informed.
Quoted 9 lines
thanks.
Quoted 4 lines
I believe that the EFI stub is doing the right thing by ensuring that the EFI memory map is used, so this is just another configuration that your binding has to consider.
going through EFI stub, next is to boot numa kernel using UEFI, will include UEFI boot support in v2 patch.
Quoted 2 lines
Mark.
Below is the example for the proposal of numa bindings in DT. This covers cpu to node mapping, memory ranges to node mapping. Also defines proximity distance matrix of nodes to each other. please let me know your comments to go ahead with the implementation.
numa-map{ /* Address cells used for memory range base address in mem-map. For all others, size-cells is used. Node-count tells the number of numa nodes in the system. */ #address-cells = <2>; #size-cells = <1>; #node-count = <4>; /* Memmap for memory ranges on each node> mem-map = <0x0 0x00c00000 0>, <0x1 0x00000000 1>, <0x100 0x00000000 2>, <0x200 0x00000000 3>; /* CPU to node map for 4 NODE and 16 CPUs system < first-cpu last-cpu node belongs> */ cpu-map = <0 3 0>, <4 7 1>, <8 11 2>, <12 16 3>; /*Proximity Distance matrix for 4Node system <from-node to-node distance> */ node-matrix= <0 0 10>, <0 1 20>, <0 2 30>, <0 3 10>, <1 0 20>, <1 1 10>, <1 2 30>, <1 3 10>, <2 0 30>, <2 1 20>, <2 2 10>, <2 3 10>, <3 0 10>, <3 1 20>, <3 2 30>, <3 3 10>,
Quoted 1 line
}
Hi Ganapat,
The above caught my attention.
For a 4-node system do we not need 16 distances; the implication of that would be that the distance between node A-B could be different from the distance between B-A? Also the distance from a node to itself could be safely assumed to be zero?
I think we should have a symmetric matrix with zero-diagonals so strictly only seven values would need specifying for a 4-node system.
Cheers,
Signature · 1 line
Steve
RFC PATCH 4/4 arm64:numa: adding numa support for arm64 platforms.
Quoted 1 line · Steve Capper
On Fri, Oct 17, 2014 at 10:49:56PM +0530, Ganapatrao Kulkarni wrote:
[...]
Quoted 24 lines
/*Proximity Distance matrix for 4Node systemQuoted 18 lines
<from-node to-node distance> */ node-matrix= <0 0 10>, <0 1 20>, <0 2 30>, <0 3 10>, <1 0 20>, <1 1 10>, <1 2 30>, <1 3 10>, <2 0 30>, <2 1 20>, <2 2 10>, <2 3 10>, <3 0 10>, <3 1 20>, <3 2 30>, <3 3 10>,Quoted 1 line
}
Hi Ganapat,
The above caught my attention.
Quoted 7 lines
For a 4-node system do we not need 16 distances; the implication of that would be that the distance between node A-B could be different from the distance between B-A? Also the distance from a node to itself could be safely assumed to be zero?
I think we should have a symmetric matrix with zero-diagonals so strictly only seven values would need specifying for a 4-node system.
s/seven/six/
I really need to learn how to count.... :-/
Quoted 4 lines
Cheers,
Signature · 1 line
Steve
RFC PATCH 4/4 arm64:numa: adding numa support for arm64 platforms.
Quoted 29 lines · Steve Capper
Quoted 1 line · Steve Capper
On Fri, Oct 17, 2014 at 10:49:56PM +0530, Ganapatrao Kulkarni wrote:
[...]
Quoted 24 lines
/*Proximity Distance matrix for 4Node systemQuoted 18 lines
<from-node to-node distance> */ node-matrix= <0 0 10>, <0 1 20>, <0 2 30>, <0 3 10>, <1 0 20>, <1 1 10>, <1 2 30>, <1 3 10>, <2 0 30>, <2 1 20>, <2 2 10>, <2 3 10>, <3 0 10>, <3 1 20>, <3 2 30>, <3 3 10>,Quoted 1 line
}
Hi Ganapat,
The above caught my attention.
Quoted 7 lines
Quoted 7 lines
For a 4-node system do we not need 16 distances; the implication of that would be that the distance between node A-B could be different from the distance between B-A? Also the distance from a node to itself could be safely assumed to be zero?
I think we should have a symmetric matrix with zero-diagonals so strictly only seven values would need specifying for a 4-node system.
Thanks Stave for the comments.
I too thought initially to take the assumption like distance B-A is same as A-B and A-A is always defined to LOCAL. However this example is an ideal case which will define all 16 distances for 4 node system.
In actual DT, we can skip to provide A-A and B-A, In kernel implementation we will use these common/generic assumptions to derive missing distances.
Quoted 9 lines
s/seven/six/
I really need to learn how to count.... :-/
Quoted 4 lines
Cheers,
--
Steve
thanks
Ganapat
RFC PATCH 4/4 arm64:numa: adding numa support for arm64 platforms.
In reply to Ganapatrao KulkarniHi Ganapatrao,
On 2014-10-18 1:19, Ganapatrao Kulkarni wrote:
[...]
Quoted 16 lines
Below is the example for the proposal of numa bindings in DT. This covers cpu to node mapping, memory ranges to node mapping. Also defines proximity distance matrix of nodes to each other. please let me know your comments to go ahead with the implementation.
numa-map{ /* Address cells used for memory range base address in mem-map. For all others, size-cells is used. Node-count tells the number of numa nodes in the system. */ #address-cells = <2>; #size-cells = <1>; #node-count = <4>; /* Memmap for memory ranges on each node>
Quoted 7 lines
mem-map = <0x0 0x00c00000 0>,
<0x1 0x00000000 1>,
<0x100 0x00000000 2>,
<0x200 0x00000000 3>;
/* CPU to node map for 4 NODE and 16 CPUs system
< first-cpu last-cpu node belongs>What's the property for the cpu? MPIDR of this CPU?
Quoted 6 lines
*/
cpu-map = <0 3 0>,
<4 7 1>,
<8 11 2>,
<12 16 3>;Thanks
Hanjun
RFC PATCH 4/4 arm64:numa: adding numa support for arm64 platforms.
Hi Hanjun,
Quoted 25 lines · Hanjun Guo
Hi Ganapatrao,
On 2014-10-18 1:19, Ganapatrao Kulkarni wrote:
[...]Quoted 21 lines
Below is the example for the proposal of numa bindings in DT. This covers cpu to node mapping, memory ranges to node mapping. Also defines proximity distance matrix of nodes to each other. please let me know your comments to go ahead with the implementation.
numa-map{ /* Address cells used for memory range base address in mem-map. For all others, size-cells is used. Node-count tells the number of numa nodes in the system. */ #address-cells = <2>; #size-cells = <1>; #node-count = <4>; /* Memmap for memory ranges on each node> mem-map = <0x0 0x00c00000 0>, <0x1 0x00000000 1>, <0x100 0x00000000 2>, <0x200 0x00000000 3>;
Quoted 4 lines
Quoted 2 lines
/* CPU to node map for 4 NODE and 16 CPUs system
< first-cpu last-cpu node belongs>What's the property for the cpu? MPIDR of this CPU?
I see in ACPI spec, there is mapping between logical cpu number to physical id(using MPIDR) using GICC Affinity Structure
Here i am defining mapping between the logical CPUs and the node it belongs. SMP initialization uses CPU node property of DT to bring them up. We can get physical id using cpu_logical_map(cpu), which is MPIDR Do you see any need to expand cpu-map here to have the mapping between physical cpu id and logical cpu id?
Quoted 8 lines
Quoted 7 lines
*/ cpu-map = <0 3 0>, <4 7 1>, <8 11 2>, <12 16 3>;
Quoted 4 lines
Thanks
Hanjun
thanks
ganapat
Quoted 4 lines
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
RFC PATCH 4/4 arm64:numa: adding numa support for arm64 platforms.
In reply to Ganapatrao KulkarniAdding numa support for arm64 based platforms.
This version creates numa mapping by parsing the dt table. cpu to node id mapping is derived from cluster_id as defined in cpu-map. memory to node id mapping is derived from nid property of memory node.
--- arch/arm64/Kconfig | 33 +++ arch/arm64/include/asm/mmzone.h | 32 +++ arch/arm64/include/asm/numa.h | 41 ++++ arch/arm64/kernel/setup.c | 8 + arch/arm64/kernel/smp.c | 2 + arch/arm64/mm/Makefile | 1 + arch/arm64/mm/init.c | 33 ++- arch/arm64/mm/numa.c | 471 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 617 insertions(+), 4 deletions(-) create mode 100644 arch/arm64/include/asm/mmzone.h create mode 100644 arch/arm64/include/asm/numa.h create mode 100644 arch/arm64/mm/numa.c
arch/arm64/Kconfig +33 -0
@@ -142,6 +142,7 @@ config ARCH_THUNDER select NET_VENDOR_CAVIUM select SATA_AHCI select SATA_AHCI_PLATFORM + select HAVE_MEMBLOCK_NODE_MAP if NUMA config ARCH_VEXPRESS bool "ARMv8 software model (Versatile Express)"
@@ -309,6 +310,38 @@ config HOTPLUG_CPU Say Y here to experiment with turning CPUs off and on. CPUs can be controlled through /sys/devices/system/cpu. +# Common NUMA Features +config NUMA + bool "Numa Memory Allocation and Scheduler Support" + depends on SMP + ---help--- + Enable NUMA (Non Uniform Memory Access) support. + + The kernel will try to allocate memory used by a CPU on the + local memory controller of the CPU and add some more + NUMA awareness to the kernel. + +config ARM64_DT_NUMA + def_bool y + prompt "DT NUMA detection" + depends on ARM64 && NUMA && DTC + ---help--- + Enable DT based numa. + +config NODES_SHIFT + int "Maximum NUMA Nodes (as a power of 2)" + range 1 10 + default "2" + depends on NEED_MULTIPLE_NODES + ---help--- + Specify the maximum number of NUMA Nodes available on the target + system. Increases memory reserved to accommodate various tables. + +config USE_PERCPU_NUMA_NODE_ID + def_bool y + depends on NUMA + + source kernel/Kconfig.preempt config HZ
arch/arm64/include/asm/mmzone.h new file +32 -0
@@ -0,0 +1,32 @@ +#ifndef __ASM_ARM64_MMZONE_H_ +#define __ASM_ARM64_MMZONE_H_ + +#ifdef CONFIG_NUMA + +#include <linux/mmdebug.h> +#include <asm/smp.h> +#include <linux/types.h> +#include <asm/numa.h> + +extern struct pglist_data *node_data[]; + +#define NODE_DATA (nid) (node_data[nid]) + + +struct numa_memblk { +u64 start; +u64 end; +int nid; +}; + +struct numa_meminfo { +int nr_blks; +struct numa_memblk blk[NR_NODE_MEMBLKS ]; +}; + +void __init numa_remove_memblk_from (int idx,struct numa_meminfo *mi); +int __init numa_cleanup_meminfo (struct numa_meminfo *mi); +void __init numa_reset_distance (void ); + +#endif /* CONFIG_NUMA */ +#endif /* __ASM_ARM64_MMZONE_H_ */
arch/arm64/include/asm/numa.h new file +41 -0
41 lines not on this page · raw message
arch/arm64/kernel/setup.c +8 -0
@@ -424,6 +424,9 @@ static int __init topology_init(void) {int i; +for_each_online_node (i) +register_one_node (i); +for_each_possible_cpu (i) {struct cpu *cpu = &per_cpu (cpu_data.cpu, i); cpu->hotpluggable =1 ;
@@ -460,7 +463,12 @@ static int c_show(struct seq_file *m, void *v)* "processor". Give glibc what it expects. */ #ifdef CONFIG_SMP +if (IS_ENABLED (CONFIG_NUMA )) { +seq_printf (m,"processor\t: %d" , i); +seq_printf (m," [nid: %d]\n" ,cpu_to_node (i)); + }else {seq_printf (m,"processor\t: %d\n" , i); + }#endif }
arch/arm64/kernel/smp.c +2 -0
@@ -50,6 +50,7 @@#include <asm/sections.h> #include <asm/tlbflush.h> #include <asm/ptrace.h> +#include <asm/numa.h> #define CREATE_TRACE_POINTS #include <trace/events/ipi.h>
@@ -123,6 +124,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)static void smp_store_cpu_info (unsigned int cpuid) {store_cpu_topology (cpuid); +numa_store_cpu_info (cpuid); }/*
arch/arm64/mm/Makefile +1 -0
@@ -3,3 +3,4 @@ obj-y := dma-mapping.o extable.o fault.o init.o \ ioremap.o mmap.o pgd.o mmu.o \ context.o proc.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o +obj-$(CONFIG_NUMA) += numa.o
arch/arm64/mm/init.c +29 -4
@@ -39,6 +39,7 @@#include <asm/setup.h> #include <asm/sizes.h> #include <asm/tlb.h> +#include <asm/numa.h> #include "mm.h"
@@ -73,6 +74,20 @@ static phys_addr_t max_zone_dma_phys(void)return min (offset + (1ULL <<32 ),memblock_end_of_DRAM ()); } +#ifdef CONFIG_NUMA +static void __init zone_sizes_init (unsigned long min,unsigned long max) +{ +unsigned long max_zone_pfns[MAX_NR_ZONES ]; + +memset (max_zone_pfns,0 ,sizeof (max_zone_pfns)); +if (IS_ENABLED (CONFIG_ZONE_DMA )) + max_zone_pfns[ZONE_DMA ] =PFN_DOWN (max_zone_dma_phys ()); + max_zone_pfns[ZONE_NORMAL ] = max; + +free_area_init_nodes (max_zone_pfns); +} + +#else static void __init zone_sizes_init (unsigned long min,unsigned long max) {struct memblock_region *reg;
@@ -111,6 +126,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) free_area_init_node(0, zone_size, min, zhole_size); } +#endif /* CONFIG_NUMA */ #ifdef CONFIG_HAVE_ARCH_PFN_VALID int pfn_valid (unsigned long pfn)
@@ -129,9 +145,16 @@ static void arm64_memory_present(void) {struct memblock_region *reg; -for_each_memblock (memory, reg) +for_each_memblock (memory, reg) { +#ifdef CONFIG_NUMA +memory_present (reg->nid, +memblock_region_memory_base_pfn (reg), +memblock_region_memory_end_pfn (reg)); +#else memory_present (0 ,memblock_region_memory_base_pfn (reg),memblock_region_memory_end_pfn (reg)); +#endif + } }#endif
@@ -168,6 +191,11 @@ void __init bootmem_init(void) min =PFN_UP (memblock_start_of_DRAM ()); max =PFN_DOWN (memblock_end_of_DRAM ()); + high_memory =__va ((max <<PAGE_SHIFT ) -1 ) +1 ; + max_pfn = max_low_pfn = max; + +if (IS_ENABLED (CONFIG_NUMA )) +arm64_numa_init ();/* * Sparsemem tries to allocate bootmem in memory_present(), so must be * done after the fixed reservations.
@@ -176,9 +204,6 @@ void __init bootmem_init(void)sparse_init ();zone_sizes_init (min, max); - - high_memory =__va ((max <<PAGE_SHIFT ) -1 ) +1 ; - max_pfn = max_low_pfn = max; }#ifndef CONFIG_SPARSEMEM_VMEMMAP
arch/arm64/mm/numa.c new file +471 -0
471 lines not on this page · raw message
Signature · 1 line
1.8.1.4