Skip to contentSkip to conversation

arm64, numa: Add numa support for arm64 platforms.

PATCH Superseded Ganapatrao Kulkarni 12 participants 48 messages Aug 14, 2015 – Oct 14, 2015

Subsystems (2)

v5 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

v5 cover arm64, numa: Add numa support for arm64 platforms.

v5:
- created base verion of numa.c which creates dummy numa without using dt on single socket platforms. Then added patches for dt support.
- Incorporated review comments from Hanjun Guo.

v4:
done changes as per Arnd review comments.

v3:
Added changes to support numa on arm64 based platforms. Tested these patches on cavium's multinode(2 node topology) platform. In this patchset, defined and implemented dt bindings for numa mapping for core and memory using device node property arm,associativity.

v2:
Defined and implemented numa map for memory, cores to node and proximity distance matrix of nodes.

v1:
Initial patchset to support numa on arm64 platforms.

Note:
1. This patchset is tested for numa with dt on
thunderx single socket and dual socket boards.
2. Numa DT booting needs the dt memory nodes, which are deleted in current efi-stub, hence to try numa with dt, you need to rebase with ard's patchset.
http://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/heads/arm64-uefi-early-fdt-handling

Ganapatrao Kulkarni (4):
arm64, numa: adding numa support for arm64 platforms.
Documentation: arm64/arm: dt bindings for numa.
arm64, numa: adding numa support for arm64 platforms. arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node
topology.

 Documentation/devicetree/bindings/arm/numa.txt  | 212 +++++++
 arch/arm64/Kconfig                              |  32 +
 arch/arm64/boot/dts/cavium/Makefile             |   2 +-
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790 ++++++++++++++++++++++++
 arch/arm64/include/asm/mmzone.h                 |  32 +
 arch/arm64/include/asm/numa.h                   |  49 ++
 arch/arm64/kernel/Makefile                      |   1 +
 arch/arm64/kernel/dt_numa.c                     | 316 ++++++++++
 arch/arm64/kernel/setup.c                       |   9 +
 arch/arm64/kernel/smp.c                         |   3 +
 arch/arm64/mm/Makefile                          |   1 +
 arch/arm64/mm/init.c                            |  34 +-
 arch/arm64/mm/numa.c                            | 563 +++++++++++++++++
 14 files changed, 2115 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
 create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
 create mode 100644 arch/arm64/boot/dts/cavium/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/kernel/dt_numa.c
 create mode 100644 arch/arm64/mm/numa.c
Signature · 1 line
1.8.1.4
#1 lore raw

PATCH v5 1/4 arm64, numa: adding numa support for arm64 platforms.

Adding numa support for arm64 based platforms.
This patch adds by default the dummy numa node and
maps all memory and cpus to node 0.
using this patch, numa can be simulated on single node arm64 platforms.

---
 arch/arm64/Kconfig              |  26 ++
 arch/arm64/include/asm/mmzone.h |  32 +++
 arch/arm64/include/asm/numa.h   |  42 +++
 arch/arm64/kernel/setup.c       |   9 +
 arch/arm64/kernel/smp.c         |   2 +
 arch/arm64/mm/Makefile          |   1 +
 arch/arm64/mm/init.c            |  34 ++-
 arch/arm64/mm/numa.c            | 550 ++++++++++++++++++++++++++++++++++++++++
 8 files changed, 690 insertions(+), 6 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 +26 -0
index 43a0c26..fa37a5d 100644
@@ -72,6 +72,7 @@ config ARM64
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_RCU_TABLE_FREE
 	select HAVE_SYSCALL_TRACEPOINTS
+	select HAVE_MEMBLOCK_NODE_MAP if NUMA
 	select IRQ_DOMAIN
 	select IRQ_FORCED_THREADING
 	select MODULES_USE_ELF_RELA
@@ -559,6 +560,31 @@ 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 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 UP_LATE_INIT
arch/arm64/include/asm/mmzone.h new file +32 -0
new file mode 100644
index 0000000..d27ee66
@@ -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 +42 -0

42 lines not on this page · raw message

arch/arm64/kernel/setup.c +9 -0
index 4d4d7ce..6e101eb 100644
@@ -65,6 +65,7 @@
 #include <asm/efi.h>
 #include <asm/virt.h>
 #include <asm/xen/hypervisor.h>
+#include <asm/numa.h>
 
 unsigned long elf_hwcap __read_mostly;
 EXPORT_SYMBOL_GPL(elf_hwcap);
@@ -439,6 +440,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;
@@ -511,7 +515,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
index 50fb469..ae3e02c 100644
@@ -52,6 +52,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>
@@ -124,6 +125,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
index 773d37a..bb92d41 100644
@@ -4,3 +4,4 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
 				   context.o proc.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_ARM64_PTDUMP)	+= dump.o
+obj-$(CONFIG_NUMA)		+= numa.o
arch/arm64/mm/init.c +28 -6
index 54da32e..cab384b 100644
@@ -42,6 +42,7 @@
 #include <asm/sizes.h>
 #include <asm/tlb.h>
 #include <asm/alternative.h>
+#include <asm/numa.h>
 
 #include "mm.h"
 
@@ -77,6 +78,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;
@@ -115,6 +130,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)
@@ -132,10 +148,15 @@ static void arm64_memory_present(void)
 static void arm64_memory_present(void)
 {
 	struct memblock_region *reg;
+	int nid = 0;
 
-	for_each_memblock(memory, reg)
-		memory_present(0, memblock_region_memory_base_pfn(reg),
-			       memblock_region_memory_end_pfn(reg));
+	for_each_memblock(memory, reg) {
+#ifdef CONFIG_NUMA
+		nid = reg->nid;
+#endif
+		memory_present(nid, memblock_region_memory_base_pfn(reg),
+				memblock_region_memory_end_pfn(reg));
+	}
 }
 #endif
 
@@ -200,6 +221,10 @@ 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;
+
+	arm64_numa_init();
 	/*
 	 * Sparsemem tries to allocate bootmem in memory_present(), so must be
 	 * done after the fixed reservations.
@@ -208,9 +233,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 +550 -0

550 lines not on this page · raw message

Signature · 1 line
1.8.1.4
#2 lore raw

PATCH v5 1/4 arm64, numa: adding numa support for arm64 platforms.

Hi Catalin/Will,

Quoted 852 lines · Ganapatrao Kulkarni

Adding numa support for arm64 based platforms.
This patch adds by default the dummy numa node and
maps all memory and cpus to node 0.
using this patch, numa can be simulated on single node arm64 platforms.

---
 arch/arm64/Kconfig              |  26 ++
 arch/arm64/include/asm/mmzone.h |  32 +++
 arch/arm64/include/asm/numa.h   |  42 +++
 arch/arm64/kernel/setup.c       |   9 +
 arch/arm64/kernel/smp.c         |   2 +
 arch/arm64/mm/Makefile          |   1 +
 arch/arm64/mm/init.c            |  34 ++-
 arch/arm64/mm/numa.c            | 550 ++++++++++++++++++++++++++++++++++++++++
 8 files changed, 690 insertions(+), 6 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 +26 -0
index 43a0c26..fa37a5d 100644
@@ -72,6 +72,7 @@ config ARM64
        select HAVE_PERF_USER_STACK_DUMP
        select HAVE_RCU_TABLE_FREE
        select HAVE_SYSCALL_TRACEPOINTS
+       select HAVE_MEMBLOCK_NODE_MAP if NUMA
        select IRQ_DOMAIN
        select IRQ_FORCED_THREADING
        select MODULES_USE_ELF_RELA
@@ -559,6 +560,31 @@ 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 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 UP_LATE_INIT
arch/arm64/include/asm/mmzone.h new file +32 -0
new file mode 100644
index 0000000..d27ee66
@@ -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 +42 -0
new file mode 100644
index 0000000..59b834e
@@ -0,0 +1,42 @@
+#ifndef _ASM_NUMA_H
+#define _ASM_NUMA_H
+
+#include <linux/nodemask.h>
+#include <asm/topology.h>
+
+#ifdef CONFIG_NUMA
+
+#define NR_NODE_MEMBLKS                (MAX_NUMNODES * 2)
+#define ZONE_ALIGN (1UL << (MAX_ORDER + PAGE_SHIFT))
+
+/* currently, arm64 implements flat NUMA topology */
+#define parent_node(node)      (node)
+
+/* dummy definitions for pci functions */
+#define pcibus_to_node(node)   0
+#define cpumask_of_pcibus(bus) 0
+
+struct __node_cpu_hwid {
+       u32 node_id;    /* logical node containing this CPU */
+       u64 cpu_hwid;   /* MPIDR for this CPU */
+};
+
+extern struct __node_cpu_hwid node_cpu_hwid[NR_CPUS];
+extern nodemask_t numa_nodes_parsed __initdata;
+
+const struct cpumask *cpumask_of_node(int node);
+/* Mappings between node number and cpus on that node. */
+extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+
+void __init arm64_numa_init(void);
+int __init numa_add_memblk(u32 nodeid, u64 start, u64 end);
+void numa_store_cpu_info(int cpu);
+void __init build_cpu_to_node_map(void);
+void __init numa_set_distance(int from, int to, int distance);
+#else  /* CONFIG_NUMA */
+static inline void numa_store_cpu_info(int cpu)                { }
+static inline void arm64_numa_init(void)               { }
+static inline void build_cpu_to_node_map(void) { }
+static inline void numa_set_distance(int from, int to, int distance) { }
+#endif /* CONFIG_NUMA */
+#endif /* _ASM_NUMA_H */
arch/arm64/kernel/setup.c +9 -0
index 4d4d7ce..6e101eb 100644
@@ -65,6 +65,7 @@
 #include <asm/efi.h>
 #include <asm/virt.h>
 #include <asm/xen/hypervisor.h>
+#include <asm/numa.h>
 
 unsigned long elf_hwcap __read_mostly;
 EXPORT_SYMBOL_GPL(elf_hwcap);
@@ -439,6 +440,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;
@@ -511,7 +515,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
index 50fb469..ae3e02c 100644
@@ -52,6 +52,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>
@@ -124,6 +125,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
index 773d37a..bb92d41 100644
@@ -4,3 +4,4 @@ obj-y                           := dma-mapping.o extable.o fault.o init.o \
                                   context.o proc.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE)     += hugetlbpage.o
 obj-$(CONFIG_ARM64_PTDUMP)     += dump.o
+obj-$(CONFIG_NUMA)             += numa.o
arch/arm64/mm/init.c +28 -6
index 54da32e..cab384b 100644
@@ -42,6 +42,7 @@
 #include <asm/sizes.h>
 #include <asm/tlb.h>
 #include <asm/alternative.h>
+#include <asm/numa.h>
 
 #include "mm.h"
 
@@ -77,6 +78,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;
@@ -115,6 +130,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)
@@ -132,10 +148,15 @@ static void arm64_memory_present(void)
 static void arm64_memory_present(void)
 {
        struct memblock_region *reg;
+       int nid = 0;
 
-       for_each_memblock(memory, reg)
-               memory_present(0, memblock_region_memory_base_pfn(reg),
-                              memblock_region_memory_end_pfn(reg));
+       for_each_memblock(memory, reg) {
+#ifdef CONFIG_NUMA
+               nid = reg->nid;
+#endif
+               memory_present(nid, memblock_region_memory_base_pfn(reg),
+                               memblock_region_memory_end_pfn(reg));
+       }
 }
 #endif
 
@@ -200,6 +221,10 @@ 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;
+
+       arm64_numa_init();
        /*
         * Sparsemem tries to allocate bootmem in memory_present(), so must be
         * done after the fixed reservations.
@@ -208,9 +233,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 +550 -1
new file mode 100644
index 0000000..2be83de
@@ -0,0 +1,550 @@
+/*
+ * NUMA support, based on the x86 implementation.
+ *
+ * Copyright (C) 2015 Cavium Inc.
+ * Author: Ganapatrao Kulkarni <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program 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 program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+#include <linux/topology.h>
+#include <linux/mmzone.h>
+
+#include <asm/smp_plat.h>
+
+int __initdata numa_off;
+nodemask_t numa_nodes_parsed __initdata;
+static int numa_distance_cnt;
+static u8 *numa_distance;
+static u8 dummy_numa_enabled;
+
+struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
+EXPORT_SYMBOL(node_data);
+
+struct __node_cpu_hwid node_cpu_hwid[NR_CPUS];
+static struct numa_meminfo numa_meminfo;
+
+static __init int numa_setup(char *opt)
+{
+       if (!opt)
+               return -EINVAL;
+       if (!strncmp(opt, "off", 3)) {
+               pr_info("%s\n", "NUMA turned off");
+               numa_off = 1;
+       }
+       return 0;
+}
+early_param("numa", numa_setup);
+
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+EXPORT_SYMBOL(node_to_cpumask_map);
+
+int cpu_to_node_map[NR_CPUS];
+EXPORT_SYMBOL(cpu_to_node_map);
+
+/*
+ * Returns a pointer to the bitmask of CPUs on Node 'node'.
+ */
+const struct cpumask *cpumask_of_node(int node)
+{
+       if (node >= nr_node_ids) {
+               pr_warn("cpumask_of_node(%d): node > nr_node_ids(%d)\n",
+                       node, nr_node_ids);
+               dump_stack();
+               return cpu_none_mask;
+       }
+       if (node_to_cpumask_map[node] == NULL) {
+               pr_warn("cpumask_of_node(%d): no node_to_cpumask_map!\n",
+                       node);
+               dump_stack();
+               return cpu_online_mask;
+       }
+       return node_to_cpumask_map[node];
+}
+EXPORT_SYMBOL(cpumask_of_node);
+
+void numa_clear_node(int cpu)
+{
+       set_cpu_numa_node(cpu, NUMA_NO_NODE);
+}
+
+void map_cpu_to_node(int cpu, int nid)
+{
+       if (nid < 0) { /* just initialize by zero */
+               cpu_to_node_map[cpu] = 0;
+               return;
+       }
+
+       cpu_to_node_map[cpu] = nid;
+       cpumask_set_cpu(cpu, node_to_cpumask_map[nid]);
+       set_numa_node(nid);
+}
+
+/**
+ * build_cpu_to_node_map - setup cpu to node and node to cpumask arrays
+ *
+ * Build cpu to node mapping and initialize the per node cpu masks using
+ * info from the node_cpuid array handed to us by ACPI or DT.
+ */
+void __init build_cpu_to_node_map(void)
+{
+       int cpu, i, node;
+
+       for (node = 0; node < MAX_NUMNODES; node++)
+               cpumask_clear(node_to_cpumask_map[node]);
+
+       for_each_possible_cpu(cpu) {
+               node = NUMA_NO_NODE;
+               for_each_possible_cpu(i) {
+                       if (cpu_logical_map(cpu) == node_cpu_hwid[i].cpu_hwid) {
+                               node = node_cpu_hwid[i].node_id;
+                               break;
+                       }
+               }
+               map_cpu_to_node(cpu, node);
+       }
+}
+/*
+ * Allocate node_to_cpumask_map based on number of available nodes
+ * Requires node_possible_map to be valid.
+ *
+ * Note: cpumask_of_node() is not valid until after this is done.
+ * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
+ */
+void __init setup_node_to_cpumask_map(void)
+{
+       unsigned int node;
+
+       /* setup nr_node_ids if not done yet */
+       if (nr_node_ids == MAX_NUMNODES)
+               setup_nr_node_ids();
+
+       /* allocate the map */
+       for (node = 0; node < nr_node_ids; node++)
+               alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
+
+       /* cpumask_of_node() will now work */
+       pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
+}
+
+/*
+ *  Set the cpu to node and mem mapping
+ */
+void numa_store_cpu_info(int cpu)
+{
+       if (dummy_numa_enabled) {
+               /* set to default */
+               node_cpu_hwid[cpu].node_id  =  0;
+               node_cpu_hwid[cpu].cpu_hwid = cpu_logical_map(cpu);
+       }
+       map_cpu_to_node(cpu, node_cpu_hwid[cpu].node_id);
+}
+
+/**
+ * numa_add_memblk_to - Add one numa_memblk to a numa_meminfo
+ */
+
+static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
+                                    struct numa_meminfo *mi)
+{
+       /* ignore zero length blks */
+       if (start == end)
+               return 0;
+
+       /* whine about and ignore invalid blks */
+       if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
+               pr_warn("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
+                               nid, start, end - 1);
+               return 0;
+       }
+
+       if (mi->nr_blks >= NR_NODE_MEMBLKS) {
+               pr_err("NUMA: too many memblk ranges\n");
+               return -EINVAL;
+       }
+
+       pr_info("NUMA: Adding memblock %d [0x%llx - 0x%llx] on node %d\n",
+                       mi->nr_blks, start, end, nid);
+       mi->blk[mi->nr_blks].start = start;
+       mi->blk[mi->nr_blks].end = end;
+       mi->blk[mi->nr_blks].nid = nid;
+       mi->nr_blks++;
+       return 0;
+}
+
+/**
+ * numa_add_memblk - Add one numa_memblk to numa_meminfo
+ * @nid: NUMA node ID of the new memblk
+ * @start: Start address of the new memblk
+ * @end: End address of the new memblk
+ *
+ * Add a new memblk to the default numa_meminfo.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+#define MAX_PHYS_ADDR  ((phys_addr_t)~0)
+
+int __init numa_add_memblk(u32 nid, u64 base, u64 end)
+{
+       const u64 phys_offset = __pa(PAGE_OFFSET);
+
+       base &= PAGE_MASK;
+       end &= PAGE_MASK;
+
+       if (base > MAX_PHYS_ADDR) {
+               pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
+                               base, base + end);
+               return -ENOMEM;
+       }
+
+       if (base + end > MAX_PHYS_ADDR) {
+               pr_info("NUMA: Ignoring memory range 0x%lx - 0x%llx\n",
+                               ULONG_MAX, base + end);
+               end = MAX_PHYS_ADDR - base;
+       }
+
+       if (base + end < phys_offset) {
+               pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
+                          base, base + end);
+               return -ENOMEM;
+       }
+       if (base < phys_offset) {
+               pr_info("NUMA: Ignoring memory range 0x%llx - 0x%llx\n",
+                          base, phys_offset);
+               end -= phys_offset - base;
+               base = phys_offset;
+       }
+
+       return numa_add_memblk_to(nid, base, base + end, &numa_meminfo);
+}
+EXPORT_SYMBOL(numa_add_memblk);
+
+/* Initialize NODE_DATA for a node on the local memory */
+static void __init setup_node_data(int nid, u64 start, u64 end)
+{
+       const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
+       u64 nd_pa;
+       void *nd;
+       int tnid;
+
+       start = roundup(start, ZONE_ALIGN);
+
+       pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
+              nid, start, end - 1);
+
+       /*
+        * Allocate node data.  Try node-local memory and then any node.
+        */
+       nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid);
+       if (!nd_pa) {
+               nd_pa = __memblock_alloc_base(nd_size, SMP_CACHE_BYTES,
+                                             MEMBLOCK_ALLOC_ACCESSIBLE);
+               if (!nd_pa) {
+                       pr_err("Cannot find %zu bytes in node %d\n",
+                              nd_size, nid);
+                       return;
+               }
+       }
+       nd = __va(nd_pa);
+
+       /* report and initialize */
+       pr_info("  NODE_DATA [mem %#010Lx-%#010Lx]\n",
+              nd_pa, nd_pa + nd_size - 1);
+       tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
+       if (tnid != nid)
+               pr_info("    NODE_DATA(%d) on node %d\n", nid, tnid);
+
+       node_data[nid] = nd;
+       memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
+       NODE_DATA(nid)->node_id = nid;
+       NODE_DATA(nid)->node_start_pfn = start >> PAGE_SHIFT;
+       NODE_DATA(nid)->node_spanned_pages = (end - start) >> PAGE_SHIFT;
+
+       node_set_online(nid);
+}
+
+/*
+ * Set nodes, which have memory in @mi, in *@nodemask.
+ */
+static void __init numa_nodemask_from_meminfo(nodemask_t *nodemask,
+                                             const struct numa_meminfo *mi)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(mi->blk); i++)
+               if (mi->blk[i].start != mi->blk[i].end &&
+                   mi->blk[i].nid != NUMA_NO_NODE)
+                       node_set(mi->blk[i].nid, *nodemask);
+}
+
+/*
+ * Sanity check to catch more bad NUMA configurations (they are amazingly
+ * common).  Make sure the nodes cover all memory.
+ */
+static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
+{
+       u64 numaram, totalram;
+       int i;
+
+       numaram = 0;
+       for (i = 0; i < mi->nr_blks; i++) {
+               u64 s = mi->blk[i].start >> PAGE_SHIFT;
+               u64 e = mi->blk[i].end >> PAGE_SHIFT;
+
+               numaram += e - s;
+               numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e);
+               if ((s64)numaram < 0)
+                       numaram = 0;
+       }
+
+       totalram = max_pfn - absent_pages_in_range(0, max_pfn);
+
+       /* We seem to lose 3 pages somewhere. Allow 1M of slack. */
+       if ((s64)(totalram - numaram) >= (1 << (20 - PAGE_SHIFT))) {
+               pr_err("NUMA: nodes only cover %lluMB of your %lluMB Total RAM. Not used.\n",
+                      (numaram << PAGE_SHIFT) >> 20,
+                      (totalram << PAGE_SHIFT) >> 20);
+               return false;
+       }
+       return true;
+}
+
+/**
+ * numa_reset_distance - Reset NUMA distance table
+ *
+ * The current table is freed.  The next numa_set_distance() call will
+ * create a new one.
+ */
+void __init numa_reset_distance(void)
+{
+       size_t size = numa_distance_cnt * numa_distance_cnt *
+               sizeof(numa_distance[0]);
+
+       /* numa_distance could be 1LU marking allocation failure, test cnt */
+       if (numa_distance_cnt)
+               memblock_free(__pa(numa_distance), size);
+       numa_distance_cnt = 0;
+       numa_distance = NULL;   /* enable table creation */
+}
+
+static int __init numa_alloc_distance(void)
+{
+       nodemask_t nodes_parsed;
+       size_t size;
+       int i, j, cnt = 0;
+       u64 phys;
+
+       /* size the new table and allocate it */
+       nodes_parsed = numa_nodes_parsed;
+       numa_nodemask_from_meminfo(&nodes_parsed, &numa_meminfo);
+
+       for_each_node_mask(i, nodes_parsed)
+               cnt = i;
+       cnt++;
+       size = cnt * cnt * sizeof(numa_distance[0]);
+
+       phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
+                                     size, PAGE_SIZE);
+       if (!phys) {
+               pr_warn("NUMA: Warning: can't allocate distance table!\n");
+               /* don't retry until explicitly reset */
+               numa_distance = (void *)1LU;
+               return -ENOMEM;
+       }
+       memblock_reserve(phys, size);
+
+       numa_distance = __va(phys);
+       numa_distance_cnt = cnt;
+
+       /* fill with the default distances */
+       for (i = 0; i < cnt; i++)
+               for (j = 0; j < cnt; j++)
+                       numa_distance[i * cnt + j] = i == j ?
+                               LOCAL_DISTANCE : REMOTE_DISTANCE;
+       pr_debug("NUMA: Initialized distance table, cnt=%d\n", cnt);
+
+       return 0;
+}
+
+/**
+ * numa_set_distance - Set NUMA distance from one NUMA to another
+ * @from: the 'from' node to set distance
+ * @to: the 'to'  node to set distance
+ * @distance: NUMA distance
+ *
+ * Set the distance from node @from to @to to @distance.  If distance table
+ * doesn't exist, one which is large enough to accommodate all the currently
+ * known nodes will be created.
+ *
+ * If such table cannot be allocated, a warning is printed and further
+ * calls are ignored until the distance table is reset with
+ * numa_reset_distance().
+ *
+ * If @from or @to is higher than the highest known node or lower than zero
+ * at the time of table creation or @distance doesn't make sense, the call
+ * is ignored.
+ * This is to allow simplification of specific NUMA config implementations.
+ */
+void __init numa_set_distance(int from, int to, int distance)
+{
+       if (!numa_distance && numa_alloc_distance() < 0)
+               return;
+
+       if (from >= numa_distance_cnt || to >= numa_distance_cnt ||
+                       from < 0 || to < 0) {
+               pr_warn_once("NUMA: Warning: node ids are out of bound, from=%d to=%d distance=%d\n",
+                           from, to, distance);
+               return;
+       }
+
+       if ((u8)distance != distance ||
+           (from == to && distance != LOCAL_DISTANCE)) {
+               pr_warn_once("NUMA: Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
+                            from, to, distance);
+               return;
+       }
+
+       numa_distance[from * numa_distance_cnt + to] = distance;
+}
+EXPORT_SYMBOL(numa_set_distance);
+
+int __node_distance(int from, int to)
+{
+       if (from >= numa_distance_cnt || to >= numa_distance_cnt)
+               return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
+       return numa_distance[from * numa_distance_cnt + to];
+}
+EXPORT_SYMBOL(__node_distance);
+
+static int __init numa_register_memblks(struct numa_meminfo *mi)
+{
+       unsigned long uninitialized_var(pfn_align);
+       int i, nid;
+
+       /* Account for nodes with cpus and no memory */
+       node_possible_map = numa_nodes_parsed;
+       numa_nodemask_from_meminfo(&node_possible_map, mi);
+       if (WARN_ON(nodes_empty(node_possible_map)))
+               return -EINVAL;
+
+       for (i = 0; i < mi->nr_blks; i++) {
+               struct numa_memblk *mb = &mi->blk[i];
+
+               memblock_set_node(mb->start, mb->end - mb->start,
+                                 &memblock.memory, mb->nid);
+       }
+
+       /*
+        * If sections array is gonna be used for pfn -> nid mapping, check
+        * whether its granularity is fine enough.
+        */
+#ifdef NODE_NOT_IN_PAGE_FLAGS
+       pfn_align = node_map_pfn_alignment();
+       if (pfn_align && pfn_align < PAGES_PER_SECTION) {
+               pr_warn("Node alignment %lluMB < min %lluMB, rejecting NUMA config\n",
+                      PFN_PHYS(pfn_align) >> 20,
+                      PFN_PHYS(PAGES_PER_SECTION) >> 20);
+               return -EINVAL;
+       }
+#endif
+       if (!numa_meminfo_cover_memory(mi))
+               return -EINVAL;
+
+       /* Finally register nodes. */
+       for_each_node_mask(nid, node_possible_map) {
+               u64 start = PFN_PHYS(max_pfn);
+               u64 end = 0;
+
+               for (i = 0; i < mi->nr_blks; i++) {
+                       if (nid != mi->blk[i].nid)
+                               continue;
+                       start = min(mi->blk[i].start, start);
+                       end = max(mi->blk[i].end, end);
+               }
+
+               if (start < end)
+                       setup_node_data(nid, start, end);
+       }
+
+       /* Dump memblock with node info and return. */
+       memblock_dump_all();
+       return 0;
+}
+
+static int __init numa_init(int (*init_func)(void))
+{
+       int ret, i;
+
+       nodes_clear(numa_nodes_parsed);
+       nodes_clear(node_possible_map);
+       nodes_clear(node_online_map);
+
+       ret = init_func();
+       if (ret < 0)
+               return ret;
+
+       ret = numa_register_memblks(&numa_meminfo);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < nr_cpu_ids; i++)
+               numa_clear_node(i);
+
+       setup_node_to_cpumask_map();
+       build_cpu_to_node_map();
+       return 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", "No NUMA configuration found");
+       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));
+       dummy_numa_enabled = 1;
+
+       return 0;
+}
+
+/**
+ * arm64_numa_init - Initialize NUMA
+ *
+ * Try each configured NUMA initialization method until one succeeds.  The
+ * last fallback is dummy single node config encomapssing whole memory and
+ * never fails.
+ */
+void __init arm64_numa_init(void)
+{
+       numa_init(dummy_numa_init);
+}
--
Quoted 2 lines

1.8.1.4

can you please review this patch.

thanks
Ganapat

#3 lore raw

PATCH v5 1/4 arm64, numa: adding numa support for arm64 platforms.

Quoted 8 lines · Ganapatrao Kulkarni
Quoted 6 lines · Ganapatrao Kulkarni

Adding numa support for arm64 based platforms.
This patch adds by default the dummy numa node and
maps all memory and cpus to node 0.
using this patch, numa can be simulated on single node arm64 platforms.

[trimmed ~850 lines of context]

Quoted 1 line

can you please review this patch.

It's the middle of the merge window, please be patient.

Will

#4 lore raw

PATCH v5 1/4 arm64, numa: adding numa support for arm64 platforms.

Hi Will/Catalin,

Quoted 8 lines · Will Deacon
Quoted 7 lines · Ganapatrao Kulkarni
Quoted 5 lines · Ganapatrao Kulkarni

Adding numa support for arm64 based platforms.
This patch adds by default the dummy numa node and
maps all memory and cpus to node 0.
using this patch, numa can be simulated on single node arm64 platforms.

Quoted 7 lines
Quoted 1 line
Quoted 1 line

[trimmed ~850 lines of context]

Quoted 1 line

can you please review this patch.

It's the middle of the merge window, please be patient.

can you please share your feedback?

Quoted 2 lines

Will

thanks
Ganapat

#5 lore raw

PATCH v5 1/4 arm64, numa: adding numa support for arm64 platforms.

In reply to Ganapatrao Kulkarni

Hi Catalin,

can you please review this patch.

Quoted 852 lines · Ganapatrao Kulkarni

Adding numa support for arm64 based platforms.
This patch adds by default the dummy numa node and
maps all memory and cpus to node 0.
using this patch, numa can be simulated on single node arm64 platforms.

---
 arch/arm64/Kconfig              |  26 ++
 arch/arm64/include/asm/mmzone.h |  32 +++
 arch/arm64/include/asm/numa.h   |  42 +++
 arch/arm64/kernel/setup.c       |   9 +
 arch/arm64/kernel/smp.c         |   2 +
 arch/arm64/mm/Makefile          |   1 +
 arch/arm64/mm/init.c            |  34 ++-
 arch/arm64/mm/numa.c            | 550 ++++++++++++++++++++++++++++++++++++++++
 8 files changed, 690 insertions(+), 6 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 +26 -0
index 43a0c26..fa37a5d 100644
@@ -72,6 +72,7 @@ config ARM64
        select HAVE_PERF_USER_STACK_DUMP
        select HAVE_RCU_TABLE_FREE
        select HAVE_SYSCALL_TRACEPOINTS
+       select HAVE_MEMBLOCK_NODE_MAP if NUMA
        select IRQ_DOMAIN
        select IRQ_FORCED_THREADING
        select MODULES_USE_ELF_RELA
@@ -559,6 +560,31 @@ 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 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 UP_LATE_INIT
arch/arm64/include/asm/mmzone.h new file +32 -0
new file mode 100644
index 0000000..d27ee66
@@ -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 +42 -0
new file mode 100644
index 0000000..59b834e
@@ -0,0 +1,42 @@
+#ifndef _ASM_NUMA_H
+#define _ASM_NUMA_H
+
+#include <linux/nodemask.h>
+#include <asm/topology.h>
+
+#ifdef CONFIG_NUMA
+
+#define NR_NODE_MEMBLKS                (MAX_NUMNODES * 2)
+#define ZONE_ALIGN (1UL << (MAX_ORDER + PAGE_SHIFT))
+
+/* currently, arm64 implements flat NUMA topology */
+#define parent_node(node)      (node)
+
+/* dummy definitions for pci functions */
+#define pcibus_to_node(node)   0
+#define cpumask_of_pcibus(bus) 0
+
+struct __node_cpu_hwid {
+       u32 node_id;    /* logical node containing this CPU */
+       u64 cpu_hwid;   /* MPIDR for this CPU */
+};
+
+extern struct __node_cpu_hwid node_cpu_hwid[NR_CPUS];
+extern nodemask_t numa_nodes_parsed __initdata;
+
+const struct cpumask *cpumask_of_node(int node);
+/* Mappings between node number and cpus on that node. */
+extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+
+void __init arm64_numa_init(void);
+int __init numa_add_memblk(u32 nodeid, u64 start, u64 end);
+void numa_store_cpu_info(int cpu);
+void __init build_cpu_to_node_map(void);
+void __init numa_set_distance(int from, int to, int distance);
+#else  /* CONFIG_NUMA */
+static inline void numa_store_cpu_info(int cpu)                { }
+static inline void arm64_numa_init(void)               { }
+static inline void build_cpu_to_node_map(void) { }
+static inline void numa_set_distance(int from, int to, int distance) { }
+#endif /* CONFIG_NUMA */
+#endif /* _ASM_NUMA_H */
arch/arm64/kernel/setup.c +9 -0
index 4d4d7ce..6e101eb 100644
@@ -65,6 +65,7 @@
 #include <asm/efi.h>
 #include <asm/virt.h>
 #include <asm/xen/hypervisor.h>
+#include <asm/numa.h>
 
 unsigned long elf_hwcap __read_mostly;
 EXPORT_SYMBOL_GPL(elf_hwcap);
@@ -439,6 +440,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;
@@ -511,7 +515,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
index 50fb469..ae3e02c 100644
@@ -52,6 +52,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>
@@ -124,6 +125,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
index 773d37a..bb92d41 100644
@@ -4,3 +4,4 @@ obj-y                           := dma-mapping.o extable.o fault.o init.o \
                                   context.o proc.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE)     += hugetlbpage.o
 obj-$(CONFIG_ARM64_PTDUMP)     += dump.o
+obj-$(CONFIG_NUMA)             += numa.o
arch/arm64/mm/init.c +28 -6
index 54da32e..cab384b 100644
@@ -42,6 +42,7 @@
 #include <asm/sizes.h>
 #include <asm/tlb.h>
 #include <asm/alternative.h>
+#include <asm/numa.h>
 
 #include "mm.h"
 
@@ -77,6 +78,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;
@@ -115,6 +130,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)
@@ -132,10 +148,15 @@ static void arm64_memory_present(void)
 static void arm64_memory_present(void)
 {
        struct memblock_region *reg;
+       int nid = 0;
 
-       for_each_memblock(memory, reg)
-               memory_present(0, memblock_region_memory_base_pfn(reg),
-                              memblock_region_memory_end_pfn(reg));
+       for_each_memblock(memory, reg) {
+#ifdef CONFIG_NUMA
+               nid = reg->nid;
+#endif
+               memory_present(nid, memblock_region_memory_base_pfn(reg),
+                               memblock_region_memory_end_pfn(reg));
+       }
 }
 #endif
 
@@ -200,6 +221,10 @@ 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;
+
+       arm64_numa_init();
        /*
         * Sparsemem tries to allocate bootmem in memory_present(), so must be
         * done after the fixed reservations.
@@ -208,9 +233,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 +550 -1
new file mode 100644
index 0000000..2be83de
@@ -0,0 +1,550 @@
+/*
+ * NUMA support, based on the x86 implementation.
+ *
+ * Copyright (C) 2015 Cavium Inc.
+ * Author: Ganapatrao Kulkarni <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program 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 program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+#include <linux/topology.h>
+#include <linux/mmzone.h>
+
+#include <asm/smp_plat.h>
+
+int __initdata numa_off;
+nodemask_t numa_nodes_parsed __initdata;
+static int numa_distance_cnt;
+static u8 *numa_distance;
+static u8 dummy_numa_enabled;
+
+struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
+EXPORT_SYMBOL(node_data);
+
+struct __node_cpu_hwid node_cpu_hwid[NR_CPUS];
+static struct numa_meminfo numa_meminfo;
+
+static __init int numa_setup(char *opt)
+{
+       if (!opt)
+               return -EINVAL;
+       if (!strncmp(opt, "off", 3)) {
+               pr_info("%s\n", "NUMA turned off");
+               numa_off = 1;
+       }
+       return 0;
+}
+early_param("numa", numa_setup);
+
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+EXPORT_SYMBOL(node_to_cpumask_map);
+
+int cpu_to_node_map[NR_CPUS];
+EXPORT_SYMBOL(cpu_to_node_map);
+
+/*
+ * Returns a pointer to the bitmask of CPUs on Node 'node'.
+ */
+const struct cpumask *cpumask_of_node(int node)
+{
+       if (node >= nr_node_ids) {
+               pr_warn("cpumask_of_node(%d): node > nr_node_ids(%d)\n",
+                       node, nr_node_ids);
+               dump_stack();
+               return cpu_none_mask;
+       }
+       if (node_to_cpumask_map[node] == NULL) {
+               pr_warn("cpumask_of_node(%d): no node_to_cpumask_map!\n",
+                       node);
+               dump_stack();
+               return cpu_online_mask;
+       }
+       return node_to_cpumask_map[node];
+}
+EXPORT_SYMBOL(cpumask_of_node);
+
+void numa_clear_node(int cpu)
+{
+       set_cpu_numa_node(cpu, NUMA_NO_NODE);
+}
+
+void map_cpu_to_node(int cpu, int nid)
+{
+       if (nid < 0) { /* just initialize by zero */
+               cpu_to_node_map[cpu] = 0;
+               return;
+       }
+
+       cpu_to_node_map[cpu] = nid;
+       cpumask_set_cpu(cpu, node_to_cpumask_map[nid]);
+       set_numa_node(nid);
+}
+
+/**
+ * build_cpu_to_node_map - setup cpu to node and node to cpumask arrays
+ *
+ * Build cpu to node mapping and initialize the per node cpu masks using
+ * info from the node_cpuid array handed to us by ACPI or DT.
+ */
+void __init build_cpu_to_node_map(void)
+{
+       int cpu, i, node;
+
+       for (node = 0; node < MAX_NUMNODES; node++)
+               cpumask_clear(node_to_cpumask_map[node]);
+
+       for_each_possible_cpu(cpu) {
+               node = NUMA_NO_NODE;
+               for_each_possible_cpu(i) {
+                       if (cpu_logical_map(cpu) == node_cpu_hwid[i].cpu_hwid) {
+                               node = node_cpu_hwid[i].node_id;
+                               break;
+                       }
+               }
+               map_cpu_to_node(cpu, node);
+       }
+}
+/*
+ * Allocate node_to_cpumask_map based on number of available nodes
+ * Requires node_possible_map to be valid.
+ *
+ * Note: cpumask_of_node() is not valid until after this is done.
+ * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
+ */
+void __init setup_node_to_cpumask_map(void)
+{
+       unsigned int node;
+
+       /* setup nr_node_ids if not done yet */
+       if (nr_node_ids == MAX_NUMNODES)
+               setup_nr_node_ids();
+
+       /* allocate the map */
+       for (node = 0; node < nr_node_ids; node++)
+               alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
+
+       /* cpumask_of_node() will now work */
+       pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
+}
+
+/*
+ *  Set the cpu to node and mem mapping
+ */
+void numa_store_cpu_info(int cpu)
+{
+       if (dummy_numa_enabled) {
+               /* set to default */
+               node_cpu_hwid[cpu].node_id  =  0;
+               node_cpu_hwid[cpu].cpu_hwid = cpu_logical_map(cpu);
+       }
+       map_cpu_to_node(cpu, node_cpu_hwid[cpu].node_id);
+}
+
+/**
+ * numa_add_memblk_to - Add one numa_memblk to a numa_meminfo
+ */
+
+static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
+                                    struct numa_meminfo *mi)
+{
+       /* ignore zero length blks */
+       if (start == end)
+               return 0;
+
+       /* whine about and ignore invalid blks */
+       if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
+               pr_warn("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
+                               nid, start, end - 1);
+               return 0;
+       }
+
+       if (mi->nr_blks >= NR_NODE_MEMBLKS) {
+               pr_err("NUMA: too many memblk ranges\n");
+               return -EINVAL;
+       }
+
+       pr_info("NUMA: Adding memblock %d [0x%llx - 0x%llx] on node %d\n",
+                       mi->nr_blks, start, end, nid);
+       mi->blk[mi->nr_blks].start = start;
+       mi->blk[mi->nr_blks].end = end;
+       mi->blk[mi->nr_blks].nid = nid;
+       mi->nr_blks++;
+       return 0;
+}
+
+/**
+ * numa_add_memblk - Add one numa_memblk to numa_meminfo
+ * @nid: NUMA node ID of the new memblk
+ * @start: Start address of the new memblk
+ * @end: End address of the new memblk
+ *
+ * Add a new memblk to the default numa_meminfo.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+#define MAX_PHYS_ADDR  ((phys_addr_t)~0)
+
+int __init numa_add_memblk(u32 nid, u64 base, u64 end)
+{
+       const u64 phys_offset = __pa(PAGE_OFFSET);
+
+       base &= PAGE_MASK;
+       end &= PAGE_MASK;
+
+       if (base > MAX_PHYS_ADDR) {
+               pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
+                               base, base + end);
+               return -ENOMEM;
+       }
+
+       if (base + end > MAX_PHYS_ADDR) {
+               pr_info("NUMA: Ignoring memory range 0x%lx - 0x%llx\n",
+                               ULONG_MAX, base + end);
+               end = MAX_PHYS_ADDR - base;
+       }
+
+       if (base + end < phys_offset) {
+               pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
+                          base, base + end);
+               return -ENOMEM;
+       }
+       if (base < phys_offset) {
+               pr_info("NUMA: Ignoring memory range 0x%llx - 0x%llx\n",
+                          base, phys_offset);
+               end -= phys_offset - base;
+               base = phys_offset;
+       }
+
+       return numa_add_memblk_to(nid, base, base + end, &numa_meminfo);
+}
+EXPORT_SYMBOL(numa_add_memblk);
+
+/* Initialize NODE_DATA for a node on the local memory */
+static void __init setup_node_data(int nid, u64 start, u64 end)
+{
+       const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
+       u64 nd_pa;
+       void *nd;
+       int tnid;
+
+       start = roundup(start, ZONE_ALIGN);
+
+       pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
+              nid, start, end - 1);
+
+       /*
+        * Allocate node data.  Try node-local memory and then any node.
+        */
+       nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid);
+       if (!nd_pa) {
+               nd_pa = __memblock_alloc_base(nd_size, SMP_CACHE_BYTES,
+                                             MEMBLOCK_ALLOC_ACCESSIBLE);
+               if (!nd_pa) {
+                       pr_err("Cannot find %zu bytes in node %d\n",
+                              nd_size, nid);
+                       return;
+               }
+       }
+       nd = __va(nd_pa);
+
+       /* report and initialize */
+       pr_info("  NODE_DATA [mem %#010Lx-%#010Lx]\n",
+              nd_pa, nd_pa + nd_size - 1);
+       tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
+       if (tnid != nid)
+               pr_info("    NODE_DATA(%d) on node %d\n", nid, tnid);
+
+       node_data[nid] = nd;
+       memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
+       NODE_DATA(nid)->node_id = nid;
+       NODE_DATA(nid)->node_start_pfn = start >> PAGE_SHIFT;
+       NODE_DATA(nid)->node_spanned_pages = (end - start) >> PAGE_SHIFT;
+
+       node_set_online(nid);
+}
+
+/*
+ * Set nodes, which have memory in @mi, in *@nodemask.
+ */
+static void __init numa_nodemask_from_meminfo(nodemask_t *nodemask,
+                                             const struct numa_meminfo *mi)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(mi->blk); i++)
+               if (mi->blk[i].start != mi->blk[i].end &&
+                   mi->blk[i].nid != NUMA_NO_NODE)
+                       node_set(mi->blk[i].nid, *nodemask);
+}
+
+/*
+ * Sanity check to catch more bad NUMA configurations (they are amazingly
+ * common).  Make sure the nodes cover all memory.
+ */
+static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
+{
+       u64 numaram, totalram;
+       int i;
+
+       numaram = 0;
+       for (i = 0; i < mi->nr_blks; i++) {
+               u64 s = mi->blk[i].start >> PAGE_SHIFT;
+               u64 e = mi->blk[i].end >> PAGE_SHIFT;
+
+               numaram += e - s;
+               numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e);
+               if ((s64)numaram < 0)
+                       numaram = 0;
+       }
+
+       totalram = max_pfn - absent_pages_in_range(0, max_pfn);
+
+       /* We seem to lose 3 pages somewhere. Allow 1M of slack. */
+       if ((s64)(totalram - numaram) >= (1 << (20 - PAGE_SHIFT))) {
+               pr_err("NUMA: nodes only cover %lluMB of your %lluMB Total RAM. Not used.\n",
+                      (numaram << PAGE_SHIFT) >> 20,
+                      (totalram << PAGE_SHIFT) >> 20);
+               return false;
+       }
+       return true;
+}
+
+/**
+ * numa_reset_distance - Reset NUMA distance table
+ *
+ * The current table is freed.  The next numa_set_distance() call will
+ * create a new one.
+ */
+void __init numa_reset_distance(void)
+{
+       size_t size = numa_distance_cnt * numa_distance_cnt *
+               sizeof(numa_distance[0]);
+
+       /* numa_distance could be 1LU marking allocation failure, test cnt */
+       if (numa_distance_cnt)
+               memblock_free(__pa(numa_distance), size);
+       numa_distance_cnt = 0;
+       numa_distance = NULL;   /* enable table creation */
+}
+
+static int __init numa_alloc_distance(void)
+{
+       nodemask_t nodes_parsed;
+       size_t size;
+       int i, j, cnt = 0;
+       u64 phys;
+
+       /* size the new table and allocate it */
+       nodes_parsed = numa_nodes_parsed;
+       numa_nodemask_from_meminfo(&nodes_parsed, &numa_meminfo);
+
+       for_each_node_mask(i, nodes_parsed)
+               cnt = i;
+       cnt++;
+       size = cnt * cnt * sizeof(numa_distance[0]);
+
+       phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
+                                     size, PAGE_SIZE);
+       if (!phys) {
+               pr_warn("NUMA: Warning: can't allocate distance table!\n");
+               /* don't retry until explicitly reset */
+               numa_distance = (void *)1LU;
+               return -ENOMEM;
+       }
+       memblock_reserve(phys, size);
+
+       numa_distance = __va(phys);
+       numa_distance_cnt = cnt;
+
+       /* fill with the default distances */
+       for (i = 0; i < cnt; i++)
+               for (j = 0; j < cnt; j++)
+                       numa_distance[i * cnt + j] = i == j ?
+                               LOCAL_DISTANCE : REMOTE_DISTANCE;
+       pr_debug("NUMA: Initialized distance table, cnt=%d\n", cnt);
+
+       return 0;
+}
+
+/**
+ * numa_set_distance - Set NUMA distance from one NUMA to another
+ * @from: the 'from' node to set distance
+ * @to: the 'to'  node to set distance
+ * @distance: NUMA distance
+ *
+ * Set the distance from node @from to @to to @distance.  If distance table
+ * doesn't exist, one which is large enough to accommodate all the currently
+ * known nodes will be created.
+ *
+ * If such table cannot be allocated, a warning is printed and further
+ * calls are ignored until the distance table is reset with
+ * numa_reset_distance().
+ *
+ * If @from or @to is higher than the highest known node or lower than zero
+ * at the time of table creation or @distance doesn't make sense, the call
+ * is ignored.
+ * This is to allow simplification of specific NUMA config implementations.
+ */
+void __init numa_set_distance(int from, int to, int distance)
+{
+       if (!numa_distance && numa_alloc_distance() < 0)
+               return;
+
+       if (from >= numa_distance_cnt || to >= numa_distance_cnt ||
+                       from < 0 || to < 0) {
+               pr_warn_once("NUMA: Warning: node ids are out of bound, from=%d to=%d distance=%d\n",
+                           from, to, distance);
+               return;
+       }
+
+       if ((u8)distance != distance ||
+           (from == to && distance != LOCAL_DISTANCE)) {
+               pr_warn_once("NUMA: Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
+                            from, to, distance);
+               return;
+       }
+
+       numa_distance[from * numa_distance_cnt + to] = distance;
+}
+EXPORT_SYMBOL(numa_set_distance);
+
+int __node_distance(int from, int to)
+{
+       if (from >= numa_distance_cnt || to >= numa_distance_cnt)
+               return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
+       return numa_distance[from * numa_distance_cnt + to];
+}
+EXPORT_SYMBOL(__node_distance);
+
+static int __init numa_register_memblks(struct numa_meminfo *mi)
+{
+       unsigned long uninitialized_var(pfn_align);
+       int i, nid;
+
+       /* Account for nodes with cpus and no memory */
+       node_possible_map = numa_nodes_parsed;
+       numa_nodemask_from_meminfo(&node_possible_map, mi);
+       if (WARN_ON(nodes_empty(node_possible_map)))
+               return -EINVAL;
+
+       for (i = 0; i < mi->nr_blks; i++) {
+               struct numa_memblk *mb = &mi->blk[i];
+
+               memblock_set_node(mb->start, mb->end - mb->start,
+                                 &memblock.memory, mb->nid);
+       }
+
+       /*
+        * If sections array is gonna be used for pfn -> nid mapping, check
+        * whether its granularity is fine enough.
+        */
+#ifdef NODE_NOT_IN_PAGE_FLAGS
+       pfn_align = node_map_pfn_alignment();
+       if (pfn_align && pfn_align < PAGES_PER_SECTION) {
+               pr_warn("Node alignment %lluMB < min %lluMB, rejecting NUMA config\n",
+                      PFN_PHYS(pfn_align) >> 20,
+                      PFN_PHYS(PAGES_PER_SECTION) >> 20);
+               return -EINVAL;
+       }
+#endif
+       if (!numa_meminfo_cover_memory(mi))
+               return -EINVAL;
+
+       /* Finally register nodes. */
+       for_each_node_mask(nid, node_possible_map) {
+               u64 start = PFN_PHYS(max_pfn);
+               u64 end = 0;
+
+               for (i = 0; i < mi->nr_blks; i++) {
+                       if (nid != mi->blk[i].nid)
+                               continue;
+                       start = min(mi->blk[i].start, start);
+                       end = max(mi->blk[i].end, end);
+               }
+
+               if (start < end)
+                       setup_node_data(nid, start, end);
+       }
+
+       /* Dump memblock with node info and return. */
+       memblock_dump_all();
+       return 0;
+}
+
+static int __init numa_init(int (*init_func)(void))
+{
+       int ret, i;
+
+       nodes_clear(numa_nodes_parsed);
+       nodes_clear(node_possible_map);
+       nodes_clear(node_online_map);
+
+       ret = init_func();
+       if (ret < 0)
+               return ret;
+
+       ret = numa_register_memblks(&numa_meminfo);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < nr_cpu_ids; i++)
+               numa_clear_node(i);
+
+       setup_node_to_cpumask_map();
+       build_cpu_to_node_map();
+       return 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", "No NUMA configuration found");
+       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));
+       dummy_numa_enabled = 1;
+
+       return 0;
+}
+
+/**
+ * arm64_numa_init - Initialize NUMA
+ *
+ * Try each configured NUMA initialization method until one succeeds.  The
+ * last fallback is dummy single node config encomapssing whole memory and
+ * never fails.
+ */
+void __init arm64_numa_init(void)
+{
+       numa_init(dummy_numa_init);
+}
--
Quoted 2 lines

1.8.1.4

thanks
Ganapat

#6 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

In reply to Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

---
 Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
Documentation/devicetree/bindings/arm/numa.txt new file +212 -0
new file mode 100644
index 0000000..dc3ef86
@@ -0,0 +1,212 @@
+==============================================================================
+NUMA binding description.
+==============================================================================
+
+==============================================================================
+1 - Introduction
+==============================================================================
+
+Systems employing a Non Uniform Memory Access (NUMA) architecture contain
+collections of hardware resources including processors, memory, and I/O buses,
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is generally faster
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node
+topology information to OS.
+
+==============================================================================
+2 - arm,associativity
+==============================================================================
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to to be
+mapped to numa nodes.
+
+arm,associativity property is set of 32-bit integers which defines level of
+topology and boundary in the system at which a significant difference in
+performance can be measured between cross-device accesses within
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within the system,
+while the last cell enumerates the individual devices, such as an SMT thread
+of a CPU, or a bus bridge within an SoC".
+
+ex:
+	/* board 0, socket 0, cluster 0, core 0  thread 0 */
+	arm,associativity = <0 0 0 0 0>;
+
+==============================================================================
+3 - arm,associativity-reference-points
+==============================================================================
+This property is a set of 32-bit integers, each representing an index into
+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant boundaries.
+There can be more than one level of NUMA.
+
+Ex:
+	arm,associativity-reference-points = <0 1>;
+	The board Id(index 0) used first to calculate the associativity (node
+	distance), then follows the  socket id(index 1).
+
+	arm,associativity-reference-points = <1 0>;
+	The socket Id(index 1) used first to calculate the associativity,
+	then follows the board id(index 0).
+
+	arm,associativity-reference-points = <0>;
+	Only the board Id(index 0) used to calculate the associativity.
+
+	arm,associativity-reference-points = <1>;
+	Only socket Id(index 1) used to calculate the associativity.
+
+==============================================================================
+4 - Example dts
+==============================================================================
+
+Example: 2 Node system consists of 2 boards and each board having one socket
+and 8 core in each socket.
+
+	arm,associativity-reference-points = <0>;
+
+	memory at 00c00000 {
+		device_type = "memory";
+		reg = <0x0 0x00c00000 0x0 0x80000000>;
+		/* board 0, socket 0, no specific core */
+		arm,associativity = <0 0 0xffff>;
+	};
+
+	memory at 10000000000 {
+		device_type = "memory";
+		reg = <0x100 0x00000000 0x0 0x80000000>;
+		/* board 1, socket 0, no specific core */
+		arm,associativity = <1 0 0xffff>;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu at 000 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x000>;
+			enable-method = "psci";
+			/* board 0, socket 0, core 0*/
+			arm,associativity = <0 0 0>;
+		};
+		cpu at 001 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x001>;
+			enable-method = "psci";
+			arm,associativity = <0 0 1>;
+		};
+		cpu at 002 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x002>;
+			enable-method = "psci";
+			arm,associativity = <0 0 2>;
+		};
+		cpu at 003 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x003>;
+			enable-method = "psci";
+			arm,associativity = <0 0 3>;
+		};
+		cpu at 004 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x004>;
+			enable-method = "psci";
+			arm,associativity = <0 0 4>;
+		};
+		cpu at 005 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x005>;
+			enable-method = "psci";
+			arm,associativity = <0 0 5>;
+		};
+		cpu at 006 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x006>;
+			enable-method = "psci";
+			arm,associativity = <0 0 6>;
+		};
+		cpu at 007 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x007>;
+			enable-method = "psci";
+			arm,associativity = <0 0 7>;
+		};
+		cpu at 008 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x008>;
+			enable-method = "psci";
+			/* board 1, socket 0, core 0*/
+			arm,associativity = <1 0 0>;
+		};
+		cpu at 009 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x009>;
+			enable-method = "psci";
+			arm,associativity = <1 0 1>;
+		};
+		cpu at 00a {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00a>;
+			enable-method = "psci";
+			arm,associativity = <0 0 2>;
+		};
+		cpu at 00b {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00b>;
+			enable-method = "psci";
+			arm,associativity = <1 0 3>;
+		};
+		cpu at 00c {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00c>;
+			enable-method = "psci";
+			arm,associativity = <1 0 4>;
+		};
+		cpu at 00d {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00d>;
+			enable-method = "psci";
+			arm,associativity = <1 0 5>;
+		};
+		cpu at 00e {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00e>;
+			enable-method = "psci";
+			arm,associativity = <1 0 6>;
+		};
+		cpu at 00f {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00f>;
+			enable-method = "psci";
+			arm,associativity = <1 0 7>;
+		};
+	};
+
+	pcie0: pcie0 at 0x8480,00000000 {
+		compatible = "arm,armv8";
+		device_type = "pci";
+		bus-range = <0 255>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0x8480 0x00000000 0 0x10000000>;  /* Configuration space */
+		ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000 0x70 0x00000000>; /* mem ranges */
+		/* board 0, socket 0, pci bus 0*/
+		arm,associativity = <0 0 0>;
+        };
Signature · 1 line
1.8.1.4
#7 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Arnd, Rob,

as the change below suggests the same topology syntax as already implemented for PPC, could you take a look at this one for arm64? Please ack the devicetree changes, assuming you are fine with it.

All other review comments are addressed so far and there are no open issues with the patches. This would help us to further drive this series upstream.

Many thanks,

-Robert

Quoted 232 lines
---
 Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
Documentation/devicetree/bindings/arm/numa.txt new file +212 -0
new file mode 100644
index 0000000..dc3ef86
@@ -0,0 +1,212 @@
+==============================================================================
+NUMA binding description.
+==============================================================================
+
+==============================================================================
+1 - Introduction
+==============================================================================
+
+Systems employing a Non Uniform Memory Access (NUMA) architecture contain
+collections of hardware resources including processors, memory, and I/O buses,
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is generally faster
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node
+topology information to OS.
+
+==============================================================================
+2 - arm,associativity
+==============================================================================
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to to be
+mapped to numa nodes.
+
+arm,associativity property is set of 32-bit integers which defines level of
+topology and boundary in the system at which a significant difference in
+performance can be measured between cross-device accesses within
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within the system,
+while the last cell enumerates the individual devices, such as an SMT thread
+of a CPU, or a bus bridge within an SoC".
+
+ex:
+	/* board 0, socket 0, cluster 0, core 0  thread 0 */
+	arm,associativity = <0 0 0 0 0>;
+
+==============================================================================
+3 - arm,associativity-reference-points
+==============================================================================
+This property is a set of 32-bit integers, each representing an index into
+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant boundaries.
+There can be more than one level of NUMA.
+
+Ex:
+	arm,associativity-reference-points = <0 1>;
+	The board Id(index 0) used first to calculate the associativity (node
+	distance), then follows the  socket id(index 1).
+
+	arm,associativity-reference-points = <1 0>;
+	The socket Id(index 1) used first to calculate the associativity,
+	then follows the board id(index 0).
+
+	arm,associativity-reference-points = <0>;
+	Only the board Id(index 0) used to calculate the associativity.
+
+	arm,associativity-reference-points = <1>;
+	Only socket Id(index 1) used to calculate the associativity.
+
+==============================================================================
+4 - Example dts
+==============================================================================
+
+Example: 2 Node system consists of 2 boards and each board having one socket
+and 8 core in each socket.
+
+	arm,associativity-reference-points = <0>;
+
+	memory at 00c00000 {
+		device_type = "memory";
+		reg = <0x0 0x00c00000 0x0 0x80000000>;
+		/* board 0, socket 0, no specific core */
+		arm,associativity = <0 0 0xffff>;
+	};
+
+	memory at 10000000000 {
+		device_type = "memory";
+		reg = <0x100 0x00000000 0x0 0x80000000>;
+		/* board 1, socket 0, no specific core */
+		arm,associativity = <1 0 0xffff>;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu at 000 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x000>;
+			enable-method = "psci";
+			/* board 0, socket 0, core 0*/
+			arm,associativity = <0 0 0>;
+		};
+		cpu at 001 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x001>;
+			enable-method = "psci";
+			arm,associativity = <0 0 1>;
+		};
+		cpu at 002 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x002>;
+			enable-method = "psci";
+			arm,associativity = <0 0 2>;
+		};
+		cpu at 003 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x003>;
+			enable-method = "psci";
+			arm,associativity = <0 0 3>;
+		};
+		cpu at 004 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x004>;
+			enable-method = "psci";
+			arm,associativity = <0 0 4>;
+		};
+		cpu at 005 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x005>;
+			enable-method = "psci";
+			arm,associativity = <0 0 5>;
+		};
+		cpu at 006 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x006>;
+			enable-method = "psci";
+			arm,associativity = <0 0 6>;
+		};
+		cpu at 007 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x007>;
+			enable-method = "psci";
+			arm,associativity = <0 0 7>;
+		};
+		cpu at 008 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x008>;
+			enable-method = "psci";
+			/* board 1, socket 0, core 0*/
+			arm,associativity = <1 0 0>;
+		};
+		cpu at 009 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x009>;
+			enable-method = "psci";
+			arm,associativity = <1 0 1>;
+		};
+		cpu at 00a {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00a>;
+			enable-method = "psci";
+			arm,associativity = <0 0 2>;
+		};
+		cpu at 00b {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00b>;
+			enable-method = "psci";
+			arm,associativity = <1 0 3>;
+		};
+		cpu at 00c {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00c>;
+			enable-method = "psci";
+			arm,associativity = <1 0 4>;
+		};
+		cpu at 00d {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00d>;
+			enable-method = "psci";
+			arm,associativity = <1 0 5>;
+		};
+		cpu at 00e {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00e>;
+			enable-method = "psci";
+			arm,associativity = <1 0 6>;
+		};
+		cpu at 00f {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00f>;
+			enable-method = "psci";
+			arm,associativity = <1 0 7>;
+		};
+	};
+
+	pcie0: pcie0 at 0x8480,00000000 {
+		compatible = "arm,armv8";
+		device_type = "pci";
+		bus-range = <0 255>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0x8480 0x00000000 0 0x10000000>;  /* Configuration space */
+		ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000 0x70 0x00000000>; /* mem ranges */
+		/* board 0, socket 0, pci bus 0*/
+		arm,associativity = <0 0 0>;
+        };
Signature · 7 lines
1.8.1.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
#8 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

In reply to Ganapatrao Kulkarni
Quoted 4 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Given this matches PPC, looks fine to me.

Quoted 231 lines
---
 Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
Documentation/devicetree/bindings/arm/numa.txt new file +212 -1
new file mode 100644
index 0000000..dc3ef86
@@ -0,0 +1,212 @@
+==============================================================================
+NUMA binding description.
+==============================================================================
+
+==============================================================================
+1 - Introduction
+==============================================================================
+
+Systems employing a Non Uniform Memory Access (NUMA) architecture contain
+collections of hardware resources including processors, memory, and I/O buses,
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is generally faster
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node
+topology information to OS.
+
+==============================================================================
+2 - arm,associativity
+==============================================================================
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to to be
+mapped to numa nodes.
+
+arm,associativity property is set of 32-bit integers which defines level of
+topology and boundary in the system at which a significant difference in
+performance can be measured between cross-device accesses within
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within the system,
+while the last cell enumerates the individual devices, such as an SMT thread
+of a CPU, or a bus bridge within an SoC".
+
+ex:
+       /* board 0, socket 0, cluster 0, core 0  thread 0 */
+       arm,associativity = <0 0 0 0 0>;
+
+==============================================================================
+3 - arm,associativity-reference-points
+==============================================================================
+This property is a set of 32-bit integers, each representing an index into
+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant boundaries.
+There can be more than one level of NUMA.
+
+Ex:
+       arm,associativity-reference-points = <0 1>;
+       The board Id(index 0) used first to calculate the associativity (node
+       distance), then follows the  socket id(index 1).
+
+       arm,associativity-reference-points = <1 0>;
+       The socket Id(index 1) used first to calculate the associativity,
+       then follows the board id(index 0).
+
+       arm,associativity-reference-points = <0>;
+       Only the board Id(index 0) used to calculate the associativity.
+
+       arm,associativity-reference-points = <1>;
+       Only socket Id(index 1) used to calculate the associativity.
+
+==============================================================================
+4 - Example dts
+==============================================================================
+
+Example: 2 Node system consists of 2 boards and each board having one socket
+and 8 core in each socket.
+
+       arm,associativity-reference-points = <0>;
+
+       memory at 00c00000 {
+               device_type = "memory";
+               reg = <0x0 0x00c00000 0x0 0x80000000>;
+               /* board 0, socket 0, no specific core */
+               arm,associativity = <0 0 0xffff>;
+       };
+
+       memory at 10000000000 {
+               device_type = "memory";
+               reg = <0x100 0x00000000 0x0 0x80000000>;
+               /* board 1, socket 0, no specific core */
+               arm,associativity = <1 0 0xffff>;
+       };
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu at 000 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x000>;
+                       enable-method = "psci";
+                       /* board 0, socket 0, core 0*/
+                       arm,associativity = <0 0 0>;
+               };
+               cpu at 001 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x001>;
+                       enable-method = "psci";
+                       arm,associativity = <0 0 1>;
+               };
+               cpu at 002 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x002>;
+                       enable-method = "psci";
+                       arm,associativity = <0 0 2>;
+               };
+               cpu at 003 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x003>;
+                       enable-method = "psci";
+                       arm,associativity = <0 0 3>;
+               };
+               cpu at 004 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x004>;
+                       enable-method = "psci";
+                       arm,associativity = <0 0 4>;
+               };
+               cpu at 005 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x005>;
+                       enable-method = "psci";
+                       arm,associativity = <0 0 5>;
+               };
+               cpu at 006 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x006>;
+                       enable-method = "psci";
+                       arm,associativity = <0 0 6>;
+               };
+               cpu at 007 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x007>;
+                       enable-method = "psci";
+                       arm,associativity = <0 0 7>;
+               };
+               cpu at 008 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x008>;
+                       enable-method = "psci";
+                       /* board 1, socket 0, core 0*/
+                       arm,associativity = <1 0 0>;
+               };
+               cpu at 009 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x009>;
+                       enable-method = "psci";
+                       arm,associativity = <1 0 1>;
+               };
+               cpu at 00a {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x00a>;
+                       enable-method = "psci";
+                       arm,associativity = <0 0 2>;
+               };
+               cpu at 00b {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x00b>;
+                       enable-method = "psci";
+                       arm,associativity = <1 0 3>;
+               };
+               cpu at 00c {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x00c>;
+                       enable-method = "psci";
+                       arm,associativity = <1 0 4>;
+               };
+               cpu at 00d {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x00d>;
+                       enable-method = "psci";
+                       arm,associativity = <1 0 5>;
+               };
+               cpu at 00e {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x00e>;
+                       enable-method = "psci";
+                       arm,associativity = <1 0 6>;
+               };
+               cpu at 00f {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x00f>;
+                       enable-method = "psci";
+                       arm,associativity = <1 0 7>;
+               };
+       };
+
+       pcie0: pcie0 at 0x8480,00000000 {
+               compatible = "arm,armv8";
+               device_type = "pci";
+               bus-range = <0 255>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0x8480 0x00000000 0 0x10000000>;  /* Configuration space */
+               ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000 0x70 0x00000000>; /* mem ranges */
+               /* board 0, socket 0, pci bus 0*/
+               arm,associativity = <0 0 0>;
+        };
--

1.8.1.4

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#9 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

In reply to Ganapatrao Kulkarni
Quoted 168 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

---
  Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
  1 file changed, 212 insertions(+)

create mode 100644 Documentation/devicetree/bindings/arm/numa.txt

Documentation/devicetree/bindings/arm/numa.txt new file +153 -0
new file mode 100644
index 0000000..dc3ef86
@@ -0,0 +1,212 @@
+==============================================================================
+NUMA binding description.
+==============================================================================
+
+==============================================================================
+1 - Introduction
+==============================================================================
+
+Systems employing a Non Uniform Memory Access (NUMA) architecture contain
+collections of hardware resources including processors, memory, and I/O buses,
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is generally faster
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node
+topology information to OS.
+
+==============================================================================
+2 - arm,associativity
+==============================================================================
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to to be
+mapped to numa nodes.
+
+arm,associativity property is set of 32-bit integers which defines level of
+topology and boundary in the system at which a significant difference in
+performance can be measured between cross-device accesses within
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within the system,
+while the last cell enumerates the individual devices, such as an SMT thread
+of a CPU, or a bus bridge within an SoC".
+
+ex:
+	/* board 0, socket 0, cluster 0, core 0  thread 0 */
+	arm,associativity = <0 0 0 0 0>;
+
+==============================================================================
+3 - arm,associativity-reference-points
+==============================================================================
+This property is a set of 32-bit integers, each representing an index into
+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant boundaries.
+There can be more than one level of NUMA.
+
+Ex:
+	arm,associativity-reference-points = <0 1>;
+	The board Id(index 0) used first to calculate the associativity (node
+	distance), then follows the  socket id(index 1).
+
+	arm,associativity-reference-points = <1 0>;
+	The socket Id(index 1) used first to calculate the associativity,
+	then follows the board id(index 0).
+
+	arm,associativity-reference-points = <0>;
+	Only the board Id(index 0) used to calculate the associativity.
+
+	arm,associativity-reference-points = <1>;
+	Only socket Id(index 1) used to calculate the associativity.
+
+==============================================================================
+4 - Example dts
+==============================================================================
+
+Example: 2 Node system consists of 2 boards and each board having one socket
+and 8 core in each socket.
+
+	arm,associativity-reference-points = <0>;
+
+	memory at 00c00000 {
+		device_type = "memory";
+		reg = <0x0 0x00c00000 0x0 0x80000000>;
+		/* board 0, socket 0, no specific core */
+		arm,associativity = <0 0 0xffff>;
+	};
+
+	memory at 10000000000 {
+		device_type = "memory";
+		reg = <0x100 0x00000000 0x0 0x80000000>;
+		/* board 1, socket 0, no specific core */
+		arm,associativity = <1 0 0xffff>;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu at 000 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x000>;
+			enable-method = "psci";
+			/* board 0, socket 0, core 0*/
+			arm,associativity = <0 0 0>;
+		};
+		cpu at 001 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x001>;
+			enable-method = "psci";
+			arm,associativity = <0 0 1>;
+		};
+		cpu at 002 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x002>;
+			enable-method = "psci";
+			arm,associativity = <0 0 2>;
+		};
+		cpu at 003 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x003>;
+			enable-method = "psci";
+			arm,associativity = <0 0 3>;
+		};
+		cpu at 004 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x004>;
+			enable-method = "psci";
+			arm,associativity = <0 0 4>;
+		};
+		cpu at 005 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x005>;
+			enable-method = "psci";
+			arm,associativity = <0 0 5>;
+		};
+		cpu at 006 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x006>;
+			enable-method = "psci";
+			arm,associativity = <0 0 6>;
+		};
+		cpu at 007 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x007>;
+			enable-method = "psci";
+			arm,associativity = <0 0 7>;
+		};
+		cpu at 008 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x008>;
+			enable-method = "psci";
+			/* board 1, socket 0, core 0*/
+			arm,associativity = <1 0 0>;
+		};
+		cpu at 009 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";

Documentation/devicetree/bindings/arm/numa.txt line 163

Quoted 10 lines
Documentation/devicetree/bindings/arm/numa.txt new file +10 -0
+			reg = <0x0 0x009>;
+			enable-method = "psci";
+			arm,associativity = <1 0 1>;
+		};
+		cpu at 00a {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00a>;
+			enable-method = "psci";
+			arm,associativity = <0 0 2>;

Nit: this should be
arm,associativity = <1 0 2>;

Quoted 50 lines
Documentation/devicetree/bindings/arm/numa.txt new file +49 -0
+		};
+		cpu at 00b {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00b>;
+			enable-method = "psci";
+			arm,associativity = <1 0 3>;
+		};
+		cpu at 00c {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00c>;
+			enable-method = "psci";
+			arm,associativity = <1 0 4>;
+		};
+		cpu at 00d {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00d>;
+			enable-method = "psci";
+			arm,associativity = <1 0 5>;
+		};
+		cpu at 00e {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00e>;
+			enable-method = "psci";
+			arm,associativity = <1 0 6>;
+		};
+		cpu at 00f {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00f>;
+			enable-method = "psci";
+			arm,associativity = <1 0 7>;
+		};
+	};
+
+	pcie0: pcie0 at 0x8480,00000000 {
+		compatible = "arm,armv8";
+		device_type = "pci";
+		bus-range = <0 255>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0x8480 0x00000000 0 0x10000000>;  /* Configuration space */
+		ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000 0x70 0x00000000>; /* mem ranges */
+		/* board 0, socket 0, pci bus 0*/
+		arm,associativity = <0 0 0>;
+        };
reviewer
#10 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

In reply to Ganapatrao Kulkarni

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

However, (somewhat counter to that) I'm also concerned that this isn't sufficient for systems we're beginning to see today (more on that below), so I don't think a simple copy of ibm,associativity is good enough.

Quoted 25 lines
---
 Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
Documentation/devicetree/bindings/arm/numa.txt new file +12 -0
new file mode 100644
index 0000000..dc3ef86
@@ -0,0 +1,212 @@
+==============================================================================
+NUMA binding description.
+==============================================================================
+
+==============================================================================
+1 - Introduction
+==============================================================================
+
+Systems employing a Non Uniform Memory Access (NUMA) architecture contain
+collections of hardware resources including processors, memory, and I/O buses,
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is generally faster

Documentation/devicetree/bindings/arm/numa.txt line 22

Quoted 10 lines
Documentation/devicetree/bindings/arm/numa.txt new file +10 -0
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node
+topology information to OS.
+
+==============================================================================
+2 - arm,associativity
+==============================================================================
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to to be
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an arm,associativity property being assumed to share that value?

Documentation/devicetree/bindings/arm/numa.txt line 24

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+arm,associativity property is set of 32-bit integers which defines level of

s/set/list/ -- the order is important.

Documentation/devicetree/bindings/arm/numa.txt line 30

Quoted 6 lines
Documentation/devicetree/bindings/arm/numa.txt new file +6 -0
+topology and boundary in the system at which a significant difference in
+performance can be measured between cross-device accesses within
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within the system,
+while the last cell enumerates the individual devices, such as an SMT thread
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative distances at all. That seems like an oversight.

Additionally, I'm somewhat unclear on how what you'd be expected to provide for this property in cases like ring or mesh interconnects, where there isn't a strict hierarchy (see systems with ARM's own CCN, or Tilera's TILE-Mx), but there is some measure of closeness.

Must all of these have the same length? If so, why not have a #(whatever)-cells property in the root to describe the expected length? If not, how are they to be interpreted relative to each other?

Documentation/devicetree/bindings/arm/numa.txt line 32

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+ex:

s/ex/Example:/, please. There's no need to contract that.

Documentation/devicetree/bindings/arm/numa.txt line 39

Quoted 7 lines
Documentation/devicetree/bindings/arm/numa.txt new file +7 -0
+       /* board 0, socket 0, cluster 0, core 0  thread 0 */
+       arm,associativity = <0 0 0 0 0>;
+
+==============================================================================
+3 - arm,associativity-reference-points
+==============================================================================
+This property is a set of 32-bit integers, each representing an index into

Likeise, s/set/list/

Documentation/devicetree/bindings/arm/numa.txt line 42

Quoted 3 lines
Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant boundaries.
+There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property is already ordered from most significant to least significant per its description.

What does this property achieve?

The description also doesn't describe where this property is expected to live. The example isn't sufficient to disambiguate that, especially as it seems like a trivial case.

Is this only expected at the root of the tree? Can it be re-defined in sub-nodes?

Documentation/devicetree/bindings/arm/numa.txt line 44

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Ex:

s/Ex/Example:/, please

Quoted 38 lines
Documentation/devicetree/bindings/arm/numa.txt new file +38 -0
+       arm,associativity-reference-points = <0 1>;
+       The board Id(index 0) used first to calculate the associativity (node
+       distance), then follows the  socket id(index 1).
+
+       arm,associativity-reference-points = <1 0>;
+       The socket Id(index 1) used first to calculate the associativity,
+       then follows the board id(index 0).
+
+       arm,associativity-reference-points = <0>;
+       Only the board Id(index 0) used to calculate the associativity.
+
+       arm,associativity-reference-points = <1>;
+       Only socket Id(index 1) used to calculate the associativity.
+
+==============================================================================
+4 - Example dts
+==============================================================================
+
+Example: 2 Node system consists of 2 boards and each board having one socket
+and 8 core in each socket.
+
+       arm,associativity-reference-points = <0>;
+
+       memory at 00c00000 {
+               device_type = "memory";
+               reg = <0x0 0x00c00000 0x0 0x80000000>;
+               /* board 0, socket 0, no specific core */
+               arm,associativity = <0 0 0xffff>;
+       };
+
+       memory at 10000000000 {
+               device_type = "memory";
+               reg = <0x100 0x00000000 0x0 0x80000000>;
+               /* board 1, socket 0, no specific core */
+               arm,associativity = <1 0 0xffff>;
+       };
+
+       cpus {

Documentation/devicetree/bindings/arm/numa.txt line 92

Quoted 10 lines
Documentation/devicetree/bindings/arm/numa.txt new file +10 -0
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu at 000 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x000>;
+                       enable-method = "psci";
+                       /* board 0, socket 0, core 0*/
+                       arm,associativity = <0 0 0>;

We should specify w.r.t. memory and CPUs how the property is expected to be used (e.g. in the CPU nodes rather than the cpu-map, with separate memory nodes, etc). The generic description of arm,associativity isn't sufficient to limit confusion there.

Thanks,
Mark.

#11 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

+benh

Quoted 8 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

So just keep the ibm? I'm okay with that. That would help move to common code. Alternatively, we could drop the vendor prefix and have common code just check for both.

Quoted 36 lines

However, (somewhat counter to that) I'm also concerned that this isn't sufficient for systems we're beginning to see today (more on that below), so I don't think a simple copy of ibm,associativity is good enough.

Quoted 30 lines
---
 Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
Documentation/devicetree/bindings/arm/numa.txt new file +17 -0
new file mode 100644
index 0000000..dc3ef86
@@ -0,0 +1,212 @@
+==============================================================================
+NUMA binding description.
+==============================================================================
+
+==============================================================================
+1 - Introduction
+==============================================================================
+
+Systems employing a Non Uniform Memory Access (NUMA) architecture contain
+collections of hardware resources including processors, memory, and I/O buses,
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is generally faster
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node
+topology information to OS.
+
+==============================================================================
Quoted 8 lines

Documentation/devicetree/bindings/arm/numa.txt line 22

Quoted 5 lines
Documentation/devicetree/bindings/arm/numa.txt new file +5 -0
+2 - arm,associativity
+==============================================================================
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to to be
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an arm,associativity property being assumed to share that value?

There is actually already based on kernel code. So the documentation just needs to be explicit.

Quoted 16 lines

Documentation/devicetree/bindings/arm/numa.txt line 24

Quoted 3 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+arm,associativity property is set of 32-bit integers which defines level of

s/set/list/ -- the order is important.

Documentation/devicetree/bindings/arm/numa.txt line 30

Quoted 6 lines
Documentation/devicetree/bindings/arm/numa.txt new file +6 -0
+topology and boundary in the system at which a significant difference in
+performance can be measured between cross-device accesses within
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within the system,
+while the last cell enumerates the individual devices, such as an SMT thread
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative distances at all. That seems like an oversight.

Quoted 8 lines

Additionally, I'm somewhat unclear on how what you'd be expected to provide for this property in cases like ring or mesh interconnects, where there isn't a strict hierarchy (see systems with ARM's own CCN, or Tilera's TILE-Mx), but there is some measure of closeness.

Must all of these have the same length? If so, why not have a #(whatever)-cells property in the root to describe the expected length? If not, how are they to be interpreted relative to each other?

All points that could be asked of the IBM binding. Perhaps Arnd or Ben can provide some insight or know who can?

Rob

#12 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Quoted 3 lines · Rob Herring

So just keep the ibm? I'm okay with that. That would help move to common code. Alternatively, we could drop the vendor prefix and have common code just check for both.

That wouldn't be the first time we go down that path and it makes sense imho.

Quoted 2 lines

All points that could be asked of the IBM binding. Perhaps Arnd or Ben can provide some insight or know who can?

They are part of the PAPR specification which we've been trying to get published for a while now but that hasn't happened yet. Beware that there are variants of the format based on some other property. There's also
"ibm,associativity-reference-points" which is used to calculate distances. I'll see if I can get you an excerpt of the PAPR chapter, or reword it, in the next few days (please poke me if I drop the ball next week).

Cheers,
Ben.

#13 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Hi Ben,

Quoted 12 lines · Benjamin Herrenschmidt
Quoted 3 lines · Rob Herring

So just keep the ibm? I'm okay with that. That would help move to common code. Alternatively, we could drop the vendor prefix and have common code just check for both.

That wouldn't be the first time we go down that path and it makes sense imho.

Quoted 2 lines

All points that could be asked of the IBM binding. Perhaps Arnd or Ben can provide some insight or know who can?

Quoted 8 lines

They are part of the PAPR specification which we've been trying to get published for a while now but that hasn't happened yet. Beware that there are variants of the format based on some other property. There's also
"ibm,associativity-reference-points" which is used to calculate distances. I'll see if I can get you an excerpt of the PAPR chapter, or reword it, in the next few days (please poke me if I drop the ball next week).

did you get a chance to write an excerpt of the PAPR chapter? please share the details.

Quoted 4 lines

Cheers,
Ben.

thanks
Ganapat

#14 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

In reply to Rob Herring
Quoted 9 lines · Rob Herring

+benh

Quoted 6 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Quoted 7 lines
Quoted 2 lines

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

So just keep the ibm? I'm okay with that. That would help move to common code. Alternatively, we could drop the vendor prefix and have common code just check for both.

Hi all,

Why not copy the method of ACPI numa? There only three elements should be configured:
1) a cpu belong to which node
2) a memory block belong to which node
3) the distance of each two nodes

The devicetree nodes of numa can be like below:

/ {
	...

	numa-nodes-info {
		node-name: node-description {
			mem-ranges = <...>;
			cpus-list = <...>;
		};

		nodes-distance {
			distance-list = <...>;
		};
	};

	...
};

Sorry, I don't think xxx,associativity is a good method, it's hard to config, and it seems hardware-dependent. Especially, when we want to support memory hot-add, it's too hard. Because xxx,associativity have no obvious information about it. Like powerpc, it use another
property: "/ibm,dynamic-reconfiguration-memory".

I spend almost a whole month to implement of_numa(configured by dt-nodes), base upon my opinion mentioned above. If somebody are interested in it, I can send my patchset to show it.

Regards,
Thunder.

#15 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Quoted 5 lines · Leizhen (ThunderTown)

Why not copy the method of ACPI numa? There only three elements should be configured:
1) a cpu belong to which node
2) a memory block belong to which node
3) the distance of each two nodes

This means your are bolting into the DT representation the concept of "Node" which isn't necessarily very meaningful.

Your system is really a hierarchy of objects. You can have cores on a chip, already possibly sharing some level of cache or not, you can have chips on a module, modules linked at various distances, etc...

What is "a node" ?

For example, I have a P8 chip with 2 chips on a module (fast X-bus) and 2 modules (slightly slower A-bus). All 4 chips have 2 memory controllers each.

Is a "node" a chip or a module ?

The Linux concept of node is too restrictive. The associativity properties avoid this by allowing you to define as many "levels" of associativity as you wish. Also since it's right justified, a given component doesn't need to have all levels (a MC can stop at chip while cores can go down one more level for example).

The reference points property gives a hint as "interesting" levels can typically be used as a hint for chosing what Linux will use as a "node" at least until Linux gets smarter. It can also be used to calculate distances.

Cheers,
Ben.

#16 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Quoted 6 lines · Benjamin Herrenschmidt
Quoted 5 lines · Leizhen (ThunderTown)

Why not copy the method of ACPI numa? There only three elements should be configured:
1) a cpu belong to which node
2) a memory block belong to which node
3) the distance of each two nodes

Sorry, I forgot to write something:
4) a device(maybe a bus device) belongs to which node

For example:

device-name {
        ...
        numa-node = <&node0>;
};

To simplify the discussion, I will not mention device again. Treat both cpus and devices as masters, memorys as slaves.

A bus is not a master, we allow binding numa node to a bus, because we may
want all devices on the bus to inherit its numa node-id without obvious configured one by one.

Quoted 8 lines

This means your are bolting into the DT representation the concept of "Node" which isn't necessarily very meaningful.

Your system is really a hierarchy of objects. You can have cores on a chip, already possibly sharing some level of cache or not, you can have chips on a module, modules linked at various distances, etc...

Quoted 7 lines

What is "a node" ?

For example, I have a P8 chip with 2 chips on a module (fast X-bus) and 2 modules (slightly slower A-bus). All 4 chips have 2 memory controllers each.

Is a "node" a chip or a module ?

A numa node is a abstract concept, it needn't related to a real hardware level. A numa node normally contains both cpus and mems, but may only contains cpus or mems, or maybe nothing(quite rare). We put cpus or mems into a node, because we want to use node-distance to implement the nearest memory access, the nearest process schedule.

In your example:
On fast X-bus, have a module contains 2 chips.
On slightly slower A-bus, have 2 modules(treat them as 2 chips). Each chip contains 2 memory controllers.

Suppose each chip access its local bus memory faster than another.

Case1:
Each chip access its 2 local memory controllers faster than others. Then we can define numa nodes:
node-xbus-0: a chip and 2 local memory.
node-xbus-1: a chip and 2 local memory.
node-abus-0: a chip(module) and 2 local memory.
node-abus-1: a chip(module) and 2 local memory.

Case2:
Each chip access any memory controllers on its local bus are the same. Then we can define numa nodes:
node-xbus: 2 chips and 4 local memory.
node-abus: 2 chips(modules) and 4 local memory.

Quoted 18 lines

The Linux concept of node is too restrictive. The associativity properties avoid this by allowing you to define as many "levels" of associativity as you wish. Also since it's right justified, a given component doesn't need to have all levels (a MC can stop at chip while cores can go down one more level for example).

The reference points property gives a hint as "interesting" levels can typically be used as a hint for chosing what Linux will use as a "node" at least until Linux gets smarter. It can also be used to calculate distances.

Cheers,
Ben.

.

#17 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

In reply to Leizhen (ThunderTown)

Hi Thunder,

Quoted 28 lines · Leizhen (ThunderTown)
Quoted 9 lines · Rob Herring

+benh

Quoted 6 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Quoted 7 lines
Quoted 2 lines

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

So just keep the ibm? I'm okay with that. That would help move to common code. Alternatively, we could drop the vendor prefix and have common code just check for both.

Hi all,

Why not copy the method of ACPI numa? There only three elements should be configured:
1) a cpu belong to which node
2) a memory block belong to which node
3) the distance of each two nodes

The devicetree nodes of numa can be like below:

Quoted 17 lines
/ {
        ...

        numa-nodes-info {
                node-name: node-description {
                        mem-ranges = <...>;
                        cpus-list = <...>;
                };

                nodes-distance {
                        distance-list = <...>;
                };
        };

        ...
};

some what similar to what your are proposing is already implemented in my v2 patchset.
https://lwn.net/Articles/623920/
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/305164.html
we have went to associativity property based implementation to keep it more generic.
i do have both acpi(using linaro/hanjun's patches) and associativity based implementations on our internal tree
and tested on thunderx platform.
i do see issue in creating numa mapping using ACPI for IOs(for example, i am not able to create numa mapping for ITS which is on each node, using ACPI tables), since ACPI spec (tables SRAT and SLIT) talks only about processor and memory.
however associativity is generic and you can apply on any dt node.

Quoted 11 lines

Sorry, I don't think xxx,associativity is a good method, it's hard to config, and it seems hardware-dependent. Especially, when we want to support memory hot-add, it's too hard. Because xxx,associativity have no obvious information about it. Like powerpc, it use another
property: "/ibm,dynamic-reconfiguration-memory".

I spend almost a whole month to implement of_numa(configured by dt-nodes), base upon my opinion mentioned above. If somebody are interested in it, I can send my patchset to show it.

Regards,
Thunder.

thanks
ganapat

#18 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Quoted 46 lines · Ganapatrao Kulkarni

Hi Thunder,

Quoted 42 lines · Leizhen (ThunderTown)
Quoted 9 lines · Rob Herring

+benh

Quoted 6 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Quoted 7 lines
Quoted 2 lines

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

So just keep the ibm? I'm okay with that. That would help move to common code. Alternatively, we could drop the vendor prefix and have common code just check for both.

Hi all,

Why not copy the method of ACPI numa? There only three elements should be configured:
1) a cpu belong to which node
2) a memory block belong to which node
3) the distance of each two nodes

The devicetree nodes of numa can be like below:

/ {
        ...

        numa-nodes-info {
                node-name: node-description {
                        mem-ranges = <...>;
                        cpus-list = <...>;
                };

                nodes-distance {
                        distance-list = <...>;
                };
        };
Quoted 7 lines
Quoted 3 lines
        ...
};

some what similar to what your are proposing is already implemented in my v2 patchset.
https://lwn.net/Articles/623920/
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/305164.html

Sorry, I have not read your old version patchsets before.

The basic ideas are consistent, but details are different. I think your v2 patchset may meet some problem:

-------------------------
+- cpu-map: This property defines the association of range of processors
+ (range of cpu ids) and the proximity domain to which
+ the processor belongs.

+ cpu-map = <0 7 0>,
+ <8 15 1>;
-------------------------

1.
I am not sure the cpu ids is logical cpu-ids in Linux or the sequence number of the CPU dt-nodes in dts. The former case: logical cpu-id is allocated by Linux, we can not ensure that cpu0 is the first CPU dt-node. The latter case: depend on Linux strictly parse CPU dt-nodes follow the sequence in dts.

2. You should put most codes into /drivers/of/, because it can be shared with other ARCHs which base upon devicetree.

Here is my detailed example:
Examples:

/ {
	#address-cells = <2>;
	#size-cells = <2>;

	memory at 0 {
		device_type = "memory";
		reg = <0x0 0x00000000 0x0 0x40000000>,
		      <0x1 0x00000000 0x1 0x00000000>,
		      <0x2 0x00000000 0x0 0x40000000>,
		      <0x2 0x80000000 0x0 0x40000000>;
	};

	CPU0: cpu at 10000 {
		device_type = "cpu";
		reg = <0x10000>;
		...
	};

	numa-nodes-info {
		node0: cluster0 {
			mem-ranges = <0x0 0x00000000 0x1 0x00000000>;
			cpus-list = <&CPU0 &CPU1>;
		};

		node1: cluster1 {
			mem-ranges = <0x1 0x00000000 0x1 0x00000000>;
			cpus-list = <&CPU2>;
		};

		node2: cluster2 {
			mem-ranges = <0x2 0x00000000 0x1 0x00000000>;
			cpus-list = <&CPU3 &CPU4 &CPU5>;
		};

		nodes-distance {
			distance-list = <&node0 &node1 15>, <&node1 &node2 18>;
		};
	};
Quoted 26 lines

we have went to associativity property based implementation to keep it more generic.
i do have both acpi(using linaro/hanjun's patches) and associativity based implementations on our internal tree
and tested on thunderx platform.
i do see issue in creating numa mapping using ACPI for IOs(for example, i am not able to create numa mapping for ITS which is on each node, using ACPI tables), since ACPI spec (tables SRAT and SLIT) talks only about processor and memory.
however associativity is generic and you can apply on any dt node.

Quoted 11 lines

Sorry, I don't think xxx,associativity is a good method, it's hard to config, and it seems hardware-dependent. Especially, when we want to support memory hot-add, it's too hard. Because xxx,associativity have no obvious information about it. Like powerpc, it use another
property: "/ibm,dynamic-reconfiguration-memory".

I spend almost a whole month to implement of_numa(configured by dt-nodes), base upon my opinion mentioned above. If somebody are interested in it, I can send my patchset to show it.

Regards,
Thunder.

thanks
ganapat

.

#19 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

In reply to Ganapatrao Kulkarni

Hi Ganapatrao,

Quoted 49 lines · Ganapatrao Kulkarni

Hi Thunder,

Quoted 28 lines · Leizhen (ThunderTown)
Quoted 9 lines · Rob Herring

+benh

Quoted 6 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Quoted 7 lines
Quoted 2 lines

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

So just keep the ibm? I'm okay with that. That would help move to common code. Alternatively, we could drop the vendor prefix and have common code just check for both.

Hi all,

Why not copy the method of ACPI numa? There only three elements should be configured:
1) a cpu belong to which node
2) a memory block belong to which node
3) the distance of each two nodes

The devicetree nodes of numa can be like below:

Quoted 17 lines
/ {
         ...

         numa-nodes-info {
                 node-name: node-description {
                         mem-ranges = <...>;
                         cpus-list = <...>;
                 };

                 nodes-distance {
                         distance-list = <...>;
                 };
         };

         ...
};
Quoted 9 lines

some what similar to what your are proposing is already implemented in my v2 patchset.
https://lwn.net/Articles/623920/
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/305164.html
we have went to associativity property based implementation to keep it more generic.
i do have both acpi(using linaro/hanjun's patches) and associativity based implementations on our internal tree
and tested on thunderx platform.

Great thanks!

Quoted 4 lines

i do see issue in creating numa mapping using ACPI for IOs(for example, i am not able to create numa mapping for ITS which is on each node, using ACPI tables), since ACPI spec (tables SRAT and SLIT) talks only about processor and memory.

I'm not sure why the ITS needs to know the NUMA domain, for my understanding, the interrupt will route to the correct NUMA domain using setting the affinity, ITS will configured to route it to the right GICR(cpu), so I think the ITS don't need to know which NUMA node belonging to, correct me if I missed something.

Thanks
Hanjun

#20 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Hi Hanjun,

Quoted 82 lines · Hanjun Guo

Hi Ganapatrao,

Quoted 62 lines · Ganapatrao Kulkarni

Hi Thunder,

Quoted 36 lines · Leizhen (ThunderTown)
Quoted 14 lines · Rob Herring

+benh

Quoted 9 lines · Mark Rutland

Hi,

Quoted 3 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Quoted 8 lines
Quoted 2 lines

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

So just keep the ibm? I'm okay with that. That would help move to common code. Alternatively, we could drop the vendor prefix and have common code just check for both.

Hi all,

Why not copy the method of ACPI numa? There only three elements should be configured:
1) a cpu belong to which node
2) a memory block belong to which node
3) the distance of each two nodes

The devicetree nodes of numa can be like below:

Quoted 17 lines
/ {
         ...

         numa-nodes-info {
                 node-name: node-description {
                         mem-ranges = <...>;
                         cpus-list = <...>;
                 };

                 nodes-distance {
                         distance-list = <...>;
                 };
         };

         ...
};

some what similar to what your are proposing is already implemented in my v2 patchset.
https://lwn.net/Articles/623920/

Quoted 6 lines

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/305164.html
we have went to associativity property based implementation to keep it more generic.
i do have both acpi(using linaro/hanjun's patches) and associativity based implementations on our internal tree
and tested on thunderx platform.

Great thanks!

Quoted 4 lines

i do see issue in creating numa mapping using ACPI for IOs(for example, i am not able to create numa mapping for ITS which is on each node, using ACPI tables), since ACPI spec (tables SRAT and SLIT) talks only about processor and memory.

Quoted 5 lines

I'm not sure why the ITS needs to know the NUMA domain, for my understanding, the interrupt will route to the correct NUMA domain using setting the affinity, ITS will configured to route it to the right GICR(cpu), so I think the ITS don't need to know which NUMA node belonging to, correct me if I missed something.

IIUC, GICR/collection is per cpu and can be mapped to numa node using cpu to node mapping.
However there are multiple its in multi-socket platform(at-least one its per socket),
knowing its to numa node mapping will help in routing(optimal) the interrupts to any one of GICR/collections of that node Hence, we need to find which its belongs to which socket/node using dt. same applies to pci bus too.

Quoted 3 lines

Thanks
Hanjun

thanks
Ganapat

#21 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Hi Thunder,

Quoted 46 lines · Ganapatrao Kulkarni

Hi Hanjun,

Quoted 43 lines · Hanjun Guo

Hi Ganapatrao,

Quoted 39 lines · Ganapatrao Kulkarni

Hi Thunder,

Quoted 34 lines · Leizhen (ThunderTown)
Quoted 14 lines · Rob Herring

+benh

Quoted 9 lines · Mark Rutland

Hi,

Quoted 3 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Quoted 8 lines
Quoted 2 lines

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

So just keep the ibm? I'm okay with that. That would help move to common code. Alternatively, we could drop the vendor prefix and have common code just check for both.

Hi all,

Why not copy the method of ACPI numa? There only three elements should be configured:
1) a cpu belong to which node
2) a memory block belong to which node
3) the distance of each two nodes

I too thought acpi only defines mapping for cpu and memory to numa nodes and no specification to define for IOs.
however after going through the x86 implementation, i can see there is provision for mapping IOs to numa node in acpi.
in x86 code, function pci_acpi_scan_root calls acpi_get_node to get associated node for pci bus using _PXM object.
it imply there is entry in acpi tables to map pci bus for numa node(proximity domain).
so in dt also, we should have binding to define cpu, memory and IOs to node mapping.

Quoted 53 lines
Quoted 39 lines
Quoted 23 lines
Quoted 19 lines

The devicetree nodes of numa can be like below:

/ {
         ...

         numa-nodes-info {
                 node-name: node-description {
                         mem-ranges = <...>;
                         cpus-list = <...>;
                 };

                 nodes-distance {
                         distance-list = <...>;
                 };
         };

         ...
};

some what similar to what your are proposing is already implemented in my v2 patchset.
https://lwn.net/Articles/623920/

Quoted 6 lines

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/305164.html
we have went to associativity property based implementation to keep it more generic.
i do have both acpi(using linaro/hanjun's patches) and associativity based implementations on our internal tree
and tested on thunderx platform.

Great thanks!

Quoted 4 lines

i do see issue in creating numa mapping using ACPI for IOs(for example, i am not able to create numa mapping for ITS which is on each node, using ACPI tables), since ACPI spec (tables SRAT and SLIT) talks only about processor and memory.

Quoted 5 lines

I'm not sure why the ITS needs to know the NUMA domain, for my understanding, the interrupt will route to the correct NUMA domain using setting the affinity, ITS will configured to route it to the right GICR(cpu), so I think the ITS don't need to know which NUMA node belonging to, correct me if I missed something.

IIUC, GICR/collection is per cpu and can be mapped to numa node using cpu to node mapping.
However there are multiple its in multi-socket platform(at-least one its per socket),
knowing its to numa node mapping will help in routing(optimal) the interrupts to any one of GICR/collections of that node Hence, we need to find which its belongs to which socket/node using dt. same applies to pci bus too.

Quoted 1 line
Quoted 5 lines
Quoted 2 lines

Thanks
Hanjun

thanks
Ganapat

thanks
Ganapat

#22 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Quoted 51 lines · Ganapatrao Kulkarni

Hi Thunder,

Quoted 46 lines · Ganapatrao Kulkarni

Hi Hanjun,

Quoted 43 lines · Hanjun Guo

Hi Ganapatrao,

Quoted 39 lines · Ganapatrao Kulkarni

Hi Thunder,

Quoted 34 lines · Leizhen (ThunderTown)
Quoted 14 lines · Rob Herring

+benh

Quoted 9 lines · Mark Rutland

Hi,

Quoted 3 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Quoted 8 lines
Quoted 2 lines

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

So just keep the ibm? I'm okay with that. That would help move to common code. Alternatively, we could drop the vendor prefix and have common code just check for both.

Hi all,

Why not copy the method of ACPI numa? There only three elements should be configured:
1) a cpu belong to which node
2) a memory block belong to which node
3) the distance of each two nodes

Quoted 10 lines

I too thought acpi only defines mapping for cpu and memory to numa nodes and no specification to define for IOs.
however after going through the x86 implementation, i can see there is provision for mapping IOs to numa node in acpi.
in x86 code, function pci_acpi_scan_root calls acpi_get_node to get associated node for pci bus using _PXM object.
it imply there is entry in acpi tables to map pci bus for numa node(proximity domain).
so in dt also, we should have binding to define cpu, memory and IOs to node mapping.

Yes, we should implement of_node_to_nid, to support device driver use dev_to_node.

I have added description about it, in the reply to Benjamin Herrenschmidt, at 2015/8/31 9:46.

Quoted 63 lines
Quoted 53 lines
Quoted 39 lines
Quoted 23 lines
Quoted 19 lines

The devicetree nodes of numa can be like below:

/ {
         ...

         numa-nodes-info {
                 node-name: node-description {
                         mem-ranges = <...>;
                         cpus-list = <...>;
                 };

                 nodes-distance {
                         distance-list = <...>;
                 };
         };

         ...
};

some what similar to what your are proposing is already implemented in my v2 patchset.
https://lwn.net/Articles/623920/

Quoted 6 lines

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/305164.html
we have went to associativity property based implementation to keep it more generic.
i do have both acpi(using linaro/hanjun's patches) and associativity based implementations on our internal tree
and tested on thunderx platform.

Great thanks!

Quoted 4 lines

i do see issue in creating numa mapping using ACPI for IOs(for example, i am not able to create numa mapping for ITS which is on each node, using ACPI tables), since ACPI spec (tables SRAT and SLIT) talks only about processor and memory.

Quoted 5 lines

I'm not sure why the ITS needs to know the NUMA domain, for my understanding, the interrupt will route to the correct NUMA domain using setting the affinity, ITS will configured to route it to the right GICR(cpu), so I think the ITS don't need to know which NUMA node belonging to, correct me if I missed something.

IIUC, GICR/collection is per cpu and can be mapped to numa node using cpu to node mapping.
However there are multiple its in multi-socket platform(at-least one its per socket),
knowing its to numa node mapping will help in routing(optimal) the interrupts to any one of GICR/collections of that node Hence, we need to find which its belongs to which socket/node using dt. same applies to pci bus too.

Quoted 1 line
Quoted 5 lines
Quoted 2 lines

Thanks
Hanjun

thanks
Ganapat

thanks
Ganapat

.

#23 lore raw

Re: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.

In reply to Mark Rutland

Hi Mark,

I have tried to answer your comments, in the meantime we are waiting for Ben to share the details.

Quoted 6 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Quoted 8 lines

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

However, (somewhat counter to that) I'm also concerned that this isn't sufficient for systems we're beginning to see today (more on that below), so I don't think a simple copy of ibm,associativity is good enough.

it is just copy right now, however it can evolve when we come across more arm64 numa platforms

Quoted 43 lines
Quoted 5 lines
---
 Documentation/devicetree/bindings/arm/numa.txt | 212

+++++++++++++++++++++++++

Review

Quoted 4 lines
 1 file changed, 212 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
(quoted diff) +0 -0

b/Documentation/devicetree/bindings/arm/numa.txt

Documentation/devicetree/bindings/arm/numa.txt

Quoted 6 lines

new file mode 100644
index 0000000..dc3ef86

Documentation/devicetree/bindings/arm/numa.txt new file +0 -0
@@ -0,0 +1,212 @@

+==============================================================================

Documentation/devicetree/bindings/arm/numa.txt line 2

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
+NUMA binding description.

+==============================================================================

Documentation/devicetree/bindings/arm/numa.txt line 2

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
+

+==============================================================================

Documentation/devicetree/bindings/arm/numa.txt line 6

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
+1 - Introduction

+==============================================================================

Documentation/devicetree/bindings/arm/numa.txt line 5

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Systems employing a Non Uniform Memory Access (NUMA) architecture

contain

Documentation/devicetree/bindings/arm/numa.txt line 6

Quoted 1 line
Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
+collections of hardware resources including processors, memory, and I/O

buses,

Documentation/devicetree/bindings/arm/numa.txt line 8

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is generally

faster

Documentation/devicetree/bindings/arm/numa.txt line 16

Quoted 5 lines
Documentation/devicetree/bindings/arm/numa.txt new file +4 -0
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node
+topology information to OS.
+

+==============================================================================

Documentation/devicetree/bindings/arm/numa.txt line 18

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
+2 - arm,associativity
Quoted 9 lines

+==============================================================================

Documentation/devicetree/bindings/arm/numa.txt line 15

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to

to be

Documentation/devicetree/bindings/arm/numa.txt line 22

Quoted 1 line
Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an arm,associativity property being assumed to share that value?

yes there is inheritance and respective bus drivers should take care of it, like pci driver does at present.

Quoted 7 lines

Documentation/devicetree/bindings/arm/numa.txt line 18

Quoted 3 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+arm,associativity property is set of 32-bit integers which defines

level of

s/set/list/ -- the order is important.

ok

Quoted 6 lines

Documentation/devicetree/bindings/arm/numa.txt

Quoted 5 lines
Documentation/devicetree/bindings/arm/numa.txt new file +4 -0
+topology and boundary in the system at which a significant difference in
+performance can be measured between cross-device accesses within
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within the

system,

Quoted 7 lines

Documentation/devicetree/bindings/arm/numa.txt line 23

Quoted 1 line
Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
+while the last cell enumerates the individual devices, such as an SMT

thread

Documentation/devicetree/bindings/arm/numa.txt line 30

Quoted 1 line
Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative distances at all. That seems like an oversight.

distance is computed, will add the details to document.
local nodes will have distance as 10(LOCAL_DISTANCE) and every level, the distance multiplies by 2.
for example, for level 1 numa topology, distance from local node to remote node will be 20.

Quoted 6 lines

Additionally, I'm somewhat unclear on how what you'd be expected to provide for this property in cases like ring or mesh interconnects, where there isn't a strict hierarchy (see systems with ARM's own CCN, or Tilera's TILE-Mx), but there is some measure of closeness.

IIUC, as per ARMs CCN architecture, all core/clusters are at equal distance of DDR, i dont see any NUMA topology.
however, if there are 2 SoC connected thorough the CCN, then it is very much similar to cavium topology.

Must all of these have the same length? If so, why not have a

Quoted 3 lines

#(whatever)-cells property in the root to describe the expected length? If not, how are they to be interpreted relative to each other?

yes, all are of default size.
IMHO, there is no need to add cells property.

Quoted 10 lines

Documentation/devicetree/bindings/arm/numa.txt line 26

Quoted 3 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+ex:

s/ex/Example:/, please. There's no need to contract that.

Documentation/devicetree/bindings/arm/numa.txt line 35

Quoted 4 lines
Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+       /* board 0, socket 0, cluster 0, core 0  thread 0 */
+       arm,associativity = <0 0 0 0 0>;
+
Quoted 9 lines

+==============================================================================

Documentation/devicetree/bindings/arm/numa.txt line 37

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
+3 - arm,associativity-reference-points

+==============================================================================

Documentation/devicetree/bindings/arm/numa.txt line 31

Quoted 1 line
Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
+This property is a set of 32-bit integers, each representing an index

into

Likeise, s/set/list/

ok

Quoted 10 lines

Documentation/devicetree/bindings/arm/numa.txt line 33

Quoted 3 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant

boundaries.

Documentation/devicetree/bindings/arm/numa.txt line 42

Quoted 1 line
Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
+There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property is already ordered from most significant to least significant per its description.

first entry in arm,associativity-reference-points is used to find which entry in associativity defines node id.
also entries in arm,associativity-reference-points defines, how many entries(depth) in associativity can be used to calculate node distance
in both level 1 and multi level(hierarchical) numa topology.

Quoted 7 lines

What does this property achieve?

The description also doesn't describe where this property is expected to live. The example isn't sufficient to disambiguate that, especially as it seems like a trivial case.

sure, will add one more example to describe the
arm,associativity-reference-points

Quoted 4 lines

Is this only expected at the root of the tree? Can it be re-defined in sub-nodes?

yes it is defined only at the root.

Quoted 6 lines

Documentation/devicetree/bindings/arm/numa.txt line 36

Quoted 3 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Ex:

s/Ex/Example:/, please

sure.

Quoted 50 lines

Documentation/devicetree/bindings/arm/numa.txt line 38

Quoted 3 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+       arm,associativity-reference-points = <0 1>;
+       The board Id(index 0) used first to calculate the associativity

(node

Documentation/devicetree/bindings/arm/numa.txt line 58

Quoted 13 lines
Documentation/devicetree/bindings/arm/numa.txt new file +12 -0
+       distance), then follows the  socket id(index 1).
+
+       arm,associativity-reference-points = <1 0>;
+       The socket Id(index 1) used first to calculate the associativity,
+       then follows the board id(index 0).
+
+       arm,associativity-reference-points = <0>;
+       Only the board Id(index 0) used to calculate the associativity.
+
+       arm,associativity-reference-points = <1>;
+       Only socket Id(index 1) used to calculate the associativity.
+

+==============================================================================

Documentation/devicetree/bindings/arm/numa.txt line 60

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
+4 - Example dts

+==============================================================================

Documentation/devicetree/bindings/arm/numa.txt line 53

Quoted 2 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Example: 2 Node system consists of 2 boards and each board having one

socket

Quoted 26 lines
Documentation/devicetree/bindings/arm/numa.txt new file +26 -0
+and 8 core in each socket.
+
+       arm,associativity-reference-points = <0>;
+
+       memory@00c00000 {
+               device_type = "memory";
+               reg = <0x0 0x00c00000 0x0 0x80000000>;
+               /* board 0, socket 0, no specific core */
+               arm,associativity = <0 0 0xffff>;
+       };
+
+       memory@10000000000 {
+               device_type = "memory";
+               reg = <0x100 0x00000000 0x0 0x80000000>;
+               /* board 1, socket 0, no specific core */
+               arm,associativity = <1 0 0xffff>;
+       };
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu@000 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x000>;
Quoted 9 lines

Documentation/devicetree/bindings/arm/numa.txt line 92

Quoted 3 lines
Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+                       enable-method = "psci";
+                       /* board 0, socket 0, core 0*/
+                       arm,associativity = <0 0 0>;

We should specify w.r.t. memory and CPUs how the property is expected to be used (e.g. in the CPU nodes rather than the cpu-map, with separate memory nodes, etc). The generic description of arm,associativity isn't sufficient to limit confusion there.

ok, will add the details like which nodes can use this property.

Quoted 4 lines

Thanks,
Mark.

thanks
Ganapat

#24 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

(sending again, by mistake it was set to html mode)

Quoted 264 lines · Ganapatrao Kulkarni

Hi Mark,

I have tried to answer your comments, in the meantime we are waiting for Ben to share the details.

Quoted 7 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Quoted 7 lines

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

However, (somewhat counter to that) I'm also concerned that this isn't sufficient for systems we're beginning to see today (more on that below), so I don't think a simple copy of ibm,associativity is good enough.

it is just copy right now, however it can evolve when we come across more arm64 numa platforms

Quoted 44 lines
Quoted 44 lines
---
 Documentation/devicetree/bindings/arm/numa.txt | 212
+++++++++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
Documentation/devicetree/bindings/arm/numa.txt new file +9 -0
new file mode 100644
index 0000000..dc3ef86
@@ -0,0 +1,212 @@
 
+==============================================================================
+NUMA binding description.
 
+==============================================================================
+
 
+==============================================================================
+1 - Introduction
 
+==============================================================================
+
+Systems employing a Non Uniform Memory Access (NUMA) architecture

contain
+collections of hardware resources including processors, memory, and I/O buses,

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is generally

faster

Documentation/devicetree/bindings/arm/numa.txt new file +6 -0
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node
+topology information to OS.
+
 
+==============================================================================
+2 - arm,associativity
Quoted 8 lines
Quoted 5 lines

+==============================================================================

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to

to be
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an arm,associativity property being assumed to share that value?

yes there is inheritance and respective bus drivers should take care of it, like pci driver does at present.

Quoted 7 lines
Quoted 5 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+arm,associativity property is set of 32-bit integers which defines

level of

s/set/list/ -- the order is important.

ok

Quoted 14 lines
Quoted 11 lines

+topology and boundary in the system at which a significant difference in

Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+performance can be measured between cross-device accesses within
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within the

system,
+while the last cell enumerates the individual devices, such as an SMT thread
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative distances at all. That seems like an oversight.

distance is computed, will add the details to document.
local nodes will have distance as 10(LOCAL_DISTANCE) and every level, the distance multiplies by 2.
for example, for level 1 numa topology, distance from local node to remote node will be 20.

Quoted 6 lines

Additionally, I'm somewhat unclear on how what you'd be expected to provide for this property in cases like ring or mesh interconnects, where there isn't a strict hierarchy (see systems with ARM's own CCN, or Tilera's TILE-Mx), but there is some measure of closeness.

IIUC, as per ARMs CCN architecture, all core/clusters are at equal distance of DDR, i dont see any NUMA topology.
however, if there are 2 SoC connected thorough the CCN, then it is very much similar to cavium topology.

Quoted 3 lines

Must all of these have the same length? If so, why not have a #(whatever)-cells property in the root to describe the expected length? If not, how are they to be interpreted relative to each other?

yes, all are of default size.
IMHO, there is no need to add cells property.

Quoted 11 lines

Documentation/devicetree/bindings/arm/numa.txt

Quoted 4 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+ex:

s/ex/Example:/, please. There's no need to contract that.

Quoted 4 lines
Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+       /* board 0, socket 0, cluster 0, core 0  thread 0 */
+       arm,associativity = <0 0 0 0 0>;
+
Quoted 8 lines
Quoted 6 lines

+==============================================================================
+3 - arm,associativity-reference-points

+==============================================================================
+This property is a set of 32-bit integers, each representing an index into

Likeise, s/set/list/

ok

Quoted 10 lines
Quoted 6 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant

boundaries.
+There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property is already ordered from most significant to least significant per its description.

first entry in arm,associativity-reference-points is used to find which entry in associativity defines node id.
also entries in arm,associativity-reference-points defines, how many entries(depth) in associativity can be used to calculate node distance
in both level 1 and multi level(hierarchical) numa topology.

Quoted 7 lines

What does this property achieve?

The description also doesn't describe where this property is expected to live. The example isn't sufficient to disambiguate that, especially as it seems like a trivial case.

sure, will add one more example to describe the
arm,associativity-reference-points

Quoted 4 lines

Is this only expected at the root of the tree? Can it be re-defined in sub-nodes?

yes it is defined only at the root.

Quoted 6 lines

Documentation/devicetree/bindings/arm/numa.txt

Quoted 4 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Ex:

s/Ex/Example:/, please

sure.

Quoted 52 lines
Quoted 52 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+       arm,associativity-reference-points = <0 1>;
+       The board Id(index 0) used first to calculate the associativity

(node

Documentation/devicetree/bindings/arm/numa.txt new file +4 -0
+       distance), then follows the  socket id(index 1).
+
+       arm,associativity-reference-points = <1 0>;
+       The socket Id(index 1) used first to calculate the

associativity,

Documentation/devicetree/bindings/arm/numa.txt new file +13 -0
+       then follows the board id(index 0).
+
+       arm,associativity-reference-points = <0>;
+       Only the board Id(index 0) used to calculate the associativity.
+
+       arm,associativity-reference-points = <1>;
+       Only socket Id(index 1) used to calculate the associativity.
+
 
+==============================================================================
+4 - Example dts
 
+==============================================================================
+
+Example: 2 Node system consists of 2 boards and each board having one

socket

Documentation/devicetree/bindings/arm/numa.txt new file +26 -0
+and 8 core in each socket.
+
+       arm,associativity-reference-points = <0>;
+
+       memory at 00c00000 {
+               device_type = "memory";
+               reg = <0x0 0x00c00000 0x0 0x80000000>;
+               /* board 0, socket 0, no specific core */
+               arm,associativity = <0 0 0xffff>;
+       };
+
+       memory at 10000000000 {
+               device_type = "memory";
+               reg = <0x100 0x00000000 0x0 0x80000000>;
+               /* board 1, socket 0, no specific core */
+               arm,associativity = <1 0 0xffff>;
+       };
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu at 000 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x000>;
Quoted 8 lines

Documentation/devicetree/bindings/arm/numa.txt line 92

Quoted 3 lines
Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+                       enable-method = "psci";
+                       /* board 0, socket 0, core 0*/
+                       arm,associativity = <0 0 0>;

We should specify w.r.t. memory and CPUs how the property is expected to be used (e.g. in the CPU nodes rather than the cpu-map, with separate memory nodes, etc). The generic description of arm,associativity isn't sufficient to limit confusion there.

ok, will add the details like which nodes can use this property.

Quoted 4 lines

Thanks,
Mark.

thanks
Ganapat

#25 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Quoted 1 line · Ganapatrao Kulkarni

(sending again, by mistake it was set to html mode)

I sorry, I was trying to get OpenPower to move faster & release PAPR publicly but it looks like it's going to take a bit longer, so I'll try to write a summary in the next couple of days.

Ben.

Quoted 324 lines
Quoted 322 lines · Ganapatrao Kulkarni

Hi Mark,

I have tried to answer your comments, in the meantime we are waiting for Ben
to share the details.

On Fri, Aug 28, 2015 at 6:02 PM, Mark Rutland <[email protected]

Quoted 13 lines

wrote:

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Given this is just a copy of ibm,associativity, I'm not sure I see much
point in renaming the properties.

Quoted 6 lines

However, (somewhat counter to that) I'm also concerned that this isn't
sufficient for systems we're beginning to see today (more on that below), so I don't think a simple copy of ibm,associativity is good
enough.

it is just copy right now, however it can evolve when we come across more
arm64 numa platforms

Quoted 56 lines
Quoted 56 lines

Signed-off-by: Ganapatrao Kulkarni <
gkulkarni at caviumnetworks.com>

---
 Documentation/devicetree/bindings/arm/numa.txt | 212
+++++++++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644

Documentation/devicetree/bindings/arm/numa.txt

Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
new file mode 100644
index 0000000..dc3ef86
@@ -0,0 +1,212 @@
 
+==============================================================

================
+NUMA binding description.

+==============================================================
================
+

+==============================================================
================
+1 - Introduction

+==============================================================
================

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Systems employing a Non Uniform Memory Access (NUMA)

architecture
contain
+collections of hardware resources including processors, memory, and I/O
buses,

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is

generally
faster
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node

Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+topology information to OS.
+
 
+==============================================================

================
+2 - arm,associativity

Quoted 11 lines
Quoted 7 lines

+==============================================================
================

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which

needs to
to be
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an
arm,associativity property being assumed to share that value?

yes there is inheritance and respective bus drivers should take care of it,
like pci driver does at present.

Quoted 8 lines
Quoted 6 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+arm,associativity property is set of 32-bit integers which

defines
level of

s/set/list/ -- the order is important.

ok

Quoted 11 lines
Quoted 11 lines

+topology and boundary in the system at which a significant difference
in
+performance can be measured between cross-device accesses within

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within

the
system,

Quoted 8 lines
Quoted 4 lines

+while the last cell enumerates the individual devices, such as an SMT
thread
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative
distances at all. That seems like an oversight.

distance is computed, will add the details to document. local nodes will have distance as 10(LOCAL_DISTANCE) and every level, the
distance multiplies by 2.
for example, for level 1 numa topology, distance from local node to remote
node will be 20.

Quoted 9 lines

Additionally, I'm somewhat unclear on how what you'd be expected to
provide for this property in cases like ring or mesh interconnects,
where there isn't a strict hierarchy (see systems with ARM's own CCN, or
Tilera's TILE-Mx), but there is some measure of closeness.

IIUC, as per ARMs CCN architecture, all core/clusters are at equal distance
of DDR, i dont see any NUMA topology.
however, if there are 2 SoC connected thorough the CCN, then it is very much
similar to cavium topology.

Quoted 4 lines

Must all of these have the same length? If so, why not have a #(whatever)-cells property in the root to describe the expected length?
If not, how are they to be interpreted relative to each other?

yes, all are of default size.
IMHO, there is no need to add cells property.

Quoted 15 lines

Documentation/devicetree/bindings/arm/numa.txt

Quoted 4 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+ex:

s/ex/Example:/, please. There's no need to contract that.

Quoted 8 lines
Documentation/devicetree/bindings/arm/numa.txt new file +4 -0
+       /* board 0, socket 0, cluster 0, core 0  thread 0 */
+       arm,associativity = <0 0 0 0 0>;
+
 
+==============================================================

================
+3 - arm,associativity-reference-points

Quoted 7 lines
Quoted 5 lines

+==============================================================
================
+This property is a set of 32-bit integers, each representing an index
into

Likeise, s/set/list/

ok

Quoted 14 lines
Quoted 8 lines

+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant
boundaries.
+There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property
is already ordered from most significant to least significant per its
description.

first entry in arm,associativity-reference-points is used to find which
entry in associativity defines node id.
also entries in arm,associativity-reference-points defines, how many entries(depth) in associativity can be used to calculate node
distance
in both level 1 and multi level(hierarchical) numa topology.

Quoted 9 lines

What does this property achieve?

The description also doesn't describe where this property is expected to
live. The example isn't sufficient to disambiguate that, especially as
it seems like a trivial case.

sure, will add one more example to describe the
arm,associativity-reference-points

Quoted 5 lines

Is this only expected at the root of the tree? Can it be re -defined in
sub-nodes?

yes it is defined only at the root.

Quoted 6 lines

Documentation/devicetree/bindings/arm/numa.txt

Quoted 4 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Ex:

s/Ex/Example:/, please

sure.

Quoted 62 lines
Quoted 51 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+       arm,associativity-reference-points = <0 1>;
+       The board Id(index 0) used first to calculate the

associativity
(node

Documentation/devicetree/bindings/arm/numa.txt new file +4 -0
+       distance), then follows the  socket id(index 1).
+
+       arm,associativity-reference-points = <1 0>;
+       The socket Id(index 1) used first to calculate the

associativity,

Documentation/devicetree/bindings/arm/numa.txt new file +4 -0
+       then follows the board id(index 0).
+
+       arm,associativity-reference-points = <0>;
+       Only the board Id(index 0) used to calculate the

associativity.

Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+
+       arm,associativity-reference-points = <1>;
+       Only socket Id(index 1) used to calculate the

associativity.
+

+==============================================================
================
+4 - Example dts

+==============================================================
================

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Example: 2 Node system consists of 2 boards and each board

having one
socket

Documentation/devicetree/bindings/arm/numa.txt new file +19 -0
+and 8 core in each socket.
+
+       arm,associativity-reference-points = <0>;
+
+       memory at 00c00000 {
+               device_type = "memory";
+               reg = <0x0 0x00c00000 0x0 0x80000000>;
+               /* board 0, socket 0, no specific core */
+               arm,associativity = <0 0 0xffff>;
+       };
+
+       memory at 10000000000 {
+               device_type = "memory";
+               reg = <0x100 0x00000000 0x0 0x80000000>;
+               /* board 1, socket 0, no specific core */
+               arm,associativity = <1 0 0xffff>;
+       };
+
+       cpus {

Documentation/devicetree/bindings/arm/numa.txt line 92

Quoted 10 lines
Documentation/devicetree/bindings/arm/numa.txt new file +10 -0
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu at 000 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x000>;
+                       enable-method = "psci";
+                       /* board 0, socket 0, core 0*/
+                       arm,associativity = <0 0 0>;
Quoted 7 lines

We should specify w.r.t. memory and CPUs how the property is expected to
be used (e.g. in the CPU nodes rather than the cpu-map, with separate
memory nodes, etc). The generic description of arm,associativity isn't
sufficient to limit confusion there.

ok, will add the details like which nodes can use this property.

Quoted 4 lines

Thanks,
Mark.

thanks
Ganapat

#26 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

In reply to Ganapatrao Kulkarni
Quoted 1 line · Ganapatrao Kulkarni

(sending again, by mistake it was set to html mode)

The representation consists of a hierarchy of domains, the idea being that resources are grouped in domains of similar average performance relative to each other.

The platform decides which "levels" of that hierarchy are significant.

The "ibm,associativity" property allows to determine the associatitivy between two resources (ie nodes) at a given level.

Unfortunately that property went through changes, so another property in the DT (ibm,architecture-vec-5) contains, among a bunch of other things, a bit indicating which form of the ibm,associativity property is used. I'm going to stick to the new "form 1" in this description.

The ibm,associativity contains one or more lists of numbers (32-bit cells), which represent the domains:

	< C1 , L1_1, L1_2, ... , C2, L2_1, L2_2, ... >

Where C1 (count 1) is the number of items for list 1, and L1_1, L1_2, ... L1_C1 are the items for list 1, and same for C2/L2.

The entries in those lists are domain numbers from the highest level of grouping to the lowest (successive numbers are sub divisions) for example drawer#, socket#, chip#, core#... with the lowest level being the actual resource itself. So within a domain that last number is generally unique.

Different resources can have different number of levels, for example if we have a grouping of node,socket,chip,core, a CPU core node would have a list with all 4 but a memory controller on a chip might have only the first 3.

This is an important statement in the spec:

<<
The user of this information is cautioned not to imply
any specific physical/logical significance of the various intermediate levels.

Quoted 1 line
Quoted 1 line

We can have multiple lists because a given resource can be connected via multiple path in the same platform.

That means that to properly calculate the distance to another resource, all the path need to be looked at (assuming the HW will pick the shortest).

Additionally, to help the OS, another property "ibm,associativity -reference-points" property indicates which levels (which indices in the above lists) are of biggest significance to the platform. This can typically be used by an OS to decide what to consider a "NUMA node" if the OS cannot operate on distances alone. This is a list of 1-based numbers representing indices in the associativity list. They should be in order of significance of the boundary.

Finally, the ibm,max-associativity-domains (in the /rtas node on pseries) is an array of cells < C, M1, M2, ... MC > (first is count) containing for each domain/level the max number supported by the platform.

Ben.

Quoted 324 lines
Quoted 322 lines · Ganapatrao Kulkarni

Hi Mark,

I have tried to answer your comments, in the meantime we are waiting for Ben
to share the details.

On Fri, Aug 28, 2015 at 6:02 PM, Mark Rutland <[email protected]

Quoted 13 lines

wrote:

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Given this is just a copy of ibm,associativity, I'm not sure I see much
point in renaming the properties.

Quoted 6 lines

However, (somewhat counter to that) I'm also concerned that this isn't
sufficient for systems we're beginning to see today (more on that below), so I don't think a simple copy of ibm,associativity is good
enough.

it is just copy right now, however it can evolve when we come across more
arm64 numa platforms

Quoted 56 lines
Quoted 56 lines

Signed-off-by: Ganapatrao Kulkarni <
gkulkarni at caviumnetworks.com>

---
 Documentation/devicetree/bindings/arm/numa.txt | 212
+++++++++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644

Documentation/devicetree/bindings/arm/numa.txt

Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
new file mode 100644
index 0000000..dc3ef86
@@ -0,0 +1,212 @@
 
+==============================================================

================
+NUMA binding description.

+==============================================================
================
+

+==============================================================
================
+1 - Introduction

+==============================================================
================

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Systems employing a Non Uniform Memory Access (NUMA)

architecture
contain
+collections of hardware resources including processors, memory, and I/O
buses,

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is

generally
faster
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node

Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+topology information to OS.
+
 
+==============================================================

================
+2 - arm,associativity

Quoted 11 lines
Quoted 7 lines

+==============================================================
================

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which

needs to
to be
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an
arm,associativity property being assumed to share that value?

yes there is inheritance and respective bus drivers should take care of it,
like pci driver does at present.

Quoted 8 lines
Quoted 6 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+arm,associativity property is set of 32-bit integers which

defines
level of

s/set/list/ -- the order is important.

ok

Quoted 11 lines
Quoted 11 lines

+topology and boundary in the system at which a significant difference
in
+performance can be measured between cross-device accesses within

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within

the
system,

Quoted 8 lines
Quoted 4 lines

+while the last cell enumerates the individual devices, such as an SMT
thread
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative
distances at all. That seems like an oversight.

distance is computed, will add the details to document. local nodes will have distance as 10(LOCAL_DISTANCE) and every level, the
distance multiplies by 2.
for example, for level 1 numa topology, distance from local node to remote
node will be 20.

Quoted 9 lines

Additionally, I'm somewhat unclear on how what you'd be expected to
provide for this property in cases like ring or mesh interconnects,
where there isn't a strict hierarchy (see systems with ARM's own CCN, or
Tilera's TILE-Mx), but there is some measure of closeness.

IIUC, as per ARMs CCN architecture, all core/clusters are at equal distance
of DDR, i dont see any NUMA topology.
however, if there are 2 SoC connected thorough the CCN, then it is very much
similar to cavium topology.

Quoted 4 lines

Must all of these have the same length? If so, why not have a #(whatever)-cells property in the root to describe the expected length?
If not, how are they to be interpreted relative to each other?

yes, all are of default size.
IMHO, there is no need to add cells property.

Quoted 15 lines

Documentation/devicetree/bindings/arm/numa.txt

Quoted 4 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+ex:

s/ex/Example:/, please. There's no need to contract that.

Quoted 8 lines
Documentation/devicetree/bindings/arm/numa.txt new file +4 -0
+       /* board 0, socket 0, cluster 0, core 0  thread 0 */
+       arm,associativity = <0 0 0 0 0>;
+
 
+==============================================================

================
+3 - arm,associativity-reference-points

Quoted 7 lines
Quoted 5 lines

+==============================================================
================
+This property is a set of 32-bit integers, each representing an index
into

Likeise, s/set/list/

ok

Quoted 14 lines
Quoted 8 lines

+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant
boundaries.
+There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property
is already ordered from most significant to least significant per its
description.

first entry in arm,associativity-reference-points is used to find which
entry in associativity defines node id.
also entries in arm,associativity-reference-points defines, how many entries(depth) in associativity can be used to calculate node
distance
in both level 1 and multi level(hierarchical) numa topology.

Quoted 9 lines

What does this property achieve?

The description also doesn't describe where this property is expected to
live. The example isn't sufficient to disambiguate that, especially as
it seems like a trivial case.

sure, will add one more example to describe the
arm,associativity-reference-points

Quoted 5 lines

Is this only expected at the root of the tree? Can it be re -defined in
sub-nodes?

yes it is defined only at the root.

Quoted 6 lines

Documentation/devicetree/bindings/arm/numa.txt

Quoted 4 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Ex:

s/Ex/Example:/, please

sure.

Quoted 62 lines
Quoted 51 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+       arm,associativity-reference-points = <0 1>;
+       The board Id(index 0) used first to calculate the

associativity
(node

Documentation/devicetree/bindings/arm/numa.txt new file +4 -0
+       distance), then follows the  socket id(index 1).
+
+       arm,associativity-reference-points = <1 0>;
+       The socket Id(index 1) used first to calculate the

associativity,

Documentation/devicetree/bindings/arm/numa.txt new file +4 -0
+       then follows the board id(index 0).
+
+       arm,associativity-reference-points = <0>;
+       Only the board Id(index 0) used to calculate the

associativity.

Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+
+       arm,associativity-reference-points = <1>;
+       Only socket Id(index 1) used to calculate the

associativity.
+

+==============================================================
================
+4 - Example dts

+==============================================================
================

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Example: 2 Node system consists of 2 boards and each board

having one
socket

Documentation/devicetree/bindings/arm/numa.txt new file +19 -0
+and 8 core in each socket.
+
+       arm,associativity-reference-points = <0>;
+
+       memory at 00c00000 {
+               device_type = "memory";
+               reg = <0x0 0x00c00000 0x0 0x80000000>;
+               /* board 0, socket 0, no specific core */
+               arm,associativity = <0 0 0xffff>;
+       };
+
+       memory at 10000000000 {
+               device_type = "memory";
+               reg = <0x100 0x00000000 0x0 0x80000000>;
+               /* board 1, socket 0, no specific core */
+               arm,associativity = <1 0 0xffff>;
+       };
+
+       cpus {

Documentation/devicetree/bindings/arm/numa.txt line 92

Quoted 10 lines
Documentation/devicetree/bindings/arm/numa.txt new file +10 -0
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu at 000 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x000>;
+                       enable-method = "psci";
+                       /* board 0, socket 0, core 0*/
+                       arm,associativity = <0 0 0>;
Quoted 7 lines

We should specify w.r.t. memory and CPUs how the property is expected to
be used (e.g. in the CPU nodes rather than the cpu-map, with separate
memory nodes, etc). The generic description of arm,associativity isn't
sufficient to limit confusion there.

ok, will add the details like which nodes can use this property.

Quoted 4 lines

Thanks,
Mark.

thanks
Ganapat

#27 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Thanks Ben for the details.

Quoted 17 lines · Benjamin Herrenschmidt
Quoted 1 line · Ganapatrao Kulkarni

(sending again, by mistake it was set to html mode)

The representation consists of a hierarchy of domains, the idea being that resources are grouped in domains of similar average performance relative to each other.

The platform decides which "levels" of that hierarchy are significant.

The "ibm,associativity" property allows to determine the associatitivy between two resources (ie nodes) at a given level.

Unfortunately that property went through changes, so another property in the DT (ibm,architecture-vec-5) contains, among a bunch of other things, a bit indicating which form of the ibm,associativity property is used. I'm going to stick to the new "form 1" in this description.

Quoted 7 lines

The ibm,associativity contains one or more lists of numbers (32-bit cells), which represent the domains:

        < C1 , L1_1, L1_2, ... , C2, L2_1, L2_2, ... >

Where C1 (count 1) is the number of items for list 1, and L1_1, L1_2, ... L1_C1 are the items for list 1, and same for C2/L2.

can you please put some examples for more clarity.

Quoted 11 lines

The entries in those lists are domain numbers from the highest level of grouping to the lowest (successive numbers are sub divisions) for example drawer#, socket#, chip#, core#... with the lowest level being the actual resource itself. So within a domain that last number is generally unique.

Different resources can have different number of levels, for example if we have a grouping of node,socket,chip,core, a CPU core node would have a list with all 4 but a memory controller on a chip might have only the first 3.

can you please put some examples for more clarity.

Quoted 16 lines

This is an important statement in the spec:

<<
The user of this information is cautioned not to imply
any specific physical/logical significance of the various intermediate levels.

Quoted 1 line
Quoted 1 line

We can have multiple lists because a given resource can be connected via multiple path in the same platform.

That means that to properly calculate the distance to another resource, all the path need to be looked at (assuming the HW will pick the shortest).

Quoted 7 lines

Additionally, to help the OS, another property "ibm,associativity -reference-points" property indicates which levels (which indices in the above lists) are of biggest significance to the platform. This can typically be used by an OS to decide what to consider a "NUMA node" if the OS cannot operate on distances alone. This is a list of 1-based numbers representing indices in the associativity list. They should be in order of significance of the boundary.

some examples please.

Quoted 5 lines

Finally, the ibm,max-associativity-domains (in the /rtas node on pseries) is an array of cells < C, M1, M2, ... MC > (first is count) containing for each domain/level the max number supported by the platform.

max number of what/cpu?
how this helps?
please give some examples to understand this!

Quoted 327 lines

Ben.

Quoted 324 lines
Quoted 322 lines · Ganapatrao Kulkarni

Hi Mark,

I have tried to answer your comments, in the meantime we are waiting for Ben
to share the details.

On Fri, Aug 28, 2015 at 6:02 PM, Mark Rutland <[email protected]

Quoted 13 lines

wrote:

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Given this is just a copy of ibm,associativity, I'm not sure I see much
point in renaming the properties.

Quoted 6 lines

However, (somewhat counter to that) I'm also concerned that this isn't
sufficient for systems we're beginning to see today (more on that below), so I don't think a simple copy of ibm,associativity is good
enough.

it is just copy right now, however it can evolve when we come across more
arm64 numa platforms

Quoted 56 lines
Quoted 56 lines

Signed-off-by: Ganapatrao Kulkarni <
gkulkarni at caviumnetworks.com>

---
 Documentation/devicetree/bindings/arm/numa.txt | 212
+++++++++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644

Documentation/devicetree/bindings/arm/numa.txt

Documentation/devicetree/bindings/arm/numa.txt new file +1 -0
new file mode 100644
index 0000000..dc3ef86
@@ -0,0 +1,212 @@
 
+==============================================================

================
+NUMA binding description.

+==============================================================
================
+

+==============================================================
================
+1 - Introduction

+==============================================================
================

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Systems employing a Non Uniform Memory Access (NUMA)

architecture
contain
+collections of hardware resources including processors, memory, and I/O
buses,

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is

generally
faster
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node

Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+topology information to OS.
+
 
+==============================================================

================
+2 - arm,associativity

Quoted 11 lines
Quoted 7 lines

+==============================================================
================

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which

needs to
to be
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an
arm,associativity property being assumed to share that value?

yes there is inheritance and respective bus drivers should take care of it,
like pci driver does at present.

Quoted 8 lines
Quoted 6 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+arm,associativity property is set of 32-bit integers which

defines
level of

s/set/list/ -- the order is important.

ok

Quoted 11 lines
Quoted 11 lines

+topology and boundary in the system at which a significant difference
in
+performance can be measured between cross-device accesses within

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within

the
system,

Quoted 8 lines
Quoted 4 lines

+while the last cell enumerates the individual devices, such as an SMT
thread
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative
distances at all. That seems like an oversight.

distance is computed, will add the details to document. local nodes will have distance as 10(LOCAL_DISTANCE) and every level, the
distance multiplies by 2.
for example, for level 1 numa topology, distance from local node to remote
node will be 20.

Quoted 9 lines

Additionally, I'm somewhat unclear on how what you'd be expected to
provide for this property in cases like ring or mesh interconnects,
where there isn't a strict hierarchy (see systems with ARM's own CCN, or
Tilera's TILE-Mx), but there is some measure of closeness.

IIUC, as per ARMs CCN architecture, all core/clusters are at equal distance
of DDR, i dont see any NUMA topology.
however, if there are 2 SoC connected thorough the CCN, then it is very much
similar to cavium topology.

Quoted 4 lines

Must all of these have the same length? If so, why not have a #(whatever)-cells property in the root to describe the expected length?
If not, how are they to be interpreted relative to each other?

yes, all are of default size.
IMHO, there is no need to add cells property.

Quoted 15 lines

Documentation/devicetree/bindings/arm/numa.txt

Quoted 4 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+ex:

s/ex/Example:/, please. There's no need to contract that.

Quoted 8 lines
Documentation/devicetree/bindings/arm/numa.txt new file +4 -0
+       /* board 0, socket 0, cluster 0, core 0  thread 0 */
+       arm,associativity = <0 0 0 0 0>;
+
 
+==============================================================

================
+3 - arm,associativity-reference-points

Quoted 7 lines
Quoted 5 lines

+==============================================================
================
+This property is a set of 32-bit integers, each representing an index
into

Likeise, s/set/list/

ok

Quoted 14 lines
Quoted 8 lines

+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant
boundaries.
+There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property
is already ordered from most significant to least significant per its
description.

first entry in arm,associativity-reference-points is used to find which
entry in associativity defines node id.
also entries in arm,associativity-reference-points defines, how many entries(depth) in associativity can be used to calculate node
distance
in both level 1 and multi level(hierarchical) numa topology.

Quoted 9 lines

What does this property achieve?

The description also doesn't describe where this property is expected to
live. The example isn't sufficient to disambiguate that, especially as
it seems like a trivial case.

sure, will add one more example to describe the
arm,associativity-reference-points

Quoted 5 lines

Is this only expected at the root of the tree? Can it be re -defined in
sub-nodes?

yes it is defined only at the root.

Quoted 6 lines

Documentation/devicetree/bindings/arm/numa.txt

Quoted 4 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Ex:

s/Ex/Example:/, please

sure.

Quoted 62 lines
Quoted 51 lines
Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+       arm,associativity-reference-points = <0 1>;
+       The board Id(index 0) used first to calculate the

associativity
(node

Documentation/devicetree/bindings/arm/numa.txt new file +4 -0
+       distance), then follows the  socket id(index 1).
+
+       arm,associativity-reference-points = <1 0>;
+       The socket Id(index 1) used first to calculate the

associativity,

Documentation/devicetree/bindings/arm/numa.txt new file +4 -0
+       then follows the board id(index 0).
+
+       arm,associativity-reference-points = <0>;
+       Only the board Id(index 0) used to calculate the

associativity.

Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+
+       arm,associativity-reference-points = <1>;
+       Only socket Id(index 1) used to calculate the

associativity.
+

+==============================================================
================
+4 - Example dts

+==============================================================
================

Documentation/devicetree/bindings/arm/numa.txt new file +2 -0
+
+Example: 2 Node system consists of 2 boards and each board

having one
socket

Documentation/devicetree/bindings/arm/numa.txt new file +19 -0
+and 8 core in each socket.
+
+       arm,associativity-reference-points = <0>;
+
+       memory at 00c00000 {
+               device_type = "memory";
+               reg = <0x0 0x00c00000 0x0 0x80000000>;
+               /* board 0, socket 0, no specific core */
+               arm,associativity = <0 0 0xffff>;
+       };
+
+       memory at 10000000000 {
+               device_type = "memory";
+               reg = <0x100 0x00000000 0x0 0x80000000>;
+               /* board 1, socket 0, no specific core */
+               arm,associativity = <1 0 0xffff>;
+       };
+
+       cpus {

Documentation/devicetree/bindings/arm/numa.txt line 92

Quoted 10 lines
Documentation/devicetree/bindings/arm/numa.txt new file +10 -0
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu at 000 {
+                       device_type = "cpu";
+                       compatible =  "arm,armv8";
+                       reg = <0x0 0x000>;
+                       enable-method = "psci";
+                       /* board 0, socket 0, core 0*/
+                       arm,associativity = <0 0 0>;
Quoted 7 lines

We should specify w.r.t. memory and CPUs how the property is expected to
be used (e.g. in the CPU nodes rather than the cpu-map, with separate
memory nodes, etc). The generic description of arm,associativity isn't
sufficient to limit confusion there.

ok, will add the details like which nodes can use this property.

Quoted 4 lines

Thanks,
Mark.

thanks
Ganapat

thanks
Ganapat

reviewer
#28 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

In reply to Ganapatrao Kulkarni
Quoted 27 lines · Ganapatrao Kulkarni

(sending again, by mistake it was set to html mode)

Quoted 23 lines · Ganapatrao Kulkarni

Hi Mark,

I have tried to answer your comments, in the meantime we are waiting for Ben to share the details.

Quoted 7 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Quoted 7 lines

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

However, (somewhat counter to that) I'm also concerned that this isn't sufficient for systems we're beginning to see today (more on that below), so I don't think a simple copy of ibm,associativity is good enough.

it is just copy right now, however it can evolve when we come across more arm64 numa platforms

Whatever we do I suspect we'll have to evolve it as new platforms appear. As I mentioned there are contemporary NUMA ARM64 platforms (e.g. those with CCN) that I don't think we can ignore now given we'll have to cater for them.

Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
Quoted 8 lines

+==============================================================================
+2 - arm,associativity

+==============================================================================

(quoted diff) +2 -0
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to

to be
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an arm,associativity property being assumed to share that value?

Quoted 2 lines
Quoted 2 lines

yes there is inheritance and respective bus drivers should take care of it, like pci driver does at present.

Ok.

That seems counter to my initial interpretation of the wording that the property must be present on device nodes that need to be mapped to NUMA nodes.

Is there any simple way of describing the set of nodes that need this property?

Quoted 14 lines
Quoted 14 lines
Quoted 12 lines
Quoted 9 lines

+topology and boundary in the system at which a significant difference in

Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+performance can be measured between cross-device accesses within
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within the

system,
+while the last cell enumerates the individual devices, such as an SMT thread
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative distances at all. That seems like an oversight.

Quoted 5 lines
Quoted 5 lines

distance is computed, will add the details to document.
local nodes will have distance as 10(LOCAL_DISTANCE) and every level, the distance multiplies by 2.
for example, for level 1 numa topology, distance from local node to remote node will be 20.

This seems arbitrary.

Why not always have this explicitly described?

Quoted 8 lines
Quoted 8 lines
Quoted 4 lines

Additionally, I'm somewhat unclear on how what you'd be expected to provide for this property in cases like ring or mesh interconnects, where there isn't a strict hierarchy (see systems with ARM's own CCN, or Tilera's TILE-Mx), but there is some measure of closeness.

IIUC, as per ARMs CCN architecture, all core/clusters are at equal distance of DDR, i dont see any NUMA topology.

The CCN is a ring interconnect, so CPU clusters (henceforth CPUs) can be connected with differing distances to RAM instances (or devices).

Consider the simplified network below:

  +-------+      +--------+      +-------+
  | CPU 0 |------| DRAM A |------| CPU 1 |
  +-------+      +--------+      +-------+
      |                              |
      |                              |
  +--------+                     +--------+
  | DRAM B |                     | DRAM C |
  +--------+                     +--------+
      |                              |
      |                              |
  +-------+      +--------+      +-------+
  | CPU 2 |------| DRAM D |------| CPU 3 |
  +-------+      +--------+      +-------+

In this case CPUs and DRAMs are spaced evenly on the ring, but the distance between an arbitrary CPU and DRAM is not uniform.

CPU 0 can access DRAM A or DRAM B with a single hop, but accesses to DRAM C or DRAM D take three hops.

An access from CPU 0 to DRAM C could contend with accesses from CPU 1 to DRAM D, as they share hops on the ring.

There is definitely a NUMA topology here, but there's not a strict hierarchy. I don't see how you would represent this with the proposed binding.

Likewise for the mesh networks (e.g. that of TILE-Mx)

Quoted 9 lines
Quoted 9 lines

however, if there are 2 SoC connected thorough the CCN, then it is very much similar to cavium topology.

Quoted 3 lines

Must all of these have the same length? If so, why not have a #(whatever)-cells property in the root to describe the expected length? If not, how are they to be interpreted relative to each other?

yes, all are of default size.

Where that size is...?

Quoted 1 line
Quoted 1 line

IMHO, there is no need to add cells property.

That might be the case, but it's unclear from the documentation. I don't see how one would parse / verify values currently.

Quoted 10 lines
Quoted 10 lines
Quoted 8 lines
Quoted 4 lines
(quoted diff) +2 -0
+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant

boundaries.
+There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property is already ordered from most significant to least significant per its description.

Quoted 6 lines
Quoted 6 lines

first entry in arm,associativity-reference-points is used to find which entry in associativity defines node id.
also entries in arm,associativity-reference-points defines, how many entries(depth) in associativity can be used to calculate node distance
in both level 1 and multi level(hierarchical) numa topology.

I think this needs a more thorough description; I don't follow the current one.

Quoted 4 lines
Quoted 4 lines
Quoted 2 lines

Is this only expected at the root of the tree? Can it be re-defined in sub-nodes?

yes it is defined only at the root.

This needs to be stated explicitly.

I see that this being the case, *,associativity-reference-points would be a more powerful property than the #(whatever)-cells property I mentioned earlier, but a more thorough description is required.

Thanks,
Mark.

#29 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Hi Ben,

Quoted 116 lines · Mark Rutland
Quoted 27 lines · Ganapatrao Kulkarni

(sending again, by mistake it was set to html mode)

Quoted 23 lines · Ganapatrao Kulkarni

Hi Mark,

I have tried to answer your comments, in the meantime we are waiting for Ben to share the details.

Quoted 7 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Quoted 7 lines

Given this is just a copy of ibm,associativity, I'm not sure I see much point in renaming the properties.

However, (somewhat counter to that) I'm also concerned that this isn't sufficient for systems we're beginning to see today (more on that below), so I don't think a simple copy of ibm,associativity is good enough.

it is just copy right now, however it can evolve when we come across more arm64 numa platforms

Whatever we do I suspect we'll have to evolve it as new platforms appear. As I mentioned there are contemporary NUMA ARM64 platforms (e.g. those with CCN) that I don't think we can ignore now given we'll have to cater for them.

Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
Quoted 8 lines

+==============================================================================
+2 - arm,associativity

+==============================================================================

(quoted diff) +2 -0
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to

to be
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an arm,associativity property being assumed to share that value?

Quoted 2 lines
Quoted 2 lines

yes there is inheritance and respective bus drivers should take care of it, like pci driver does at present.

Ok.

That seems counter to my initial interpretation of the wording that the property must be present on device nodes that need to be mapped to NUMA nodes.

Is there any simple way of describing the set of nodes that need this property?

Quoted 14 lines
Quoted 14 lines
Quoted 12 lines
Quoted 9 lines

+topology and boundary in the system at which a significant difference in

Documentation/devicetree/bindings/arm/numa.txt new file +3 -0
+performance can be measured between cross-device accesses within
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within the

system,
+while the last cell enumerates the individual devices, such as an SMT thread
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative distances at all. That seems like an oversight.

Quoted 5 lines
Quoted 5 lines

distance is computed, will add the details to document.
local nodes will have distance as 10(LOCAL_DISTANCE) and every level, the distance multiplies by 2.
for example, for level 1 numa topology, distance from local node to remote node will be 20.

This seems arbitrary.

Why not always have this explicitly described?

Quoted 8 lines
Quoted 8 lines
Quoted 4 lines

Additionally, I'm somewhat unclear on how what you'd be expected to provide for this property in cases like ring or mesh interconnects, where there isn't a strict hierarchy (see systems with ARM's own CCN, or Tilera's TILE-Mx), but there is some measure of closeness.

IIUC, as per ARMs CCN architecture, all core/clusters are at equal distance of DDR, i dont see any NUMA topology.

The CCN is a ring interconnect, so CPU clusters (henceforth CPUs) can be connected with differing distances to RAM instances (or devices).

Consider the simplified network below:

  +-------+      +--------+      +-------+
  | CPU 0 |------| DRAM A |------| CPU 1 |
  +-------+      +--------+      +-------+
      |                              |
      |                              |
  +--------+                     +--------+
  | DRAM B |                     | DRAM C |
  +--------+                     +--------+
      |                              |
      |                              |
  +-------+      +--------+      +-------+
  | CPU 2 |------| DRAM D |------| CPU 3 |
  +-------+      +--------+      +-------+

In this case CPUs and DRAMs are spaced evenly on the ring, but the distance between an arbitrary CPU and DRAM is not uniform.

CPU 0 can access DRAM A or DRAM B with a single hop, but accesses to DRAM C or DRAM D take three hops.

Quoted 6 lines

An access from CPU 0 to DRAM C could contend with accesses from CPU 1 to DRAM D, as they share hops on the ring.

There is definitely a NUMA topology here, but there's not a strict hierarchy. I don't see how you would represent this with the proposed binding.

can you please explain, how associativity property will represent this numa topology?

Quoted 45 lines

Likewise for the mesh networks (e.g. that of TILE-Mx)

Quoted 9 lines
Quoted 9 lines

however, if there are 2 SoC connected thorough the CCN, then it is very much similar to cavium topology.

Quoted 3 lines

Must all of these have the same length? If so, why not have a #(whatever)-cells property in the root to describe the expected length? If not, how are they to be interpreted relative to each other?

yes, all are of default size.

Where that size is...?

Quoted 1 line
Quoted 1 line

IMHO, there is no need to add cells property.

That might be the case, but it's unclear from the documentation. I don't see how one would parse / verify values currently.

Quoted 10 lines
Quoted 10 lines
Quoted 8 lines
Quoted 4 lines
(quoted diff) +2 -0
+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant

boundaries.
+There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property is already ordered from most significant to least significant per its description.

Quoted 6 lines
Quoted 6 lines

first entry in arm,associativity-reference-points is used to find which entry in associativity defines node id.
also entries in arm,associativity-reference-points defines, how many entries(depth) in associativity can be used to calculate node distance
in both level 1 and multi level(hierarchical) numa topology.

I think this needs a more thorough description; I don't follow the current one.

Quoted 4 lines
Quoted 4 lines
Quoted 2 lines

Is this only expected at the root of the tree? Can it be re-defined in sub-nodes?

yes it is defined only at the root.

Quoted 8 lines

This needs to be stated explicitly.

I see that this being the case, *,associativity-reference-points would be a more powerful property than the #(whatever)-cells property I mentioned earlier, but a more thorough description is required.

Thanks,
Mark.

thanks
Ganapat

#30 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Quoted 1 line · Ganapatrao Kulkarni

Hi Ben,

Before I dig in more (short on time right now), PAPR (at least a chunk of it) was released publicly:

https://members.openpowerfoundation.org/document/dl/469

(You don't need to be a member nor to sign up to get it)

Cheers,
Ben.

Quoted 229 lines
Quoted 149 lines · Mark Rutland
Quoted 35 lines · Ganapatrao Kulkarni

(sending again, by mistake it was set to html mode)

Quoted 31 lines · Ganapatrao Kulkarni

Hi Mark,

I have tried to answer your comments, in the meantime we are waiting for Ben
to share the details.

Quoted 12 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Given this is just a copy of ibm,associativity, I'm not sure I see much
point in renaming the properties.

Quoted 7 lines

However, (somewhat counter to that) I'm also concerned that this isn't
sufficient for systems we're beginning to see today (more on that
below), so I don't think a simple copy of ibm,associativity is good
enough.

it is just copy right now, however it can evolve when we come across more
arm64 numa platforms

Whatever we do I suspect we'll have to evolve it as new platforms appear. As I mentioned there are contemporary NUMA ARM64 platforms (e.g.
those with CCN) that I don't think we can ignore now given we'll have to
cater for them.

Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 4 lines

+==========================================================
====================
+2 - arm,associativity

Quoted 8 lines

+==========================================================
====================
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to
to be
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an
arm,associativity property being assumed to share that value?

Quoted 3 lines
Quoted 3 lines

yes there is inheritance and respective bus drivers should take care of it,
like pci driver does at present.

Ok.

That seems counter to my initial interpretation of the wording that the
property must be present on device nodes that need to be mapped to NUMA
nodes.

Is there any simple way of describing the set of nodes that need this
property?

Quoted 19 lines
Quoted 19 lines
Quoted 17 lines
Quoted 7 lines

+topology and boundary in the system at which a significant difference
in
+performance can be measured between cross-device accesses within

(quoted diff) +2 -0
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision
Quoted 6 lines

within the
system,
+while the last cell enumerates the individual devices, such as an SMT
thread
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative
distances at all. That seems like an oversight.

Quoted 7 lines
Quoted 7 lines

distance is computed, will add the details to document. local nodes will have distance as 10(LOCAL_DISTANCE) and every level, the
distance multiplies by 2.
for example, for level 1 numa topology, distance from local node to remote
node will be 20.

This seems arbitrary.

Why not always have this explicitly described?

Quoted 9 lines
Quoted 9 lines
Quoted 7 lines

Additionally, I'm somewhat unclear on how what you'd be expected to
provide for this property in cases like ring or mesh interconnects,
where there isn't a strict hierarchy (see systems with ARM's own CCN, or
Tilera's TILE-Mx), but there is some measure of closeness.

Quoted 3 lines
Quoted 3 lines

IIUC, as per ARMs CCN architecture, all core/clusters are at equal distance
of DDR, i dont see any NUMA topology.

The CCN is a ring interconnect, so CPU clusters (henceforth CPUs) can be
connected with differing distances to RAM instances (or devices).

Consider the simplified network below:

  +-------+      +--------+      +-------+
  | CPU 0 |------| DRAM A |------| CPU 1 |
  +-------+      +--------+      +-------+
      |                              |
      |                              |
  +--------+                     +--------+
  | DRAM B |                     | DRAM C |
  +--------+                     +--------+
      |                              |
      |                              |
  +-------+      +--------+      +-------+
  | CPU 2 |------| DRAM D |------| CPU 3 |
  +-------+      +--------+      +-------+

In this case CPUs and DRAMs are spaced evenly on the ring, but the distance between an arbitrary CPU and DRAM is not uniform.

CPU 0 can access DRAM A or DRAM B with a single hop, but accesses to
DRAM C or DRAM D take three hops.

Quoted 8 lines

An access from CPU 0 to DRAM C could contend with accesses from CPU 1 to
DRAM D, as they share hops on the ring.

There is definitely a NUMA topology here, but there's not a strict hierarchy. I don't see how you would represent this with the proposed
binding.

can you please explain, how associativity property will represent this
numa topology?

Quoted 58 lines

Likewise for the mesh networks (e.g. that of TILE-Mx)

Quoted 4 lines
Quoted 4 lines

however, if there are 2 SoC connected thorough the CCN, then it is very much
similar to cavium topology.

Quoted 8 lines
Quoted 8 lines
Quoted 5 lines

Must all of these have the same length? If so, why not have a #(whatever)-cells property in the root to describe the expected length?
If not, how are they to be interpreted relative to each other?

yes, all are of default size.

Where that size is...?

Quoted 1 line
Quoted 1 line

IMHO, there is no need to add cells property.

That might be the case, but it's unclear from the documentation. I don't
see how one would parse / verify values currently.

Quoted 14 lines
Quoted 14 lines
Quoted 12 lines
Quoted 6 lines

+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant
boundaries.
+There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property
is already ordered from most significant to least significant per its
description.

Quoted 8 lines
Quoted 8 lines

first entry in arm,associativity-reference-points is used to find which
entry in associativity defines node id.
also entries in arm,associativity-reference-points defines, how many entries(depth) in associativity can be used to calculate node
distance
in both level 1 and multi level(hierarchical) numa topology.

I think this needs a more thorough description; I don't follow the current one.

Quoted 5 lines
Quoted 5 lines
Quoted 3 lines

Is this only expected at the root of the tree? Can it be re -defined in
sub-nodes?

yes it is defined only at the root.

This needs to be stated explicitly.

Quoted 7 lines

I see that this being the case, *,associativity-reference-points would
be a more powerful property than the #(whatever)-cells property I mentioned earlier, but a more thorough description is required.

Thanks,
Mark.

thanks
Ganapat

#31 lore raw

Re: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.

Hi Ben,

Quoted 8 lines · Benjamin Herrenschmidt
Quoted 1 line · Ganapatrao Kulkarni

Hi Ben,

Before I dig in more (short on time right now), PAPR (at least a chunk of it) was released publicly:

https://members.openpowerfoundation.org/document/dl/469

thanks a lot for sharing this document.
i went through the chapter 15 of this doc which explains an example on hierarchical numa topology.
i still could not represent the ring/mesh numa topology using associativity, which will be present in other upcoming arm64 platforms.

Quoted 168 lines

(You don't need to be a member nor to sign up to get it)

Cheers,
Ben.

Quoted 162 lines
Quoted 149 lines · Mark Rutland
Quoted 35 lines · Ganapatrao Kulkarni

(sending again, by mistake it was set to html mode)

Quoted 31 lines · Ganapatrao Kulkarni

Hi Mark,

I have tried to answer your comments, in the meantime we are waiting for Ben
to share the details.

Quoted 12 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Given this is just a copy of ibm,associativity, I'm not sure I see much
point in renaming the properties.

Quoted 7 lines

However, (somewhat counter to that) I'm also concerned that this isn't
sufficient for systems we're beginning to see today (more on that
below), so I don't think a simple copy of ibm,associativity is good
enough.

it is just copy right now, however it can evolve when we come across more
arm64 numa platforms

Whatever we do I suspect we'll have to evolve it as new platforms appear. As I mentioned there are contemporary NUMA ARM64 platforms (e.g.
those with CCN) that I don't think we can ignore now given we'll have to
cater for them.

Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 4 lines

+==========================================================
====================
+2 - arm,associativity

Quoted 8 lines

+==========================================================
====================
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to
to be
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an
arm,associativity property being assumed to share that value?

Quoted 3 lines
Quoted 3 lines

yes there is inheritance and respective bus drivers should take care of it,
like pci driver does at present.

Ok.

That seems counter to my initial interpretation of the wording that the
property must be present on device nodes that need to be mapped to NUMA
nodes.

Is there any simple way of describing the set of nodes that need this
property?

Quoted 19 lines
Quoted 19 lines
Quoted 17 lines
Quoted 7 lines

+topology and boundary in the system at which a significant difference
in
+performance can be measured between cross-device accesses within

(quoted diff) +2 -0
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision
Quoted 6 lines

within the
system,
+while the last cell enumerates the individual devices, such as an SMT
thread
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative
distances at all. That seems like an oversight.

Quoted 7 lines
Quoted 7 lines

distance is computed, will add the details to document. local nodes will have distance as 10(LOCAL_DISTANCE) and every level, the
distance multiplies by 2.
for example, for level 1 numa topology, distance from local node to remote
node will be 20.

This seems arbitrary.

Why not always have this explicitly described?

Quoted 9 lines
Quoted 9 lines
Quoted 7 lines

Additionally, I'm somewhat unclear on how what you'd be expected to
provide for this property in cases like ring or mesh interconnects,
where there isn't a strict hierarchy (see systems with ARM's own CCN, or
Tilera's TILE-Mx), but there is some measure of closeness.

Quoted 3 lines
Quoted 3 lines

IIUC, as per ARMs CCN architecture, all core/clusters are at equal distance
of DDR, i dont see any NUMA topology.

The CCN is a ring interconnect, so CPU clusters (henceforth CPUs) can be
connected with differing distances to RAM instances (or devices).

Consider the simplified network below:

  +-------+      +--------+      +-------+
  | CPU 0 |------| DRAM A |------| CPU 1 |
  +-------+      +--------+      +-------+
      |                              |
      |                              |
  +--------+                     +--------+
  | DRAM B |                     | DRAM C |
  +--------+                     +--------+
      |                              |
      |                              |
  +-------+      +--------+      +-------+
  | CPU 2 |------| DRAM D |------| CPU 3 |
  +-------+      +--------+      +-------+

In this case CPUs and DRAMs are spaced evenly on the ring, but the distance between an arbitrary CPU and DRAM is not uniform.

CPU 0 can access DRAM A or DRAM B with a single hop, but accesses to
DRAM C or DRAM D take three hops.

Quoted 8 lines

An access from CPU 0 to DRAM C could contend with accesses from CPU 1 to
DRAM D, as they share hops on the ring.

There is definitely a NUMA topology here, but there's not a strict hierarchy. I don't see how you would represent this with the proposed
binding.

can you please explain, how associativity property will represent this
numa topology?

Hi Mark,

i am thinking, if we could not address(or becomes complex) these topologies using associativity,
we should think of an alternate binding which suits existing and upcoming arm64 platforms.
can we think of below numa binding which is inline with ACPI and will address all sort of topologies!

i am proposing as below,

1. introduce "proximity" node property. this property will be present in dt nodes like memory, cpu, bus and devices(like associativity property) and
will tell which numa node(proximity domain) this dt node belongs to.

examples:

               cpu@000 {
                        device_type = "cpu";
                        compatible = "cavium,thunder", "arm,armv8";
                        reg = <0x0 0x000>;
                        enable-method = "psci";
                        proximity = <0>;
                };
               cpu@001 {
                        device_type = "cpu";
                        compatible = "cavium,thunder", "arm,armv8";
                        reg = <0x0 0x001>;
                        enable-method = "psci";
                        proximity = <1>;
                };

       memory@00000000 {
                device_type = "memory";
                reg = <0x0 0x01400000 0x3 0xFEC00000>;
                proximity =<0>;

        };

        memory@10000000000 {
                device_type = "memory";
                reg = <0x100 0x00400000 0x3 0xFFC00000>;
                proximity =<1>;
        };
pcie0@0x8480,00000000 {
                compatible = "cavium,thunder-pcie";
                device_type = "pci";
                msi-parent = <&its>;
                bus-range = <0 255>;
                #size-cells = <2>;
                #address-cells = <3>;
                #stream-id-cells = <1>;
                reg = <0x8480 0x00000000 0 0x10000000>;  /*Configuration
space */
                ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000
0x70 0x00000000>, /* mem ranges */
                         <0x03000000 0x8300 0x00000000 0x8300 0x00000000
0x500 0x00000000>;
               proximity =<0>;
        };

2. Introduce new dt node "proximity-map" which will capture the NxN numa node distance matrix.

for example, 4 nodes connected in mesh/ring structure as,
A(0) <connected to> B(1) <connected to> C(2) <connected to> D(3) <connected to> A(1)

relative distance would be,

      A -> B = 20
      B -> C  = 20
      C -> D = 20
      D -> A = 20
      A -> C = 40
      B -> D = 40

and dt presentation for this distance matrix is :

       proximity-map {
             node-count = <4>;
             distance-matrix = <0 0  10>,
                                <0 1  20>,
                                <0 2  40>,
                                <0 3  20>,
                                <1 0  20>,
                                <1 1  10>,
                                <1 2  20>,
                                <1 3  40>,
                                <2 0  40>,
                                <2 1  20>,
                                <2 2  10>,
                                <2 3  20>,
                                <3 0  20>,
                                <3 1  40>,
                                <3 2  20>,
                                <3 3  10>;
          }

the entries like < 0 0 > < 1 1> < 2 2> < 3 3> can be optional and code can put default value(local distance).
the entries like <1 0> can be optional if <0 1> and <1 0> are of same distance.

Quoted 63 lines
Quoted 63 lines
Quoted 63 lines

Likewise for the mesh networks (e.g. that of TILE-Mx)

Quoted 4 lines
Quoted 4 lines

however, if there are 2 SoC connected thorough the CCN, then it is very much
similar to cavium topology.

Quoted 8 lines
Quoted 8 lines
Quoted 5 lines

Must all of these have the same length? If so, why not have a #(whatever)-cells property in the root to describe the expected length?
If not, how are they to be interpreted relative to each other?

yes, all are of default size.

Where that size is...?

Quoted 1 line
Quoted 1 line

IMHO, there is no need to add cells property.

That might be the case, but it's unclear from the documentation. I don't
see how one would parse / verify values currently.

Quoted 14 lines
Quoted 14 lines
Quoted 12 lines
Quoted 6 lines

+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant
boundaries.
+There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property
is already ordered from most significant to least significant per its
description.

Quoted 8 lines
Quoted 8 lines

first entry in arm,associativity-reference-points is used to find which
entry in associativity defines node id.
also entries in arm,associativity-reference-points defines, how many entries(depth) in associativity can be used to calculate node
distance
in both level 1 and multi level(hierarchical) numa topology.

I think this needs a more thorough description; I don't follow the current one.

Quoted 5 lines
Quoted 5 lines
Quoted 3 lines

Is this only expected at the root of the tree? Can it be re -defined in
sub-nodes?

yes it is defined only at the root.

This needs to be stated explicitly.

I see that this being the case, *,associativity-reference-points would
be a more powerful property than the #(whatever)-cells property I mentioned earlier, but a more thorough description is required.

Quoted 5 lines
Quoted 4 lines
Quoted 2 lines

Thanks,
Mark.

thanks
Ganapat

thanks
Ganapat

#32 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

(sending again, dont know, why plane text mode was unchecked. apologies for the inconvenience)

Quoted 366 lines · Ganapatrao Kulkarni

Hi Ben,

Quoted 8 lines · Benjamin Herrenschmidt
Quoted 1 line · Ganapatrao Kulkarni

Hi Ben,

Before I dig in more (short on time right now), PAPR (at least a chunk of it) was released publicly:

https://members.openpowerfoundation.org/document/dl/469

thanks a lot for sharing this document.
i went through the chapter 15 of this doc which explains an example on hierarchical numa topology.
i still could not represent the ring/mesh numa topology using associativity, which will be present in other upcoming arm64 platforms.

Quoted 168 lines

(You don't need to be a member nor to sign up to get it)

Cheers,
Ben.

Quoted 162 lines
Quoted 149 lines · Mark Rutland
Quoted 35 lines · Ganapatrao Kulkarni

(sending again, by mistake it was set to html mode)

Quoted 31 lines · Ganapatrao Kulkarni

Hi Mark,

I have tried to answer your comments, in the meantime we are waiting for Ben
to share the details.

Quoted 12 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Given this is just a copy of ibm,associativity, I'm not sure I see much
point in renaming the properties.

Quoted 7 lines

However, (somewhat counter to that) I'm also concerned that this isn't
sufficient for systems we're beginning to see today (more on that
below), so I don't think a simple copy of ibm,associativity is good
enough.

it is just copy right now, however it can evolve when we come across more
arm64 numa platforms

Whatever we do I suspect we'll have to evolve it as new platforms appear. As I mentioned there are contemporary NUMA ARM64 platforms (e.g.
those with CCN) that I don't think we can ignore now given we'll have to
cater for them.

Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 4 lines

+==========================================================
====================
+2 - arm,associativity

Quoted 8 lines

+==========================================================
====================
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to
to be
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an
arm,associativity property being assumed to share that value?

Quoted 3 lines
Quoted 3 lines

yes there is inheritance and respective bus drivers should take care of it,
like pci driver does at present.

Ok.

That seems counter to my initial interpretation of the wording that the
property must be present on device nodes that need to be mapped to NUMA
nodes.

Is there any simple way of describing the set of nodes that need this
property?

Quoted 19 lines
Quoted 19 lines
Quoted 17 lines
Quoted 7 lines

+topology and boundary in the system at which a significant difference
in
+performance can be measured between cross-device accesses within

(quoted diff) +2 -0
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision
Quoted 6 lines

within the
system,
+while the last cell enumerates the individual devices, such as an SMT
thread
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative
distances at all. That seems like an oversight.

Quoted 7 lines
Quoted 7 lines

distance is computed, will add the details to document. local nodes will have distance as 10(LOCAL_DISTANCE) and every level, the
distance multiplies by 2.
for example, for level 1 numa topology, distance from local node to remote
node will be 20.

This seems arbitrary.

Why not always have this explicitly described?

Quoted 9 lines
Quoted 9 lines
Quoted 7 lines

Additionally, I'm somewhat unclear on how what you'd be expected to
provide for this property in cases like ring or mesh interconnects,
where there isn't a strict hierarchy (see systems with ARM's own CCN, or
Tilera's TILE-Mx), but there is some measure of closeness.

Quoted 3 lines
Quoted 3 lines

IIUC, as per ARMs CCN architecture, all core/clusters are at equal distance
of DDR, i dont see any NUMA topology.

The CCN is a ring interconnect, so CPU clusters (henceforth CPUs) can be
connected with differing distances to RAM instances (or devices).

Consider the simplified network below:

  +-------+      +--------+      +-------+
  | CPU 0 |------| DRAM A |------| CPU 1 |
  +-------+      +--------+      +-------+
      |                              |
      |                              |
  +--------+                     +--------+
  | DRAM B |                     | DRAM C |
  +--------+                     +--------+
      |                              |
      |                              |
  +-------+      +--------+      +-------+
  | CPU 2 |------| DRAM D |------| CPU 3 |
  +-------+      +--------+      +-------+

In this case CPUs and DRAMs are spaced evenly on the ring, but the distance between an arbitrary CPU and DRAM is not uniform.

CPU 0 can access DRAM A or DRAM B with a single hop, but accesses to
DRAM C or DRAM D take three hops.

Quoted 8 lines

An access from CPU 0 to DRAM C could contend with accesses from CPU 1 to
DRAM D, as they share hops on the ring.

There is definitely a NUMA topology here, but there's not a strict hierarchy. I don't see how you would represent this with the proposed
binding.

can you please explain, how associativity property will represent this
numa topology?

Hi Mark,

i am thinking, if we could not address(or becomes complex) these topologies using associativity,
we should think of an alternate binding which suits existing and upcoming arm64 platforms.
can we think of below numa binding which is inline with ACPI and will address all sort of topologies!

i am proposing as below,

1. introduce "proximity" node property. this property will be present in dt nodes like memory, cpu, bus and devices(like associativity property) and
will tell which numa node(proximity domain) this dt node belongs to.

examples:

               cpu at 000 {
                        device_type = "cpu";
                        compatible = "cavium,thunder", "arm,armv8";
                        reg = <0x0 0x000>;
                        enable-method = "psci";
                        proximity = <0>;
                };
               cpu at 001 {
                        device_type = "cpu";
                        compatible = "cavium,thunder", "arm,armv8";
                        reg = <0x0 0x001>;
                        enable-method = "psci";
                        proximity = <1>;
                };

       memory at 00000000 {
                device_type = "memory";
                reg = <0x0 0x01400000 0x3 0xFEC00000>;
                proximity =<0>;

        };

        memory at 10000000000 {
                device_type = "memory";
                reg = <0x100 0x00400000 0x3 0xFFC00000>;
                proximity =<1>;
        };
pcie0 at 0x8480,00000000 {
                compatible = "cavium,thunder-pcie";
                device_type = "pci";
                msi-parent = <&its>;
                bus-range = <0 255>;
                #size-cells = <2>;
                #address-cells = <3>;
                #stream-id-cells = <1>;
                reg = <0x8480 0x00000000 0 0x10000000>;  /*Configuration
space */
                ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000
0x70 0x00000000>, /* mem ranges */
                         <0x03000000 0x8300 0x00000000 0x8300 0x00000000
0x500 0x00000000>;
               proximity =<0>;
        };

2. Introduce new dt node "proximity-map" which will capture the NxN numa node distance matrix.

for example, 4 nodes connected in mesh/ring structure as,
A(0) <connected to> B(1) <connected to> C(2) <connected to> D(3) <connected to> A(1)

relative distance would be,

      A -> B = 20
      B -> C  = 20
      C -> D = 20
      D -> A = 20
      A -> C = 40
      B -> D = 40

and dt presentation for this distance matrix is :

       proximity-map {
             node-count = <4>;
             distance-matrix = <0 0  10>,
                                <0 1  20>,
                                <0 2  40>,
                                <0 3  20>,
                                <1 0  20>,
                                <1 1  10>,
                                <1 2  20>,
                                <1 3  40>,
                                <2 0  40>,
                                <2 1  20>,
                                <2 2  10>,
                                <2 3  20>,
                                <3 0  20>,
                                <3 1  40>,
                                <3 2  20>,
                                <3 3  10>;
          }

the entries like < 0 0 > < 1 1> < 2 2> < 3 3> can be optional and code can put default value(local distance).
the entries like <1 0> can be optional if <0 1> and <1 0> are of same distance.

Quoted 63 lines
Quoted 63 lines
Quoted 63 lines

Likewise for the mesh networks (e.g. that of TILE-Mx)

Quoted 4 lines
Quoted 4 lines

however, if there are 2 SoC connected thorough the CCN, then it is very much
similar to cavium topology.

Quoted 8 lines
Quoted 8 lines
Quoted 5 lines

Must all of these have the same length? If so, why not have a #(whatever)-cells property in the root to describe the expected length?
If not, how are they to be interpreted relative to each other?

yes, all are of default size.

Where that size is...?

Quoted 1 line
Quoted 1 line

IMHO, there is no need to add cells property.

That might be the case, but it's unclear from the documentation. I don't
see how one would parse / verify values currently.

Quoted 14 lines
Quoted 14 lines
Quoted 12 lines
Quoted 6 lines

+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant
boundaries.
+There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property
is already ordered from most significant to least significant per its
description.

Quoted 8 lines
Quoted 8 lines

first entry in arm,associativity-reference-points is used to find which
entry in associativity defines node id.
also entries in arm,associativity-reference-points defines, how many entries(depth) in associativity can be used to calculate node
distance
in both level 1 and multi level(hierarchical) numa topology.

I think this needs a more thorough description; I don't follow the current one.

Quoted 5 lines
Quoted 5 lines
Quoted 3 lines

Is this only expected at the root of the tree? Can it be re -defined in
sub-nodes?

yes it is defined only at the root.

This needs to be stated explicitly.

I see that this being the case, *,associativity-reference-points would
be a more powerful property than the #(whatever)-cells property I mentioned earlier, but a more thorough description is required.

Quoted 4 lines
Quoted 4 lines
Quoted 2 lines

Thanks,
Mark.

thanks
Ganapat

thanks
Ganapat

#33 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

In reply to Ganapatrao Kulkarni
Quoted 3 lines · Ganapatrao Kulkarni

i still could not represent the ring/mesh numa topology using associativity, which will be present in other upcoming arm64 platforms.

Right. It should be possible to represent it using the multiple list as a multi-path problem, but it's a bit awkward.

It does look like the representation might not work well for that case

Cheers,
Ben.

#34 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

In reply to Ganapatrao Kulkarni

Hi Mark,

Quoted 289 lines · Ganapatrao Kulkarni

Hi Ben,

Quoted 8 lines · Benjamin Herrenschmidt
Quoted 1 line · Ganapatrao Kulkarni

Hi Ben,

Before I dig in more (short on time right now), PAPR (at least a chunk of it) was released publicly:

https://members.openpowerfoundation.org/document/dl/469

thanks a lot for sharing this document.
i went through the chapter 15 of this doc which explains an example on hierarchical numa topology.
i still could not represent the ring/mesh numa topology using associativity, which will be present in other upcoming arm64 platforms.

Quoted 168 lines

(You don't need to be a member nor to sign up to get it)

Cheers,
Ben.

Quoted 162 lines
Quoted 149 lines · Mark Rutland
Quoted 35 lines · Ganapatrao Kulkarni

(sending again, by mistake it was set to html mode)

Quoted 31 lines · Ganapatrao Kulkarni

Hi Mark,

I have tried to answer your comments, in the meantime we are waiting for Ben
to share the details.

Quoted 12 lines · Mark Rutland

Hi,

Quoted 2 lines · Ganapatrao Kulkarni

DT bindings for numa map for memory, cores and IOs using arm,associativity device node property.

Given this is just a copy of ibm,associativity, I'm not sure I see much
point in renaming the properties.

Quoted 7 lines

However, (somewhat counter to that) I'm also concerned that this isn't
sufficient for systems we're beginning to see today (more on that
below), so I don't think a simple copy of ibm,associativity is good
enough.

it is just copy right now, however it can evolve when we come across more
arm64 numa platforms

Whatever we do I suspect we'll have to evolve it as new platforms appear. As I mentioned there are contemporary NUMA ARM64 platforms (e.g.
those with CCN) that I don't think we can ignore now given we'll have to
cater for them.

Quoted 17 lines
Quoted 17 lines
Quoted 16 lines
Quoted 4 lines

+==========================================================
====================
+2 - arm,associativity

Quoted 8 lines

+==========================================================
====================
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to
to be
+mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an
arm,associativity property being assumed to share that value?

Quoted 3 lines
Quoted 3 lines

yes there is inheritance and respective bus drivers should take care of it,
like pci driver does at present.

Ok.

That seems counter to my initial interpretation of the wording that the
property must be present on device nodes that need to be mapped to NUMA
nodes.

Is there any simple way of describing the set of nodes that need this
property?

Quoted 19 lines
Quoted 19 lines
Quoted 17 lines
Quoted 7 lines

+topology and boundary in the system at which a significant difference
in
+performance can be measured between cross-device accesses within

(quoted diff) +2 -0
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision
Quoted 6 lines

within the
system,
+while the last cell enumerates the individual devices, such as an SMT
thread
+of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative
distances at all. That seems like an oversight.

Quoted 7 lines
Quoted 7 lines

distance is computed, will add the details to document. local nodes will have distance as 10(LOCAL_DISTANCE) and every level, the
distance multiplies by 2.
for example, for level 1 numa topology, distance from local node to remote
node will be 20.

This seems arbitrary.

Why not always have this explicitly described?

Quoted 9 lines
Quoted 9 lines
Quoted 7 lines

Additionally, I'm somewhat unclear on how what you'd be expected to
provide for this property in cases like ring or mesh interconnects,
where there isn't a strict hierarchy (see systems with ARM's own CCN, or
Tilera's TILE-Mx), but there is some measure of closeness.

Quoted 3 lines
Quoted 3 lines

IIUC, as per ARMs CCN architecture, all core/clusters are at equal distance
of DDR, i dont see any NUMA topology.

The CCN is a ring interconnect, so CPU clusters (henceforth CPUs) can be
connected with differing distances to RAM instances (or devices).

Consider the simplified network below:

  +-------+      +--------+      +-------+
  | CPU 0 |------| DRAM A |------| CPU 1 |
  +-------+      +--------+      +-------+
      |                              |
      |                              |
  +--------+                     +--------+
  | DRAM B |                     | DRAM C |
  +--------+                     +--------+
      |                              |
      |                              |
  +-------+      +--------+      +-------+
  | CPU 2 |------| DRAM D |------| CPU 3 |
  +-------+      +--------+      +-------+

In this case CPUs and DRAMs are spaced evenly on the ring, but the distance between an arbitrary CPU and DRAM is not uniform.

CPU 0 can access DRAM A or DRAM B with a single hop, but accesses to
DRAM C or DRAM D take three hops.

Quoted 8 lines

An access from CPU 0 to DRAM C could contend with accesses from CPU 1 to
DRAM D, as they share hops on the ring.

There is definitely a NUMA topology here, but there's not a strict hierarchy. I don't see how you would represent this with the proposed
binding.

can you please explain, how associativity property will represent this
numa topology?

Hi Mark,

i am thinking, if we could not address(or becomes complex) these topologies using associativity,
we should think of an alternate binding which suits existing and upcoming arm64 platforms.
can we think of below numa binding which is inline with ACPI and will address all sort of topologies!

i am proposing as below,

1. introduce "proximity" node property. this property will be present in dt nodes like memory, cpu, bus and devices(like associativity property) and
will tell which numa node(proximity domain) this dt node belongs to.

examples:

               cpu at 000 {
                        device_type = "cpu";
                        compatible = "cavium,thunder", "arm,armv8";
                        reg = <0x0 0x000>;
                        enable-method = "psci";
                        proximity = <0>;
                };
               cpu at 001 {
                        device_type = "cpu";
                        compatible = "cavium,thunder", "arm,armv8";
                        reg = <0x0 0x001>;
                        enable-method = "psci";
                        proximity = <1>;
                };

       memory at 00000000 {
                device_type = "memory";
                reg = <0x0 0x01400000 0x3 0xFEC00000>;
                proximity =<0>;

        };

        memory at 10000000000 {
                device_type = "memory";
                reg = <0x100 0x00400000 0x3 0xFFC00000>;
                proximity =<1>;
        };
pcie0 at 0x8480,00000000 {
                compatible = "cavium,thunder-pcie";
                device_type = "pci";
                msi-parent = <&its>;
                bus-range = <0 255>;
                #size-cells = <2>;
                #address-cells = <3>;
                #stream-id-cells = <1>;
                reg = <0x8480 0x00000000 0 0x10000000>;  /*Configuration
space */
                ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000
0x70 0x00000000>, /* mem ranges */
                         <0x03000000 0x8300 0x00000000 0x8300 0x00000000
0x500 0x00000000>;
               proximity =<0>;
        };

2. Introduce new dt node "proximity-map" which will capture the NxN numa node distance matrix.

for example, 4 nodes connected in mesh/ring structure as,
A(0) <connected to> B(1) <connected to> C(2) <connected to> D(3) <connected to> A(1)

relative distance would be,

      A -> B = 20
      B -> C  = 20
      C -> D = 20
      D -> A = 20
      A -> C = 40
      B -> D = 40

and dt presentation for this distance matrix is :

       proximity-map {
             node-count = <4>;
             distance-matrix = <0 0  10>,
                                <0 1  20>,
                                <0 2  40>,
                                <0 3  20>,
                                <1 0  20>,
                                <1 1  10>,
                                <1 2  20>,
                                <1 3  40>,
                                <2 0  40>,
                                <2 1  20>,
                                <2 2  10>,
                                <2 3  20>,
                                <3 0  20>,
                                <3 1  40>,
                                <3 2  20>,
                                <3 3  10>;
          }
Quoted 4 lines

the entries like < 0 0 > < 1 1> < 2 2> < 3 3> can be optional and code can put default value(local distance).
the entries like <1 0> can be optional if <0 1> and <1 0> are of same distance.

is this binding looks ok?
i can implement this and submit in next version of patchset.

Quoted 65 lines
Quoted 65 lines
Quoted 65 lines
Quoted 65 lines

Likewise for the mesh networks (e.g. that of TILE-Mx)

Quoted 4 lines
Quoted 4 lines

however, if there are 2 SoC connected thorough the CCN, then it is very much
similar to cavium topology.

Quoted 8 lines
Quoted 8 lines
Quoted 5 lines

Must all of these have the same length? If so, why not have a #(whatever)-cells property in the root to describe the expected length?
If not, how are they to be interpreted relative to each other?

yes, all are of default size.

Where that size is...?

Quoted 1 line
Quoted 1 line

IMHO, there is no need to add cells property.

That might be the case, but it's unclear from the documentation. I don't
see how one would parse / verify values currently.

Quoted 14 lines
Quoted 14 lines
Quoted 12 lines
Quoted 6 lines

+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant
boundaries.
+There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property
is already ordered from most significant to least significant per its
description.

Quoted 8 lines
Quoted 8 lines

first entry in arm,associativity-reference-points is used to find which
entry in associativity defines node id.
also entries in arm,associativity-reference-points defines, how many entries(depth) in associativity can be used to calculate node
distance
in both level 1 and multi level(hierarchical) numa topology.

I think this needs a more thorough description; I don't follow the current one.

Quoted 5 lines
Quoted 5 lines
Quoted 3 lines

Is this only expected at the root of the tree? Can it be re -defined in
sub-nodes?

yes it is defined only at the root.

This needs to be stated explicitly.

I see that this being the case, *,associativity-reference-points would
be a more powerful property than the #(whatever)-cells property I mentioned earlier, but a more thorough description is required.

Quoted 8 lines
Quoted 4 lines
Quoted 4 lines
Quoted 2 lines

Thanks,
Mark.

thanks
Ganapat

thanks
Ganapat

thanks
Ganapat

reviewer
#35 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Quoted 100 lines
Quoted 100 lines

Hi Mark,

i am thinking, if we could not address(or becomes complex) these topologies using associativity,
we should think of an alternate binding which suits existing and upcoming arm64 platforms.
can we think of below numa binding which is inline with ACPI and will address all sort of topologies!

i am proposing as below,

1. introduce "proximity" node property. this property will be present in dt nodes like memory, cpu, bus and devices(like associativity property) and
will tell which numa node(proximity domain) this dt node belongs to.

examples:

               cpu at 000 {
                        device_type = "cpu";
                        compatible = "cavium,thunder", "arm,armv8";
                        reg = <0x0 0x000>;
                        enable-method = "psci";
                        proximity = <0>;
                };
               cpu at 001 {
                        device_type = "cpu";
                        compatible = "cavium,thunder", "arm,armv8";
                        reg = <0x0 0x001>;
                        enable-method = "psci";
                        proximity = <1>;
                };

       memory at 00000000 {
                device_type = "memory";
                reg = <0x0 0x01400000 0x3 0xFEC00000>;
                proximity =<0>;

        };

        memory at 10000000000 {
                device_type = "memory";
                reg = <0x100 0x00400000 0x3 0xFFC00000>;
                proximity =<1>;
        };
pcie0 at 0x8480,00000000 {
                compatible = "cavium,thunder-pcie";
                device_type = "pci";
                msi-parent = <&its>;
                bus-range = <0 255>;
                #size-cells = <2>;
                #address-cells = <3>;
                #stream-id-cells = <1>;
                reg = <0x8480 0x00000000 0 0x10000000>;  /*Configuration
space */
                ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000
0x70 0x00000000>, /* mem ranges */
                         <0x03000000 0x8300 0x00000000 0x8300 0x00000000
0x500 0x00000000>;
               proximity =<0>;
        };

2. Introduce new dt node "proximity-map" which will capture the NxN numa node distance matrix.

for example, 4 nodes connected in mesh/ring structure as,
A(0) <connected to> B(1) <connected to> C(2) <connected to> D(3) <connected to> A(1)

relative distance would be,

      A -> B = 20
      B -> C  = 20
      C -> D = 20
      D -> A = 20
      A -> C = 40
      B -> D = 40

and dt presentation for this distance matrix is :

       proximity-map {
             node-count = <4>;
             distance-matrix = <0 0  10>,
                                <0 1  20>,
                                <0 2  40>,
                                <0 3  20>,
                                <1 0  20>,
                                <1 1  10>,
                                <1 2  20>,
                                <1 3  40>,
                                <2 0  40>,
                                <2 1  20>,
                                <2 2  10>,
                                <2 3  20>,
                                <3 0  20>,
                                <3 1  40>,
                                <3 2  20>,
                                <3 3  10>;
          }
Quoted 5 lines
Quoted 4 lines

the entries like < 0 0 > < 1 1> < 2 2> < 3 3> can be optional and code can put default value(local distance).
the entries like <1 0> can be optional if <0 1> and <1 0> are of same distance.

is this binding looks ok?

This looks roughly requivalent to the ACPI SLIT, which means it's as powerful, which allays my previous concerns.

Quoted 1 line

i can implement this and submit in next version of patchset.

Please put together (plaintext) patches.

Then we have a sensible baseline that we can work from; it's somewhat difficult for others to join the disacussion here as-is.

Thanks,
Mark.

#36 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

Quoted 109 lines · Mark Rutland
Quoted 100 lines
Quoted 100 lines

Hi Mark,

i am thinking, if we could not address(or becomes complex) these topologies using associativity,
we should think of an alternate binding which suits existing and upcoming arm64 platforms.
can we think of below numa binding which is inline with ACPI and will address all sort of topologies!

i am proposing as below,

1. introduce "proximity" node property. this property will be present in dt nodes like memory, cpu, bus and devices(like associativity property) and
will tell which numa node(proximity domain) this dt node belongs to.

examples:

               cpu at 000 {
                        device_type = "cpu";
                        compatible = "cavium,thunder", "arm,armv8";
                        reg = <0x0 0x000>;
                        enable-method = "psci";
                        proximity = <0>;
                };
               cpu at 001 {
                        device_type = "cpu";
                        compatible = "cavium,thunder", "arm,armv8";
                        reg = <0x0 0x001>;
                        enable-method = "psci";
                        proximity = <1>;
                };

       memory at 00000000 {
                device_type = "memory";
                reg = <0x0 0x01400000 0x3 0xFEC00000>;
                proximity =<0>;

        };

        memory at 10000000000 {
                device_type = "memory";
                reg = <0x100 0x00400000 0x3 0xFFC00000>;
                proximity =<1>;
        };
pcie0 at 0x8480,00000000 {
                compatible = "cavium,thunder-pcie";
                device_type = "pci";
                msi-parent = <&its>;
                bus-range = <0 255>;
                #size-cells = <2>;
                #address-cells = <3>;
                #stream-id-cells = <1>;
                reg = <0x8480 0x00000000 0 0x10000000>;  /*Configuration
space */
                ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000
0x70 0x00000000>, /* mem ranges */
                         <0x03000000 0x8300 0x00000000 0x8300 0x00000000
0x500 0x00000000>;
               proximity =<0>;
        };

2. Introduce new dt node "proximity-map" which will capture the NxN numa node distance matrix.

for example, 4 nodes connected in mesh/ring structure as,
A(0) <connected to> B(1) <connected to> C(2) <connected to> D(3) <connected to> A(1)

relative distance would be,

      A -> B = 20
      B -> C  = 20
      C -> D = 20
      D -> A = 20
      A -> C = 40
      B -> D = 40

and dt presentation for this distance matrix is :

       proximity-map {
             node-count = <4>;
             distance-matrix = <0 0  10>,
                                <0 1  20>,
                                <0 2  40>,
                                <0 3  20>,
                                <1 0  20>,
                                <1 1  10>,
                                <1 2  20>,
                                <1 3  40>,
                                <2 0  40>,
                                <2 1  20>,
                                <2 2  10>,
                                <2 3  20>,
                                <3 0  20>,
                                <3 1  40>,
                                <3 2  20>,
                                <3 3  10>;
          }
Quoted 5 lines
Quoted 4 lines

the entries like < 0 0 > < 1 1> < 2 2> < 3 3> can be optional and code can put default value(local distance).
the entries like <1 0> can be optional if <0 1> and <1 0> are of same distance.

is this binding looks ok?

This looks roughly requivalent to the ACPI SLIT, which means it's as powerful, which allays my previous concerns.

Quoted 6 lines
Quoted 1 line

i can implement this and submit in next version of patchset.

Please put together (plaintext) patches.

Then we have a sensible baseline that we can work from; it's somewhat difficult for others to join the disacussion here as-is.

thanks, will post the v6 in couple of days with implementation based on this binding proposal..

Quoted 3 lines

Thanks,
Mark.

thanks
Ganapat

#37 lore raw

PATCH v5 2/4 Documentation: arm64/arm: dt bindings for numa.

In reply to Mark Rutland
Quoted 100 lines · Mark Rutland
Quoted 100 lines
Quoted 100 lines

Hi Mark,

i am thinking, if we could not address(or becomes complex) these topologies using associativity,
we should think of an alternate binding which suits existing and upcoming arm64 platforms.
can we think of below numa binding which is inline with ACPI and will address all sort of topologies!

i am proposing as below,

1. introduce "proximity" node property. this property will be present in dt nodes like memory, cpu, bus and devices(like associativity property) and
will tell which numa node(proximity domain) this dt node belongs to.

examples:

                cpu at 000 {
                         device_type = "cpu";
                         compatible = "cavium,thunder", "arm,armv8";
                         reg = <0x0 0x000>;
                         enable-method = "psci";
                         proximity = <0>;
                 };
                cpu at 001 {
                         device_type = "cpu";
                         compatible = "cavium,thunder", "arm,armv8";
                         reg = <0x0 0x001>;
                         enable-method = "psci";
                         proximity = <1>;
                 };

        memory at 00000000 {
                 device_type = "memory";
                 reg = <0x0 0x01400000 0x3 0xFEC00000>;
                 proximity =<0>;

         };

         memory at 10000000000 {
                 device_type = "memory";
                 reg = <0x100 0x00400000 0x3 0xFFC00000>;
                 proximity =<1>;
         };
pcie0 at 0x8480,00000000 {
                 compatible = "cavium,thunder-pcie";
                 device_type = "pci";
                 msi-parent = <&its>;
                 bus-range = <0 255>;
                 #size-cells = <2>;
                 #address-cells = <3>;
                 #stream-id-cells = <1>;
                 reg = <0x8480 0x00000000 0 0x10000000>;  /*Configuration
space */
                 ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000
0x70 0x00000000>, /* mem ranges */
                          <0x03000000 0x8300 0x00000000 0x8300 0x00000000
0x500 0x00000000>;
                proximity =<0>;
         };

2. Introduce new dt node "proximity-map" which will capture the NxN numa node distance matrix.

for example, 4 nodes connected in mesh/ring structure as,
A(0) <connected to> B(1) <connected to> C(2) <connected to> D(3) <connected to> A(1)

relative distance would be,

       A -> B = 20
       B -> C  = 20
       C -> D = 20
       D -> A = 20
       A -> C = 40
       B -> D = 40

and dt presentation for this distance matrix is :

        proximity-map {
              node-count = <4>;
              distance-matrix = <0 0  10>,
                                 <0 1  20>,
                                 <0 2  40>,
                                 <0 3  20>,
                                 <1 0  20>,
                                 <1 1  10>,
                                 <1 2  20>,
                                 <1 3  40>,
                                 <2 0  40>,
                                 <2 1  20>,
                                 <2 2  10>,
                                 <2 3  20>,
                                 <3 0  20>,
                                 <3 1  40>,
                                 <3 2  20>,
                                 <3 3  10>;
           }
Quoted 8 lines
Quoted 5 lines
Quoted 4 lines

the entries like < 0 0 > < 1 1> < 2 2> < 3 3> can be optional and code can put default value(local distance).
the entries like <1 0> can be optional if <0 1> and <1 0> are of same distance.

is this binding looks ok?

This looks roughly requivalent to the ACPI SLIT, which means it's as powerful, which allays my previous concerns.

Cool, I think those bindings are quite extensible and easy understood.

Thanks
Hanjun

#38 lore raw

PATCH v5 3/4 arm64, numa, dt: adding dt based numa support using dt node property arm, associativity

In reply to Ganapatrao Kulkarni

Adding dt node pasring for numa topology using property arm,associativity. arm,associativity property can be used to map memory, cpu and io devices to numa node.

---
 arch/arm64/Kconfig            |   6 +
 arch/arm64/include/asm/numa.h |   7 +
 arch/arm64/kernel/Makefile    |   1 +
 arch/arm64/kernel/dt_numa.c   | 316 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/smp.c       |   1 +
 arch/arm64/mm/numa.c          |  13 ++
 6 files changed, 344 insertions(+)
 create mode 100644 arch/arm64/kernel/dt_numa.c
arch/arm64/Kconfig +6 -0
index fa37a5d..ca0f701 100644
@@ -571,6 +571,12 @@ config NUMA
 	  local memory controller of the CPU and add some more
 	  NUMA awareness to the kernel.
 
+config ARM64_DT_NUMA
+	bool "Device Tree NUMA support"
+	depends on NUMA
+	help
+	  Enable Device Tree NUMA support.
+
 config NODES_SHIFT
 	int "Maximum NUMA Nodes (as a power of 2)"
 	range 1 10
arch/arm64/include/asm/numa.h +7 -0
index 59b834e..40c0997 100644
@@ -33,10 +33,17 @@ int __init numa_add_memblk(u32 nodeid, u64 start, u64 end);
 void numa_store_cpu_info(int cpu);
 void __init build_cpu_to_node_map(void);
 void __init numa_set_distance(int from, int to, int distance);
+#if defined(CONFIG_ARM64_DT_NUMA)
+void __init dt_numa_set_node_info(u32 cpu, u64 hwid, void *dn);
+#else
+static inline void dt_numa_set_node_info(u32 cpu, u64 hwid, void *dn) { }
+#endif
+int __init arm64_dt_numa_init(void);
 #else	/* CONFIG_NUMA */
 static inline void numa_store_cpu_info(int cpu)		{ }
 static inline void arm64_numa_init(void)		{ }
 static inline void build_cpu_to_node_map(void) { }
 static inline void numa_set_distance(int from, int to, int distance) { }
+static inline void dt_numa_set_node_info(u32 cpu, u64 hwid, void *dn) { }
 #endif	/* CONFIG_NUMA */
 #endif	/* _ASM_NUMA_H */
arch/arm64/kernel/Makefile +1 -0
index 9add37b..bc7954b 100644
@@ -37,6 +37,7 @@ arm64-obj-$(CONFIG_PCI)			+= pci.o
 arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
 arm64-obj-$(CONFIG_ACPI)		+= pci-acpi.o
 arm64-obj-$(CONFIG_ACPI)		+= acpi.o
+arm64-obj-$(CONFIG_ARM64_DT_NUMA)	+= dt_numa.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
arch/arm64/kernel/dt_numa.c new file +316 -0

316 lines not on this page · raw message

arch/arm64/kernel/smp.c +1 -0
index ae3e02c..bdf0358 100644
@@ -503,6 +503,7 @@ void __init of_parse_and_init_cpus(void)
 
 		pr_debug("cpu logical map 0x%llx\n", hwid);
 		cpu_logical_map(cpu_count) = hwid;
+		dt_numa_set_node_info(cpu_count, hwid, (void *)dn);
 next:
 		cpu_count++;
 	}
arch/arm64/mm/numa.c +13 -0
index 2be83de..0c879eb 100644
@@ -28,6 +28,7 @@
 #include <linux/nodemask.h>
 #include <linux/sched.h>
 #include <linux/topology.h>
+#include <linux/of.h>
 #include <linux/mmzone.h>
 
 #include <asm/smp_plat.h>
@@ -546,5 +547,17 @@ static int __init dummy_numa_init(void)
  */
 void __init arm64_numa_init(void)
 {
+	int (*init_func)(void);
+
+	if (IS_ENABLED(CONFIG_ARM64_DT_NUMA))
+		init_func = arm64_dt_numa_init;
+	else
+		init_func = NULL;
+
+	if (!numa_off && init_func) {
+		if (!numa_init(init_func))
+			return;
+	}
+
 	numa_init(dummy_numa_init);
 }
Signature · 1 line
1.8.1.4
maintainer
#39 lore raw

PATCH v5 3/4 arm64, numa, dt: adding dt based numa support using dt node property arm, associativity

Quoted 4 lines · Ganapatrao Kulkarni

Adding dt node pasring for numa topology using property arm,associativity. arm,associativity property can be used to map memory, cpu and io devices to numa node.

Quoted 8 lines
---
 arch/arm64/Kconfig            |   6 +
 arch/arm64/include/asm/numa.h |   7 +
 arch/arm64/kernel/Makefile    |   1 +
 arch/arm64/kernel/dt_numa.c   | 316 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/smp.c       |   1 +
 arch/arm64/mm/numa.c          |  13 ++

Since a lot of code here is very similar to powerpc, any chance of making it common, especially if we try to use the same bindings (maybe with a different prefix ("arm," vs "ibm,")? See
https://members.openpowerfoundation.org/document/dl/469.

Also, since this series is from August, any chance to post another and incorporate the feedback provided so far?

Signature · 1 line
Catalin
#40 lore raw

PATCH v5 3/4 arm64, numa, dt: adding dt based numa support using dt node property arm, associativity

Hi Catalin,

Quoted 14 lines · Catalin Marinas
Quoted 4 lines · Ganapatrao Kulkarni

Adding dt node pasring for numa topology using property arm,associativity. arm,associativity property can be used to map memory, cpu and io devices to numa node.

Quoted 8 lines
---
 arch/arm64/Kconfig            |   6 +
 arch/arm64/include/asm/numa.h |   7 +
 arch/arm64/kernel/Makefile    |   1 +
 arch/arm64/kernel/dt_numa.c   | 316 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/smp.c       |   1 +
 arch/arm64/mm/numa.c          |  13 ++
Quoted 4 lines

Since a lot of code here is very similar to powerpc, any chance of making it common, especially if we try to use the same bindings (maybe with a different prefix ("arm," vs "ibm,")? See
https://members.openpowerfoundation.org/document/dl/469.

there is discussion happened in Documentation patch (PATCH 2/4), whether to go with associativity based dt binding or not.
https://patchwork.ozlabs.org/patch/507536/
it seems this binding may not map or will be complex representation for numa topologies like mesh, ring topologies
which are used in upcoming arm64 numa platforms(as Mark Rutland pointed out). in this regard, i have proposed new binding, which will be based on associativity and acpi.
This binding will serve wide range of arm64 platforms.
i am waiting for review comments for the proposal, however i can post next version of patchset with new proposal implemented.

Quoted 6 lines

Also, since this series is from August, any chance to post another and incorporate the feedback provided so far?

--
Catalin

thanks
Ganapat

#41 lore raw

PATCH v5 4/4 arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node topology.

In reply to Ganapatrao Kulkarni

adding dt file for Cavium's Thunder SoC in 2 Node topology using arm,associativity device node property.

---
 arch/arm64/boot/dts/cavium/Makefile             |   2 +-
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790 ++++++++++++++++++++++++
 3 files changed, 869 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
 create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi
arch/arm64/boot/dts/cavium/Makefile +1 -1
index e34f89d..7fe7067 100644
@@ -1,4 +1,4 @@
-dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtb
+dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtb thunder-88xx-2n.dtb
 
 always		:= $(dtb-y)
 subdir-y	:= $(dts-dirs)
arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts new file +78 -0

78 lines not on this page · raw message

arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi new file +790 -0

790 lines not on this page · raw message

Signature · 1 line
1.8.1.4
#42 lore raw

PATCH v5 4/4 arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node topology.

Dear Ganapatrao,

Quoted 53 lines · On Fri, 14 Aug 2015 22:09:34 +0530 Ganapatrao Kulkarni…

adding dt file for Cavium's Thunder SoC in 2 Node topology using arm,associativity device node property.

---
 arch/arm64/boot/dts/cavium/Makefile             |   2 +-
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790 ++++++++++++++++++++++++
 3 files changed, 869 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
 create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi
arch/arm64/boot/dts/cavium/Makefile +1 -1
index e34f89d..7fe7067 100644
@@ -1,4 +1,4 @@
-dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtb
+dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtb thunder-88xx-2n.dtb
 
 always		:= $(dtb-y)
 subdir-y	:= $(dts-dirs)
arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts new file +24 -0
new file mode 100644
index 0000000..adbd3a9
@@ -0,0 +1,78 @@
+/*
+ * 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
Quoted 1 line

From the kernel logs, seems this FSF mailing address isn't valid.

It's better to remove this paragraph about writing to FSF

I also submitted a patch to remove this paragraph from existing thunder-88xx dts:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358225.html

Thanks,
Jisheng

#43 lore raw

v5 cover arm64, numa: Add numa support for arm64 platforms.

In reply to Ganapatrao Kulkarni
Quoted 59 lines · Ganapatrao Kulkarni

v5:
- created base verion of numa.c which creates dummy numa without using dt on single socket platforms. Then added patches for dt support.
- Incorporated review comments from Hanjun Guo.

v4:
done changes as per Arnd review comments.

v3:
Added changes to support numa on arm64 based platforms. Tested these patches on cavium's multinode(2 node topology) platform. In this patchset, defined and implemented dt bindings for numa mapping for core and memory using device node property arm,associativity.

v2:
Defined and implemented numa map for memory, cores to node and proximity distance matrix of nodes.

v1:
Initial patchset to support numa on arm64 platforms.

Note:
1. This patchset is tested for numa with dt on
thunderx single socket and dual socket boards.
2. Numa DT booting needs the dt memory nodes, which are deleted in current efi-stub, hence to try numa with dt, you need to rebase with ard's patchset.
http://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/heads/arm64-uefi-early-fdt-handling

Ganapatrao Kulkarni (4):
arm64, numa: adding numa support for arm64 platforms.
Documentation: arm64/arm: dt bindings for numa.
arm64, numa: adding numa support for arm64 platforms. arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node
topology.

 Documentation/devicetree/bindings/arm/numa.txt  | 212 +++++++
 arch/arm64/Kconfig                              |  32 +
 arch/arm64/boot/dts/cavium/Makefile             |   2 +-
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790 ++++++++++++++++++++++++
 arch/arm64/include/asm/mmzone.h                 |  32 +
 arch/arm64/include/asm/numa.h                   |  49 ++
 arch/arm64/kernel/Makefile                      |   1 +
 arch/arm64/kernel/dt_numa.c                     | 316 ++++++++++
 arch/arm64/kernel/setup.c                       |   9 +
 arch/arm64/kernel/smp.c                         |   3 +
 arch/arm64/mm/Makefile                          |   1 +
 arch/arm64/mm/init.c                            |  34 +-
 arch/arm64/mm/numa.c                            | 563 +++++++++++++++++
 14 files changed, 2115 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
 create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
 create mode 100644 arch/arm64/boot/dts/cavium/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/kernel/dt_numa.c
 create mode 100644 arch/arm64/mm/numa.c
Quoted 3 lines

--
1.8.1.4

sorry, minor correction, this patchset has 4 patches.

PATCH v5 0/8 => PATCH v5 0/4

#44 lore raw

v5 cover arm64, numa: Add numa support for arm64 platforms.

Hi Maintainers,

Quoted 61 lines · Ganapatrao Kulkarni
Quoted 59 lines · Ganapatrao Kulkarni

v5:
- created base verion of numa.c which creates dummy numa without using dt on single socket platforms. Then added patches for dt support.
- Incorporated review comments from Hanjun Guo.

v4:
done changes as per Arnd review comments.

v3:
Added changes to support numa on arm64 based platforms. Tested these patches on cavium's multinode(2 node topology) platform. In this patchset, defined and implemented dt bindings for numa mapping for core and memory using device node property arm,associativity.

v2:
Defined and implemented numa map for memory, cores to node and proximity distance matrix of nodes.

v1:
Initial patchset to support numa on arm64 platforms.

Note:
1. This patchset is tested for numa with dt on
thunderx single socket and dual socket boards.
2. Numa DT booting needs the dt memory nodes, which are deleted in current efi-stub, hence to try numa with dt, you need to rebase with ard's patchset.
http://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/heads/arm64-uefi-early-fdt-handling

Ganapatrao Kulkarni (4):
arm64, numa: adding numa support for arm64 platforms.
Documentation: arm64/arm: dt bindings for numa.
arm64, numa: adding numa support for arm64 platforms. arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node
topology.

 Documentation/devicetree/bindings/arm/numa.txt  | 212 +++++++
 arch/arm64/Kconfig                              |  32 +
 arch/arm64/boot/dts/cavium/Makefile             |   2 +-
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790 ++++++++++++++++++++++++
 arch/arm64/include/asm/mmzone.h                 |  32 +
 arch/arm64/include/asm/numa.h                   |  49 ++
 arch/arm64/kernel/Makefile                      |   1 +
 arch/arm64/kernel/dt_numa.c                     | 316 ++++++++++
 arch/arm64/kernel/setup.c                       |   9 +
 arch/arm64/kernel/smp.c                         |   3 +
 arch/arm64/mm/Makefile                          |   1 +
 arch/arm64/mm/init.c                            |  34 +-
 arch/arm64/mm/numa.c                            | 563 +++++++++++++++++
 14 files changed, 2115 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
 create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
 create mode 100644 arch/arm64/boot/dts/cavium/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/kernel/dt_numa.c
 create mode 100644 arch/arm64/mm/numa.c
Quoted 6 lines
Quoted 3 lines

--
1.8.1.4

sorry, minor correction, this patchset has 4 patches.

PATCH v5 0/8 => PATCH v5 0/4

please review this patchset.

thanks
Ganapat

#45 lore raw

v5 cover arm64, numa: Add numa support for arm64 platforms.

In reply to Ganapatrao Kulkarni
Quoted 51 lines · Ganapatrao Kulkarni

v5:
- created base verion of numa.c which creates dummy numa without using dt on single socket platforms. Then added patches for dt support.
- Incorporated review comments from Hanjun Guo.

v4:
done changes as per Arnd review comments.

v3:
Added changes to support numa on arm64 based platforms. Tested these patches on cavium's multinode(2 node topology) platform. In this patchset, defined and implemented dt bindings for numa mapping for core and memory using device node property arm,associativity.

v2:
Defined and implemented numa map for memory, cores to node and proximity distance matrix of nodes.

v1:
Initial patchset to support numa on arm64 platforms.

Note:
1. This patchset is tested for numa with dt on
thunderx single socket and dual socket boards.
2. Numa DT booting needs the dt memory nodes, which are deleted in current efi-stub, hence to try numa with dt, you need to rebase with ard's patchset.
http://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/heads/arm64-uefi-early-fdt-handling

Ganapatrao Kulkarni (4):
arm64, numa: adding numa support for arm64 platforms.
Documentation: arm64/arm: dt bindings for numa.
arm64, numa: adding numa support for arm64 platforms. arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node
topology.

  Documentation/devicetree/bindings/arm/numa.txt  | 212 +++++++
  arch/arm64/Kconfig                              |  32 +
  arch/arm64/boot/dts/cavium/Makefile             |   2 +-
  arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
  arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790 ++++++++++++++++++++++++
  arch/arm64/include/asm/mmzone.h                 |  32 +
  arch/arm64/include/asm/numa.h                   |  49 ++
  arch/arm64/kernel/Makefile                      |   1 +
  arch/arm64/kernel/dt_numa.c                     | 316 ++++++++++
  arch/arm64/kernel/setup.c                       |   9 +
  arch/arm64/kernel/smp.c                         |   3 +
  arch/arm64/mm/Makefile                          |   1 +
  arch/arm64/mm/init.c                            |  34 +-
  arch/arm64/mm/numa.c                            | 563 +++++++++++++++++
  14 files changed, 2115 insertions(+), 7 deletions(-)
Quoted 8 lines

create mode 100644 Documentation/devicetree/bindings/arm/numa.txt create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts create mode 100644 arch/arm64/boot/dts/cavium/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/kernel/dt_numa.c
create mode 100644 arch/arm64/mm/numa.c

On which version is this patch-set based?

Regards,
Matthias

#46 lore raw

v5 cover arm64, numa: Add numa support for arm64 platforms.

Quoted 68 lines · Matthias Brugger
Quoted 56 lines · Ganapatrao Kulkarni

v5:
- created base verion of numa.c which creates dummy numa without
using dt
on single socket platforms. Then added patches for dt support.
- Incorporated review comments from Hanjun Guo.

v4:
done changes as per Arnd review comments.

v3:
Added changes to support numa on arm64 based platforms. Tested these patches on cavium's multinode(2 node topology) platform. In this patchset, defined and implemented dt bindings for numa mapping for core and memory using device node property arm,associativity.

v2:
Defined and implemented numa map for memory, cores to node and proximity distance matrix of nodes.

v1:
Initial patchset to support numa on arm64 platforms.

Note:
1. This patchset is tested for numa with dt on thunderx single socket and dual socket boards.
2. Numa DT booting needs the dt memory nodes, which are deleted in
current efi-stub,
hence to try numa with dt, you need to rebase with ard's patchset.

http://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/heads/arm64-uefi-early-fdt-handling

Ganapatrao Kulkarni (4):
arm64, numa: adding numa support for arm64 platforms.
Documentation: arm64/arm: dt bindings for numa.
arm64, numa: adding numa support for arm64 platforms. arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node
topology.

  Documentation/devicetree/bindings/arm/numa.txt  | 212 +++++++
  arch/arm64/Kconfig                              |  32 +
  arch/arm64/boot/dts/cavium/Makefile             |   2 +-
  arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
  arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790
++++++++++++++++++++++++
  arch/arm64/include/asm/mmzone.h                 |  32 +
  arch/arm64/include/asm/numa.h                   |  49 ++
  arch/arm64/kernel/Makefile                      |   1 +
  arch/arm64/kernel/dt_numa.c                     | 316 ++++++++++
  arch/arm64/kernel/setup.c                       |   9 +
  arch/arm64/kernel/smp.c                         |   3 +
  arch/arm64/mm/Makefile                          |   1 +
  arch/arm64/mm/init.c                            |  34 +-
  arch/arm64/mm/numa.c                            | 563 +++++++++++++++++
  14 files changed, 2115 insertions(+), 7 deletions(-)
Quoted 8 lines

create mode 100644 Documentation/devicetree/bindings/arm/numa.txt create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts create mode 100644 arch/arm64/boot/dts/cavium/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/kernel/dt_numa.c
create mode 100644 arch/arm64/mm/numa.c

Quoted 1 line

On which version is this patch-set based?

4.2 -rc5

Quoted 3 lines

Regards,
Matthias

thanks
Ganapat

#47 lore raw

v5 cover arm64, numa: Add numa support for arm64 platforms.

Quoted 70 lines · Ganapatrao Kulkarni
Quoted 68 lines · Matthias Brugger
Quoted 64 lines · Ganapatrao Kulkarni

v5:
- created base verion of numa.c which creates dummy numa without
using dt
on single socket platforms. Then added patches for dt support.
- Incorporated review comments from Hanjun Guo.

v4:
done changes as per Arnd review comments.

v3:
Added changes to support numa on arm64 based platforms. Tested these patches on cavium's multinode(2 node topology) platform. In this patchset, defined and implemented dt bindings for numa mapping for core and memory using device node property arm,associativity.

v2:
Defined and implemented numa map for memory, cores to node and proximity distance matrix of nodes.

v1:
Initial patchset to support numa on arm64 platforms.

Note:
1. This patchset is tested for numa with dt on thunderx single socket and dual socket boards.
2. Numa DT booting needs the dt memory nodes, which are deleted in
current efi-stub,
hence to try numa with dt, you need to rebase with ard's patchset.

http://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/heads/arm64-uefi-early-fdt-handling

Ganapatrao Kulkarni (4):
arm64, numa: adding numa support for arm64 platforms.
Documentation: arm64/arm: dt bindings for numa.
arm64, numa: adding numa support for arm64 platforms. arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node
topology.

   Documentation/devicetree/bindings/arm/numa.txt  | 212 +++++++
   arch/arm64/Kconfig                              |  32 +
   arch/arm64/boot/dts/cavium/Makefile             |   2 +-
   arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
   arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790
++++++++++++++++++++++++
   arch/arm64/include/asm/mmzone.h                 |  32 +
   arch/arm64/include/asm/numa.h                   |  49 ++
   arch/arm64/kernel/Makefile                      |   1 +
   arch/arm64/kernel/dt_numa.c                     | 316 ++++++++++
   arch/arm64/kernel/setup.c                       |   9 +
   arch/arm64/kernel/smp.c                         |   3 +
   arch/arm64/mm/Makefile                          |   1 +
   arch/arm64/mm/init.c                            |  34 +-
   arch/arm64/mm/numa.c                            | 563 +++++++++++++++++
   14 files changed, 2115 insertions(+), 7 deletions(-)

create mode 100644 Documentation/devicetree/bindings/arm/numa.txt create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts create mode 100644 arch/arm64/boot/dts/cavium/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/kernel/dt_numa.c
create mode 100644 arch/arm64/mm/numa.c

Quoted 2 lines
Quoted 1 line

On which version is this patch-set based?

4.2 -rc5

Seems as if
"arm64: add support for memtest" (36dd9086cb)
is not taken into account. I wasn't able to apply the set without conflicts, neither on v4.2-rc5, v4.2-rc8, nor on arm64-uefi-early-fdt-handling.

Regards,
Matthias