linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms
@ 2016-02-20  1:13 David Daney
  2016-02-20  1:13 ` [PATCH v11 01/10] of/fdt: make generic early_init_dt_add_memory_arch() a weak alias David Daney
                   ` (10 more replies)
  0 siblings, 11 replies; 22+ messages in thread
From: David Daney @ 2016-02-20  1:13 UTC (permalink / raw)
  To: Will Deacon, linux-arm-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter
  Cc: linux-kernel, David Daney

From: David Daney <david.daney@cavium.com>

v11:
	- Dropped cleanup patches for other architectures, they will be
          submitted as a separate set after more testing.

	- Added patch set from Ard Biesheuvel that are needed to make
          the whole thing actually work.  Previously this was a
          separate set.

	- Kconfig and other fixes and simplifications as suggested by Rob Herring.

	- Rearranged, refactored and reordered so that we don't patch
          new files multiple times.

	- Summary:

		o 6 patches from Ard Biesheuvel to allow use of
		  "memory" nodes with efi stub.

		o 2 patches to document and add of_numa.c

		o 1 patch to add arm64 NUMA support.

		o 1 patch to add NUMA balancing support for arm64.

v10:
	- Incorporated review comments from Rob Herring.
	- Moved numa binding and implementation to devicetree core.
	- Added cleanup patch to remove redundant NODE_DATA macro from asm header files
	- Include numa balancing support for arm64 patch in this series.
	- Fix tile build issue reported by the kbuild robot(patch 7)

v9:	- Added cleanup patch to reuse and avoid redefinition of cpumask_of_pcibus
	  as suggested from Will Deacon and Bjorn Helgaas.
	  - Including patch to Make pci-host-generic driver numa aware.
	  - Incorporated comment from Shannon Zhao.

v8:
	- Incorporated review comments of Mark Rutland and Will Deacon.
	- Added pci helper function and macro for numa.

v7:
	- managing numa memory mapping using memblock.
	- Incorporated review comments of Mark Rutland.

v6:
	- defined and implemented the numa dt binding using
	node property proximity and device node distance-map.
	- renamed dt_numa to of_numa

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 and without NUMA with dt
        (both with and without NUMA bindings) on thunderx single
        socket and dual socket boards.


Ard Biesheuvel (6):
  of/fdt: make generic early_init_dt_add_memory_arch() a weak alias
  arm64: override generic version of early_init_dt_add_memory_arch()
  efi: move FDT handling to separate object file
  arm64/efi: move EFI /chosen node parsing before early FDT processing
  arm64/efi: ignore DT memory nodes instead of removing them
  arm64/efi: ignore DT memreserve entries instead of removing them

Ganapatrao Kulkarni (4):
  Documentation, dt, numa: dt bindings for NUMA.
  dt, numa: Add NUMA dt binding implementation.
  arm64, numa: Add NUMA support for arm64 platforms.
  arm64, mm, numa: Add NUMA balancing support for arm64.

 Documentation/devicetree/bindings/numa.txt | 272 +++++++++++++++++++
 arch/arm64/Kconfig                         |  27 ++
 arch/arm64/include/asm/efi.h               |   2 +
 arch/arm64/include/asm/mmzone.h            |  12 +
 arch/arm64/include/asm/numa.h              |  45 ++++
 arch/arm64/include/asm/pgtable.h           |  15 ++
 arch/arm64/include/asm/topology.h          |  10 +
 arch/arm64/kernel/pci.c                    |  10 +
 arch/arm64/kernel/setup.c                  |   7 +
 arch/arm64/kernel/smp.c                    |   4 +
 arch/arm64/mm/Makefile                     |   1 +
 arch/arm64/mm/init.c                       |  46 +++-
 arch/arm64/mm/mmu.c                        |   1 +
 arch/arm64/mm/numa.c                       | 403 +++++++++++++++++++++++++++++
 drivers/firmware/efi/Makefile              |   1 +
 drivers/firmware/efi/arm-init.c            |  36 ++-
 drivers/firmware/efi/efi-fdt.c             |  73 ++++++
 drivers/firmware/efi/efi.c                 |  84 ------
 drivers/firmware/efi/libstub/fdt.c         |  33 +--
 drivers/of/Kconfig                         |   3 +
 drivers/of/Makefile                        |   1 +
 drivers/of/fdt.c                           |   7 +-
 drivers/of/of_numa.c                       | 211 +++++++++++++++
 include/linux/efi.h                        |   2 +-
 include/linux/of.h                         |   9 +
 include/linux/of_fdt.h                     |   1 +
 26 files changed, 1178 insertions(+), 138 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/numa.txt
 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
 create mode 100644 drivers/firmware/efi/efi-fdt.c
 create mode 100644 drivers/of/of_numa.c

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v11 01/10] of/fdt: make generic early_init_dt_add_memory_arch() a weak alias
  2016-02-20  1:13 [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms David Daney
@ 2016-02-20  1:13 ` David Daney
  2016-02-20  1:13 ` [PATCH v11 02/10] arm64: override generic version of early_init_dt_add_memory_arch() David Daney
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2016-02-20  1:13 UTC (permalink / raw)
  To: Will Deacon, linux-arm-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter
  Cc: linux-kernel, David Daney

From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

The function early_init_dt_add_memory_arch() is defined as __weak
so that archs can override it. However, in this override implementation,
it may still be useful to invoke the generic implementation, so instead,
rename the generic version to early_init_dt_add_memory() and turn the
original definition into a weak alias. This way, the generic version can
still be called even in the presence of an arch specific override.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: David Daney <david.daney@cavium.com>
---
 drivers/of/fdt.c       | 7 +++++--
 include/linux/of_fdt.h | 1 +
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 655f79d..cba8281 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -980,7 +980,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 #define MAX_MEMBLOCK_ADDR	((phys_addr_t)~0)
 #endif
 
-void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
+void __init early_init_dt_add_memory(u64 base, u64 size)
 {
 	const u64 phys_offset = __pa(PAGE_OFFSET);
 
@@ -1038,7 +1038,7 @@ void * __init __weak early_init_dt_alloc_memory_arch(u64 size, u64 align)
 	return __va(memblock_alloc(size, align));
 }
 #else
-void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
+void __init early_init_dt_add_memory(u64 base, u64 size)
 {
 	WARN_ON(1);
 }
@@ -1058,6 +1058,9 @@ void * __init __weak early_init_dt_alloc_memory_arch(u64 size, u64 align)
 }
 #endif
 
+__weak __alias(early_init_dt_add_memory)
+void early_init_dt_add_memory_arch(u64 base, u64 size);
+
 bool __init early_init_dt_verify(void *params)
 {
 	if (!params)
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index df9ef38..463a06b 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -65,6 +65,7 @@ extern int early_init_dt_scan_memory(unsigned long node, const char *uname,
 				     int depth, void *data);
 extern void early_init_fdt_scan_reserved_mem(void);
 extern void early_init_fdt_reserve_self(void);
+extern void early_init_dt_add_memory(u64 base, u64 size);
 extern void early_init_dt_add_memory_arch(u64 base, u64 size);
 extern int early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t size,
 					     bool no_map);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v11 02/10] arm64: override generic version of early_init_dt_add_memory_arch()
  2016-02-20  1:13 [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms David Daney
  2016-02-20  1:13 ` [PATCH v11 01/10] of/fdt: make generic early_init_dt_add_memory_arch() a weak alias David Daney
@ 2016-02-20  1:13 ` David Daney
  2016-02-20  1:13 ` [PATCH v11 03/10] efi: move FDT handling to separate object file David Daney
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2016-02-20  1:13 UTC (permalink / raw)
  To: Will Deacon, linux-arm-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter
  Cc: linux-kernel, David Daney

From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Override the __weak early_init_dt_add_memory_arch() with our own
version. We need this in a subsequent patch to make the handling of
the memory nodes conditional on whether we are booting via UEFI or
not. Note that for now, all that our version does is invoke the generic
implementation.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: David Daney <david.daney@cavium.com>
---
 arch/arm64/mm/init.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index f3b061e..208c1d3 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -380,3 +380,8 @@ static int __init keepinitrd_setup(char *__unused)
 
 __setup("keepinitrd", keepinitrd_setup);
 #endif
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+	early_init_dt_add_memory(base, size);
+}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v11 03/10] efi: move FDT handling to separate object file
  2016-02-20  1:13 [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms David Daney
  2016-02-20  1:13 ` [PATCH v11 01/10] of/fdt: make generic early_init_dt_add_memory_arch() a weak alias David Daney
  2016-02-20  1:13 ` [PATCH v11 02/10] arm64: override generic version of early_init_dt_add_memory_arch() David Daney
@ 2016-02-20  1:13 ` David Daney
  2016-02-20  1:13 ` [PATCH v11 04/10] arm64/efi: move EFI /chosen node parsing before early FDT processing David Daney
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2016-02-20  1:13 UTC (permalink / raw)
  To: Will Deacon, linux-arm-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter
  Cc: linux-kernel, David Daney

From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

The EFI specific FDT handling is compiled conditionally, and is
logically independent of the rest of efi.o. So move it to a separate
file before making changes to it in subsequent patches.

Acked-by: Matt Fleming <matt.fleming@intel.com>
Acked-by: Leif Lindholm <leif.lindholm@linaro.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
[ rric: Ported to v4.5-rc1 ]
Signed-off-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: David Daney <david.daney@cavium.com>
---
 drivers/firmware/efi/Makefile  |  1 +
 drivers/firmware/efi/efi-fdt.c | 91 ++++++++++++++++++++++++++++++++++++++++++
 drivers/firmware/efi/efi.c     | 84 --------------------------------------
 3 files changed, 92 insertions(+), 84 deletions(-)
 create mode 100644 drivers/firmware/efi/efi-fdt.c

diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 62e654f..bb7ec2f 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
 obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)	+= runtime-wrappers.o
 obj-$(CONFIG_EFI_STUB)			+= libstub/
 obj-$(CONFIG_EFI_FAKE_MEMMAP)		+= fake_mem.o
+obj-$(CONFIG_EFI_PARAMS_FROM_FDT)	+= efi-fdt.o
 
 arm-obj-$(CONFIG_EFI)			:= arm-init.o arm-runtime.o
 obj-$(CONFIG_ARM)			+= $(arm-obj-y)
diff --git a/drivers/firmware/efi/efi-fdt.c b/drivers/firmware/efi/efi-fdt.c
new file mode 100644
index 0000000..8f3ce66
--- /dev/null
+++ b/drivers/firmware/efi/efi-fdt.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2013 - 2015 Linaro Ltd.
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/efi.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+
+#define UEFI_PARAM(name, prop, field)			   \
+	{						   \
+		{ name },				   \
+		{ prop },				   \
+		offsetof(struct efi_fdt_params, field),    \
+		FIELD_SIZEOF(struct efi_fdt_params, field) \
+	}
+
+static __initdata struct {
+	const char name[32];
+	const char propname[32];
+	int offset;
+	int size;
+} dt_params[] = {
+	UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
+	UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
+	UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
+	UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
+	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
+};
+
+struct param_info {
+	int found;
+	void *params;
+};
+
+static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
+				       int depth, void *data)
+{
+	struct param_info *info = data;
+	const void *prop;
+	void *dest;
+	u64 val;
+	int i, len;
+
+	if (depth != 1 || strcmp(uname, "chosen") != 0)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
+		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
+		if (!prop)
+			return 0;
+		dest = info->params + dt_params[i].offset;
+		info->found++;
+
+		val = of_read_number(prop, len / sizeof(u32));
+
+		if (dt_params[i].size == sizeof(u32))
+			*(u32 *)dest = val;
+		else
+			*(u64 *)dest = val;
+
+		if (efi_enabled(EFI_DBG))
+			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
+				dt_params[i].size * 2, val);
+	}
+	return 1;
+}
+
+int __init efi_get_fdt_params(struct efi_fdt_params *params)
+{
+	struct param_info info;
+	int ret;
+
+	pr_info("Getting EFI parameters from FDT:\n");
+
+	info.found = 0;
+	info.params = params;
+
+	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
+	if (!info.found)
+		pr_info("UEFI not found.\n");
+	else if (!ret)
+		pr_err("Can't find '%s' in device tree!\n",
+		       dt_params[info.found].name);
+
+	return ret;
+}
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 2cd37da..7c41c428 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -20,8 +20,6 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/efi.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 
@@ -490,88 +488,6 @@ static int __init efi_load_efivars(void)
 device_initcall(efi_load_efivars);
 #endif
 
-#ifdef CONFIG_EFI_PARAMS_FROM_FDT
-
-#define UEFI_PARAM(name, prop, field)			   \
-	{						   \
-		{ name },				   \
-		{ prop },				   \
-		offsetof(struct efi_fdt_params, field),    \
-		FIELD_SIZEOF(struct efi_fdt_params, field) \
-	}
-
-static __initdata struct {
-	const char name[32];
-	const char propname[32];
-	int offset;
-	int size;
-} dt_params[] = {
-	UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
-	UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
-	UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
-	UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
-	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
-};
-
-struct param_info {
-	int found;
-	void *params;
-};
-
-static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
-				       int depth, void *data)
-{
-	struct param_info *info = data;
-	const void *prop;
-	void *dest;
-	u64 val;
-	int i, len;
-
-	if (depth != 1 || strcmp(uname, "chosen") != 0)
-		return 0;
-
-	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
-		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
-		if (!prop)
-			return 0;
-		dest = info->params + dt_params[i].offset;
-		info->found++;
-
-		val = of_read_number(prop, len / sizeof(u32));
-
-		if (dt_params[i].size == sizeof(u32))
-			*(u32 *)dest = val;
-		else
-			*(u64 *)dest = val;
-
-		if (efi_enabled(EFI_DBG))
-			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
-				dt_params[i].size * 2, val);
-	}
-	return 1;
-}
-
-int __init efi_get_fdt_params(struct efi_fdt_params *params)
-{
-	struct param_info info;
-	int ret;
-
-	pr_info("Getting EFI parameters from FDT:\n");
-
-	info.found = 0;
-	info.params = params;
-
-	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
-	if (!info.found)
-		pr_info("UEFI not found.\n");
-	else if (!ret)
-		pr_err("Can't find '%s' in device tree!\n",
-		       dt_params[info.found].name);
-
-	return ret;
-}
-#endif /* CONFIG_EFI_PARAMS_FROM_FDT */
-
 static __initdata char memory_type_name[][20] = {
 	"Reserved",
 	"Loader Code",
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v11 04/10] arm64/efi: move EFI /chosen node parsing before early FDT processing
  2016-02-20  1:13 [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms David Daney
                   ` (2 preceding siblings ...)
  2016-02-20  1:13 ` [PATCH v11 03/10] efi: move FDT handling to separate object file David Daney
@ 2016-02-20  1:13 ` David Daney
  2016-02-20  1:13 ` [PATCH v11 05/10] arm64/efi: ignore DT memory nodes instead of removing them David Daney
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2016-02-20  1:13 UTC (permalink / raw)
  To: Will Deacon, linux-arm-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter
  Cc: linux-kernel, David Daney

From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

The early FDT processing is responsible for enumerating the
DT memory nodes and installing them as memblocks. This should
only be done if we are not booting via EFI, but at this point,
we don't know yet if that is the case or not.

So move part of the EFI init to before the early FDT processing. This
involves making some changes to the way EFI discovers the locations of
the EFI system table and the memory map, since those values are retrieved
from the FDT as well. Instead the of_scan infrastructure, it now uses
libfdt directly to access the /chosen node.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
[ rric: Ported to v4.5-rc1 ]
Signed-off-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: David Daney <david.daney@cavium.com>
---
 arch/arm64/include/asm/efi.h    |  2 ++
 arch/arm64/kernel/setup.c       |  3 ++
 drivers/firmware/efi/arm-init.c | 34 ++++++++++++-------
 drivers/firmware/efi/efi-fdt.c  | 72 ++++++++++++++++-------------------------
 include/linux/efi.h             |  2 +-
 5 files changed, 55 insertions(+), 58 deletions(-)

diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 8e88a69..acc7f65 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -8,8 +8,10 @@
 
 #ifdef CONFIG_EFI
 extern void efi_init(void);
+extern void efi_parse_fdt(void *fdt);
 #else
 #define efi_init()
+#define efi_parse_fdt(x)
 #endif
 
 int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 8119479..3f57233 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -181,6 +181,9 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
 {
 	void *dt_virt = fixmap_remap_fdt(dt_phys);
 
+	if (dt_virt)
+		efi_parse_fdt(dt_virt);
+
 	if (!dt_virt || !early_init_dt_scan(dt_virt)) {
 		pr_crit("\n"
 			"Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
index 9e15d57..9fe0464 100644
--- a/drivers/firmware/efi/arm-init.c
+++ b/drivers/firmware/efi/arm-init.c
@@ -170,22 +170,35 @@ static __init void reserve_regions(void)
 		if (efi_enabled(EFI_DBG))
 			pr_cont("\n");
 	}
-
-	set_bit(EFI_MEMMAP, &efi.flags);
 }
 
-void __init efi_init(void)
+void __init efi_parse_fdt(void *fdt)
 {
 	struct efi_fdt_params params;
 
 	/* Grab UEFI information placed in FDT by stub */
-	if (!efi_get_fdt_params(&params))
+	if (!efi_get_fdt_params(fdt, &params))
 		return;
 
 	efi_system_table = params.system_table;
 
 	memmap.phys_map = params.mmap;
-	memmap.map = early_memremap(params.mmap, params.mmap_size);
+	memmap.desc_size = params.desc_size;
+	memmap.desc_version = params.desc_ver;
+	memmap.nr_map = params.mmap_size / params.desc_size;
+
+	set_bit(EFI_MEMMAP, &efi.flags);
+}
+
+void __init efi_init(void)
+{
+	int mmap_size = memmap.nr_map * memmap.desc_size;
+	u64 phys_map  = memmap.phys_map;
+
+	if (!efi_enabled(EFI_MEMMAP))
+		return;
+
+	memmap.map = early_memremap(phys_map, mmap_size);
 	if (memmap.map == NULL) {
 		/*
 		* If we are booting via UEFI, the UEFI memory map is the only
@@ -194,16 +207,13 @@ void __init efi_init(void)
 		*/
 		panic("Unable to map EFI memory map.\n");
 	}
-	memmap.map_end = memmap.map + params.mmap_size;
-	memmap.desc_size = params.desc_size;
-	memmap.desc_version = params.desc_ver;
+	memmap.map_end = memmap.map + mmap_size;
 
 	if (uefi_init() < 0)
 		return;
 
 	reserve_regions();
-	early_memunmap(memmap.map, params.mmap_size);
-	memblock_mark_nomap(params.mmap & PAGE_MASK,
-			    PAGE_ALIGN(params.mmap_size +
-				       (params.mmap & ~PAGE_MASK)));
+	early_memunmap(memmap.map, mmap_size);
+	memblock_mark_nomap(phys_map & PAGE_MASK,
+			    PAGE_ALIGN(mmap_size + (phys_map & ~PAGE_MASK)));
 }
diff --git a/drivers/firmware/efi/efi-fdt.c b/drivers/firmware/efi/efi-fdt.c
index 8f3ce66..e6622d3 100644
--- a/drivers/firmware/efi/efi-fdt.c
+++ b/drivers/firmware/efi/efi-fdt.c
@@ -8,8 +8,7 @@
 
 #include <linux/init.h>
 #include <linux/efi.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
 
 #define UEFI_PARAM(name, prop, field)			   \
 	{						   \
@@ -32,60 +31,43 @@ static __initdata struct {
 	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
 };
 
-struct param_info {
-	int found;
-	void *params;
-};
-
-static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
-				       int depth, void *data)
+int __init efi_get_fdt_params(void *fdt, struct efi_fdt_params *params)
 {
-	struct param_info *info = data;
 	const void *prop;
-	void *dest;
-	u64 val;
-	int i, len;
+	int node, i;
+
+	pr_info("Getting EFI parameters from FDT:\n");
 
-	if (depth != 1 || strcmp(uname, "chosen") != 0)
-		return 0;
+	node = fdt_path_offset(fdt, "/chosen");
+	if (node < 0) {
+		pr_err("/chosen node not found!\n");
+		return false;
+	}
 
 	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
-		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
-		if (!prop)
-			return 0;
-		dest = info->params + dt_params[i].offset;
-		info->found++;
+		void *dest;
+		int len;
+		u64 val;
 
-		val = of_read_number(prop, len / sizeof(u32));
+		prop = fdt_getprop(fdt, node, dt_params[i].propname, &len);
+		if (!prop || len != dt_params[i].size)
+			goto not_found;
+		dest = (void *)params + dt_params[i].offset;
 
 		if (dt_params[i].size == sizeof(u32))
-			*(u32 *)dest = val;
+			val = *(u32 *)dest = be32_to_cpup(prop);
 		else
-			*(u64 *)dest = val;
+			val = *(u64 *)dest = be64_to_cpup(prop);
 
-		if (efi_enabled(EFI_DBG))
-			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
-				dt_params[i].size * 2, val);
+		pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
+			dt_params[i].size * 2, val);
 	}
-	return 1;
-}
+	return true;
 
-int __init efi_get_fdt_params(struct efi_fdt_params *params)
-{
-	struct param_info info;
-	int ret;
-
-	pr_info("Getting EFI parameters from FDT:\n");
-
-	info.found = 0;
-	info.params = params;
-
-	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
-	if (!info.found)
+not_found:
+	if (i == 0)
 		pr_info("UEFI not found.\n");
-	else if (!ret)
-		pr_err("Can't find '%s' in device tree!\n",
-		       dt_params[info.found].name);
-
-	return ret;
+	else
+		pr_err("Can't find '%s' in device tree!\n", dt_params[i].name);
+	return false;
 }
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 569b5a8..ede2c21 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -915,7 +915,7 @@ extern void efi_initialize_iomem_resources(struct resource *code_resource,
 		struct resource *data_resource, struct resource *bss_resource);
 extern void efi_get_time(struct timespec *now);
 extern void efi_reserve_boot_services(void);
-extern int efi_get_fdt_params(struct efi_fdt_params *params);
+extern int efi_get_fdt_params(void *fdt, struct efi_fdt_params *params);
 extern struct efi_memory_map memmap;
 extern struct kobject *efi_kobj;
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v11 05/10] arm64/efi: ignore DT memory nodes instead of removing them
  2016-02-20  1:13 [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms David Daney
                   ` (3 preceding siblings ...)
  2016-02-20  1:13 ` [PATCH v11 04/10] arm64/efi: move EFI /chosen node parsing before early FDT processing David Daney
@ 2016-02-20  1:13 ` David Daney
  2016-02-20  1:13 ` [PATCH v11 06/10] arm64/efi: ignore DT memreserve entries " David Daney
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2016-02-20  1:13 UTC (permalink / raw)
  To: Will Deacon, linux-arm-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter
  Cc: linux-kernel, David Daney

From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

There are two problems with the UEFI stub DT memory node removal
routine:
- it deletes nodes as it traverses the tree, which happens to work
  but is not supported, as deletion invalidates the node iterator;
- deleting memory nodes entirely may discard annotations in the form
  of additional properties on the nodes.

Now that the UEFI initialization has moved to an earlier stage, we can
actually just ignore any memblocks that are installed after we have
processed the UEFI memory map. This way, it is no longer necessary to
remove the nodes, so we can remove that logic from the stub as well.

Acked-by: Leif Lindholm <leif.lindholm@linaro.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
[ rric: Ported to v4.5-rc1 ]
Signed-off-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: David Daney <david.daney@cavium.com>
---
 arch/arm64/mm/init.c               |  6 +++++-
 drivers/firmware/efi/arm-init.c    |  2 +-
 drivers/firmware/efi/libstub/fdt.c | 24 +-----------------------
 3 files changed, 7 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 208c1d3..eda226e 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -383,5 +383,9 @@ __setup("keepinitrd", keepinitrd_setup);
 
 void __init early_init_dt_add_memory_arch(u64 base, u64 size)
 {
-	early_init_dt_add_memory(base, size);
+	/*
+	 * Ignore DT memory nodes if we are booting via UEFI.
+	 */
+	if (!efi_enabled(EFI_MEMMAP))
+		early_init_dt_add_memory(base, size);
 }
diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
index 9fe0464..ded8957 100644
--- a/drivers/firmware/efi/arm-init.c
+++ b/drivers/firmware/efi/arm-init.c
@@ -159,7 +159,7 @@ static __init void reserve_regions(void)
 		size = npages << PAGE_SHIFT;
 
 		if (is_normal_ram(md))
-			early_init_dt_add_memory_arch(paddr, size);
+			early_init_dt_add_memory(paddr, size);
 
 		if (is_reserve_region(md)) {
 			memblock_mark_nomap(paddr, size);
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index cf7b7d4..9df1560 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -24,7 +24,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 			unsigned long map_size, unsigned long desc_size,
 			u32 desc_ver)
 {
-	int node, prev, num_rsv;
+	int node, num_rsv;
 	int status;
 	u32 fdt_val32;
 	u64 fdt_val64;
@@ -54,28 +54,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 		goto fdt_set_fail;
 
 	/*
-	 * Delete any memory nodes present. We must delete nodes which
-	 * early_init_dt_scan_memory may try to use.
-	 */
-	prev = 0;
-	for (;;) {
-		const char *type;
-		int len;
-
-		node = fdt_next_node(fdt, prev, NULL);
-		if (node < 0)
-			break;
-
-		type = fdt_getprop(fdt, node, "device_type", &len);
-		if (type && strncmp(type, "memory", len) == 0) {
-			fdt_del_node(fdt, node);
-			continue;
-		}
-
-		prev = node;
-	}
-
-	/*
 	 * Delete all memory reserve map entries. When booting via UEFI,
 	 * kernel will use the UEFI memory map to find reserved regions.
 	 */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v11 06/10] arm64/efi: ignore DT memreserve entries instead of removing them
  2016-02-20  1:13 [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms David Daney
                   ` (4 preceding siblings ...)
  2016-02-20  1:13 ` [PATCH v11 05/10] arm64/efi: ignore DT memory nodes instead of removing them David Daney
@ 2016-02-20  1:13 ` David Daney
  2016-02-20  1:13 ` [PATCH v11 07/10] Documentation, dt, numa: dt bindings for NUMA David Daney
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2016-02-20  1:13 UTC (permalink / raw)
  To: Will Deacon, linux-arm-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter
  Cc: linux-kernel, David Daney

From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Now that the reservation of the FDT image itself is split off from
the processing of memory reservations described by the device tree,
we can make the DT scanning of memreserves conditional on whether
we booted via UEFI and have its memory map available. This allows
us to drop deletion of these memreserves in the stub. It also fixes
the issue where the /reserved-memory node (which offers another
way of reserving memory ranges) was not being ignored under UEFI.

Note that this reverts commit 0ceac9e094b0 ("efi/arm64: Fix
fdt-related memory reservation").

Acked-by: Leif Lindholm <leif.lindholm@linaro.org>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: David Daney <david.daney@cavium.com>
---
 arch/arm64/mm/init.c               |  3 ++-
 drivers/firmware/efi/libstub/fdt.c | 11 +----------
 2 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index eda226e..ee06165 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -171,7 +171,8 @@ void __init arm64_memblock_init(void)
 		memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
 #endif
 
-	early_init_fdt_scan_reserved_mem();
+	if (!efi_enabled(EFI_MEMMAP))
+		early_init_fdt_scan_reserved_mem();
 
 	/* 4GB maximum for 32-bit only capable devices */
 	if (IS_ENABLED(CONFIG_ZONE_DMA))
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index 9df1560..12cb2a3 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -24,8 +24,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 			unsigned long map_size, unsigned long desc_size,
 			u32 desc_ver)
 {
-	int node, num_rsv;
-	int status;
+	int node, status;
 	u32 fdt_val32;
 	u64 fdt_val64;
 
@@ -53,14 +52,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 	if (status != 0)
 		goto fdt_set_fail;
 
-	/*
-	 * Delete all memory reserve map entries. When booting via UEFI,
-	 * kernel will use the UEFI memory map to find reserved regions.
-	 */
-	num_rsv = fdt_num_mem_rsv(fdt);
-	while (num_rsv-- > 0)
-		fdt_del_mem_rsv(fdt, num_rsv);
-
 	node = fdt_subnode_offset(fdt, 0, "chosen");
 	if (node < 0) {
 		node = fdt_add_subnode(fdt, 0, "chosen");
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v11 07/10] Documentation, dt, numa: dt bindings for NUMA.
  2016-02-20  1:13 [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms David Daney
                   ` (5 preceding siblings ...)
  2016-02-20  1:13 ` [PATCH v11 06/10] arm64/efi: ignore DT memreserve entries " David Daney
@ 2016-02-20  1:13 ` David Daney
  2016-02-20  1:13 ` [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation David Daney
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2016-02-20  1:13 UTC (permalink / raw)
  To: Will Deacon, linux-arm-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter
  Cc: linux-kernel, David Daney

From: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>

Add DT bindings for numa mapping of memory, CPUs and IOs.

Reviewed-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
Signed-off-by: David Daney <david.daney@cavium.com>
---
 Documentation/devicetree/bindings/numa.txt | 272 +++++++++++++++++++++++++++++
 1 file changed, 272 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/numa.txt

diff --git a/Documentation/devicetree/bindings/numa.txt b/Documentation/devicetree/bindings/numa.txt
new file mode 100644
index 0000000..ec5ed7c
--- /dev/null
+++ b/Documentation/devicetree/bindings/numa.txt
@@ -0,0 +1,272 @@
+==============================================================================
+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 - numa-node-id
+==============================================================================
+
+For the purpose of identification, each NUMA node is associated with a unique
+token known as a node id. For the purpose of this binding
+a node id is a 32-bit integer.
+
+A device node is associated with a NUMA node by the presence of a
+numa-node-id property which contains the node id of the device.
+
+Example:
+	/* numa node 0 */
+	numa-node-id = <0>;
+
+	/* numa node 1 */
+	numa-node-id = <1>;
+
+==============================================================================
+3 - distance-map
+==============================================================================
+
+The device tree node distance-map describes the relative
+distance (memory latency) between all numa nodes.
+
+- compatible : Should at least contain "numa-distance-map-v1".
+
+- distance-matrix
+  This property defines a matrix to describe the relative distances
+  between all numa nodes.
+  It is represented as a list of node pairs and their relative distance.
+
+  Note:
+	1. Each entry represents distance from first node to second node.
+	The distances are equal in either direction.
+	2. The distance from a node to self (local distance) is represented
+	with value 10 and all internode distance should be represented with
+	a value greater than 10.
+	3. distance-matrix should have entries in lexicographical ascending
+	order of nodes.
+	4. There must be only one device node distance-map which must reside in the root node.
+
+Example:
+	4 nodes connected in mesh/ring topology as below,
+
+		0_______20______1
+		|               |
+		|               |
+		20             20
+		|               |
+		|               |
+		|_______________|
+		3       20      2
+
+	if relative distance for each hop is 20,
+	then internode distance would be,
+	      0 -> 1 = 20
+	      1 -> 2 = 20
+	      2 -> 3 = 20
+	      3 -> 0 = 20
+	      0 -> 2 = 40
+	      1 -> 3 = 40
+
+     and dt presentation for this distance matrix is,
+
+		distance-map {
+			 compatible = "numa-distance-map-v1";
+			 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>;
+		};
+
+==============================================================================
+4 - Example dts
+==============================================================================
+
+Dual socket system consists of 2 boards connected through ccn bus and
+each board having one socket/soc of 8 cpus, memory and pci bus.
+
+	memory@c00000 {
+		device_type = "memory";
+		reg = <0x0 0xc00000 0x0 0x80000000>;
+		/* node 0 */
+		numa-node-id = <0>;
+	};
+
+	memory@10000000000 {
+		device_type = "memory";
+		reg = <0x100 0x0 0x0 0x80000000>;
+		/* node 1 */
+		numa-node-id = <1>;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			/* node 0 */
+			numa-node-id = <0>;
+		};
+		cpu@1 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@2 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@3 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@4 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x4>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@5 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x5>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@6 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x6>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@7 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x7>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+		cpu@8 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x8>;
+			enable-method = "psci";
+			/* node 1 */
+			numa-node-id = <1>;
+		};
+		cpu@9 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x9>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+		cpu@a {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0xa>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+		cpu@b {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0xb>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+		cpu@c {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0xc>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+		cpu@d {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0xd>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+		cpu@e {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0xe>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+		cpu@f {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0xf>;
+			enable-method = "psci";
+			numa-node-id = <1>;
+		};
+	};
+
+	pcie0: pcie0@848000000000 {
+		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>;
+		/* node 0 */
+		numa-node-id = <0>;
+        };
+
+	pcie1: pcie1@948000000000 {
+		compatible = "arm,armv8";
+		device_type = "pci";
+		bus-range = <0 255>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0x9480 0x00000000 0 0x10000000>;  /* Configuration space */
+		ranges = <0x03000000 0x9010 0x00000000 0x9010 0x00000000 0x70 0x00000000>;
+		/* node 1 */
+		numa-node-id = <1>;
+        };
+
+	distance-map {
+		compatible = "numa-distance-map-v1";
+		distance-matrix = <0 0 10>,
+				  <0 1 20>,
+				  <1 1 10>;
+	};
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation.
  2016-02-20  1:13 [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms David Daney
                   ` (6 preceding siblings ...)
  2016-02-20  1:13 ` [PATCH v11 07/10] Documentation, dt, numa: dt bindings for NUMA David Daney
@ 2016-02-20  1:13 ` David Daney
  2016-02-23 19:36   ` Rob Herring
  2016-02-20  1:13 ` [PATCH v11 09/10] arm64, numa: Add NUMA support for arm64 platforms David Daney
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: David Daney @ 2016-02-20  1:13 UTC (permalink / raw)
  To: Will Deacon, linux-arm-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter
  Cc: linux-kernel, David Daney

From: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>

ADD device tree node parsing for NUMA topology using device
"numa-node-id" property distance-map.

Reviewed-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
Signed-off-by: David Daney <david.daney@cavium.com>
---
 drivers/of/Kconfig   |   3 +
 drivers/of/Makefile  |   1 +
 drivers/of/of_numa.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of.h   |   9 +++
 4 files changed, 224 insertions(+)
 create mode 100644 drivers/of/of_numa.c

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index e2a4841..b3bec3a 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -112,4 +112,7 @@ config OF_OVERLAY
 	  While this option is selected automatically when needed, you can
 	  enable it manually to improve device tree unit test coverage.
 
+config OF_NUMA
+	bool
+
 endif # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 156c072..bee3fa9 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -14,5 +14,6 @@ obj-$(CONFIG_OF_MTD)	+= of_mtd.o
 obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
 obj-$(CONFIG_OF_RESOLVE)  += resolver.o
 obj-$(CONFIG_OF_OVERLAY) += overlay.o
+obj-$(CONFIG_OF_NUMA) += of_numa.o
 
 obj-$(CONFIG_OF_UNITTEST) += unittest-data/
diff --git a/drivers/of/of_numa.c b/drivers/of/of_numa.c
new file mode 100644
index 0000000..a691d06
--- /dev/null
+++ b/drivers/of/of_numa.c
@@ -0,0 +1,211 @@
+/*
+ * OF NUMA Parsing support.
+ *
+ * Copyright (C) 2015 - 2016 Cavium Inc.
+ * Author: Ganapatrao Kulkarni <gkulkarni@cavium.com>
+ *
+ * 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/of.h>
+#include <linux/of_fdt.h>
+#include <linux/nodemask.h>
+
+#include <asm/numa.h>
+
+/* define default numa node to 0 */
+#define DEFAULT_NODE 0
+
+/* Returns nid in the range [0..MAX_NUMNODES-1],
+ * or NUMA_NO_NODE if no valid numa-node-id entry found
+ * or DEFAULT_NODE if no numa-node-id entry exists
+ */
+static int of_numa_prop_to_nid(const __be32 *of_numa_prop, int length)
+{
+	int nid;
+
+	if (!of_numa_prop)
+		return DEFAULT_NODE;
+
+	if (length != sizeof(*of_numa_prop)) {
+		pr_warn("NUMA: Invalid of_numa_prop length %d found.\n",
+				length);
+		return NUMA_NO_NODE;
+	}
+
+	nid = of_read_number(of_numa_prop, 1);
+	if (nid >= MAX_NUMNODES) {
+		pr_warn("NUMA: Invalid numa node %d found.\n", nid);
+		return NUMA_NO_NODE;
+	}
+
+	return nid;
+}
+
+static int __init early_init_of_node_to_nid(unsigned long node)
+{
+	int length;
+	const __be32 *of_numa_prop;
+
+	of_numa_prop = of_get_flat_dt_prop(node, "numa-node-id", &length);
+
+	return of_numa_prop_to_nid(of_numa_prop, length);
+}
+
+/*
+ * Even though we connect cpus to numa domains later in SMP
+ * init, we need to know the node ids now for all cpus.
+*/
+static int __init early_init_parse_cpu_node(unsigned long node)
+{
+	int nid;
+	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+
+	if (type == NULL)
+		return 0;
+
+	if (strcmp(type, "cpu") != 0)
+		return 0;
+
+	nid = early_init_of_node_to_nid(node);
+	if (nid == NUMA_NO_NODE)
+		return -EINVAL;
+
+	node_set(nid, numa_nodes_parsed);
+	return 0;
+}
+
+static int __init early_init_parse_memory_node(unsigned long node)
+{
+	const __be32 *reg, *endp;
+	int length;
+	int nid;
+	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+
+	if (type == NULL)
+		return 0;
+
+	if (strcmp(type, "memory") != 0)
+		return 0;
+
+	nid = early_init_of_node_to_nid(node);
+	if (nid == NUMA_NO_NODE)
+		return -EINVAL;
+
+	reg = of_get_flat_dt_prop(node, "reg", &length);
+	endp = reg + (length / sizeof(__be32));
+
+	while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+		u64 base, size;
+
+		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
+		size = dt_mem_next_cell(dt_root_size_cells, &reg);
+		pr_debug("NUMA:  base = %llx , node = %u\n",
+				base, nid);
+
+		if (numa_add_memblk(nid, base, size) < 0)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int __init early_init_parse_distance_map_v1(unsigned long node,
+		const char *uname)
+{
+	const __be32 *prop_dist_matrix;
+	int length = 0, i, matrix_count;
+	int nr_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
+
+	pr_info("NUMA: parsing numa-distance-map-v1\n");
+
+	prop_dist_matrix =
+		of_get_flat_dt_prop(node, "distance-matrix", &length);
+
+	if (!length) {
+		pr_err("NUMA: failed to parse distance-matrix\n");
+		return -ENODEV;
+	}
+
+	matrix_count = ((length / sizeof(__be32)) / (3 * nr_size_cells));
+
+	if ((matrix_count * sizeof(__be32) * 3 * nr_size_cells) !=  length) {
+		pr_warn("NUMA: invalid distance-matrix length %d\n", length);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < matrix_count; i++) {
+		u32 nodea, nodeb, distance;
+
+		nodea = dt_mem_next_cell(nr_size_cells, &prop_dist_matrix);
+		nodeb = dt_mem_next_cell(nr_size_cells, &prop_dist_matrix);
+		distance = dt_mem_next_cell(nr_size_cells, &prop_dist_matrix);
+		numa_set_distance(nodea, nodeb, distance);
+		pr_debug("NUMA:  distance[node%d -> node%d] = %d\n",
+				nodea, nodeb, distance);
+
+		/* Set default distance of node B->A same as A->B */
+		if (nodeb > nodea)
+			numa_set_distance(nodeb, nodea, distance);
+	}
+
+	return 0;
+}
+
+static int __init early_init_parse_distance_map(unsigned long node,
+		const char *uname)
+{
+	if (strcmp(uname, "distance-map") != 0)
+		return 0;
+
+	if (of_flat_dt_is_compatible(node, "numa-distance-map-v1"))
+		return early_init_parse_distance_map_v1(node, uname);
+
+	pr_err("NUMA: invalid distance-map device node\n");
+	return -EINVAL;
+}
+
+static int __init early_init_of_scan_numa_map(unsigned long node,
+					      const char *uname,
+					      int depth, void *data)
+{
+	int ret;
+
+	ret = early_init_parse_cpu_node(node);
+	if (ret)
+		return ret;
+
+	ret = early_init_parse_memory_node(node);
+	if (ret)
+		return ret;
+
+	return early_init_parse_distance_map(node, uname);
+}
+
+int of_node_to_nid(struct device_node *device)
+{
+	const __be32 *of_numa_prop;
+	int length;
+
+	of_numa_prop = of_get_property(device, "numa-node-id", &length);
+	if (of_numa_prop)
+		return of_numa_prop_to_nid(of_numa_prop, length);
+
+	return NUMA_NO_NODE;
+}
+
+/* DT node mapping is done already early_init_of_scan_memory */
+int __init of_numa_init(void)
+{
+	return of_scan_flat_dt(early_init_of_scan_numa_map, NULL);
+}
diff --git a/include/linux/of.h b/include/linux/of.h
index dc6e396..fe67a4c 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -685,6 +685,15 @@ static inline int of_node_to_nid(struct device_node *device)
 }
 #endif
 
+#ifdef CONFIG_OF_NUMA
+extern int of_numa_init(void);
+#else
+static inline int of_numa_init(void)
+{
+	return -ENOSYS;
+}
+#endif
+
 static inline struct device_node *of_find_matching_node(
 	struct device_node *from,
 	const struct of_device_id *matches)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v11 09/10] arm64, numa: Add NUMA support for arm64 platforms.
  2016-02-20  1:13 [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms David Daney
                   ` (7 preceding siblings ...)
  2016-02-20  1:13 ` [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation David Daney
@ 2016-02-20  1:13 ` David Daney
  2016-02-20  1:13 ` [PATCH v11 10/10] arm64, mm, numa: Add NUMA balancing support for arm64 David Daney
  2016-02-20  8:20 ` [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms Ard Biesheuvel
  10 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2016-02-20  1:13 UTC (permalink / raw)
  To: Will Deacon, linux-arm-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter
  Cc: linux-kernel, David Daney

From: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>

Attempt to get the memory and CPU NUMA node via of_numa.  If that
fails, default the dummy NUMA node and map all memory and CPUs to node
0.

Tested-by: Shannon Zhao <shannon.zhao@linaro.org>
Reviewed-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
Signed-off-by: David Daney <david.daney@cavium.com>
---
 arch/arm64/Kconfig                |  26 +++
 arch/arm64/include/asm/mmzone.h   |  12 ++
 arch/arm64/include/asm/numa.h     |  45 +++++
 arch/arm64/include/asm/topology.h |  10 +
 arch/arm64/kernel/pci.c           |  10 +
 arch/arm64/kernel/setup.c         |   4 +
 arch/arm64/kernel/smp.c           |   4 +
 arch/arm64/mm/Makefile            |   1 +
 arch/arm64/mm/init.c              |  34 +++-
 arch/arm64/mm/mmu.c               |   1 +
 arch/arm64/mm/numa.c              | 403 ++++++++++++++++++++++++++++++++++++++
 11 files changed, 545 insertions(+), 5 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

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index a969970..9f0972a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -74,6 +74,7 @@ config ARM64
 	select HAVE_HW_BREAKPOINT if PERF_EVENTS
 	select HAVE_IRQ_TIME_ACCOUNTING
 	select HAVE_MEMBLOCK
+	select HAVE_MEMBLOCK_NODE_MAP if NUMA
 	select HAVE_PATA_PLATFORM
 	select HAVE_PERF_EVENTS
 	select HAVE_PERF_REGS
@@ -96,6 +97,7 @@ config ARM64
 	select SYSCTL_EXCEPTION_TRACE
 	select HAVE_CONTEXT_TRACKING
 	select HAVE_ARM_SMCCC
+	select OF_NUMA if NUMA && OF
 	help
 	  ARM 64-bit (AArch64) Linux support.
 
@@ -545,6 +547,30 @@ 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 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
 source kernel/Kconfig.hz
 
diff --git a/arch/arm64/include/asm/mmzone.h b/arch/arm64/include/asm/mmzone.h
new file mode 100644
index 0000000..a0de9e6
--- /dev/null
+++ b/arch/arm64/include/asm/mmzone.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_MMZONE_H
+#define __ASM_MMZONE_H
+
+#ifdef CONFIG_NUMA
+
+#include <asm/numa.h>
+
+extern struct pglist_data *node_data[];
+#define NODE_DATA(nid)		(node_data[(nid)])
+
+#endif /* CONFIG_NUMA */
+#endif /* __ASM_MMZONE_H */
diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h
new file mode 100644
index 0000000..e9b4f29
--- /dev/null
+++ b/arch/arm64/include/asm/numa.h
@@ -0,0 +1,45 @@
+#ifndef __ASM_NUMA_H
+#define __ASM_NUMA_H
+
+#include <asm/topology.h>
+
+#ifdef CONFIG_NUMA
+
+/* currently, arm64 implements flat NUMA topology */
+#define parent_node(node)	(node)
+
+int __node_distance(int from, int to);
+#define node_distance(a, b) __node_distance(a, b)
+
+extern nodemask_t numa_nodes_parsed __initdata;
+
+/* Mappings between node number and cpus on that node. */
+extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+void numa_clear_node(unsigned int cpu);
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+const struct cpumask *cpumask_of_node(int node);
+#else
+/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
+static inline const struct cpumask *cpumask_of_node(int node)
+{
+	return node_to_cpumask_map[node];
+}
+#endif
+
+void __init arm64_numa_init(void);
+int __init numa_add_memblk(int nodeid, u64 start, u64 end);
+void __init numa_set_distance(int from, int to, int distance);
+void __init numa_free_distance(void);
+void __init early_map_cpu_to_node(unsigned int cpu, int nid);
+void numa_store_cpu_info(unsigned int cpu);
+
+#else	/* CONFIG_NUMA */
+
+static inline void numa_store_cpu_info(unsigned int cpu) { }
+static inline void arm64_numa_init(void) { }
+static inline void early_map_cpu_to_node(unsigned int cpu, int nid) { }
+
+#endif	/* CONFIG_NUMA */
+
+#endif	/* __ASM_NUMA_H */
diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h
index a3e9d6f..8b57339 100644
--- a/arch/arm64/include/asm/topology.h
+++ b/arch/arm64/include/asm/topology.h
@@ -22,6 +22,16 @@ void init_cpu_topology(void);
 void store_cpu_topology(unsigned int cpuid);
 const struct cpumask *cpu_coregroup_mask(int cpu);
 
+#ifdef CONFIG_NUMA
+
+struct pci_bus;
+int pcibus_to_node(struct pci_bus *bus);
+#define cpumask_of_pcibus(bus)	(pcibus_to_node(bus) == -1 ?		\
+				 cpu_all_mask :				\
+				 cpumask_of_node(pcibus_to_node(bus)))
+
+#endif /* CONFIG_NUMA */
+
 #include <asm-generic/topology.h>
 
 #endif /* _ASM_ARM_TOPOLOGY_H */
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index b3d098b..65e6b7d 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -76,6 +76,16 @@ int raw_pci_write(unsigned int domain, unsigned int bus,
 	return -ENXIO;
 }
 
+#ifdef CONFIG_NUMA
+
+int pcibus_to_node(struct pci_bus *bus)
+{
+	return dev_to_node(&bus->dev);
+}
+EXPORT_SYMBOL(pcibus_to_node);
+
+#endif
+
 #ifdef CONFIG_ACPI
 /* Root bridge scanning */
 struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 3f57233..a347a55 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -53,6 +53,7 @@
 #include <asm/cpufeature.h>
 #include <asm/cpu_ops.h>
 #include <asm/kasan.h>
+#include <asm/numa.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/smp_plat.h>
@@ -375,6 +376,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;
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index b1adc51..46c45c8 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -45,6 +45,7 @@
 #include <asm/cputype.h>
 #include <asm/cpu_ops.h>
 #include <asm/mmu_context.h>
+#include <asm/numa.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/processor.h>
@@ -125,6 +126,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);
 }
 
 /*
@@ -518,6 +520,8 @@ static void __init of_parse_and_init_cpus(void)
 
 		pr_debug("cpu logical map 0x%llx\n", hwid);
 		cpu_logical_map(cpu_count) = hwid;
+
+		early_map_cpu_to_node(cpu_count, of_node_to_nid(dn));
 next:
 		cpu_count++;
 	}
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index 57f57fd..54bb209 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -4,6 +4,7 @@ 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
 
 obj-$(CONFIG_KASAN)		+= kasan_init.o
 KASAN_SANITIZE_kasan_init.o	:= n
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index ee06165..5680c84 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -37,6 +37,7 @@
 
 #include <asm/fixmap.h>
 #include <asm/memory.h>
+#include <asm/numa.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/sizes.h>
@@ -77,6 +78,21 @@ static phys_addr_t __init 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]  = {0};
+
+	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;
@@ -117,6 +133,8 @@ 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)
 {
@@ -133,10 +151,15 @@ static void __init arm64_memory_present(void)
 static void __init 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
 
@@ -182,7 +205,6 @@ void __init arm64_memblock_init(void)
 	dma_contiguous_reserve(arm64_dma_phys_limit);
 
 	memblock_allow_resize();
-	memblock_dump_all();
 }
 
 void __init bootmem_init(void)
@@ -194,6 +216,9 @@ void __init bootmem_init(void)
 
 	early_memtest(min << PAGE_SHIFT, max << PAGE_SHIFT);
 
+	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.
@@ -204,7 +229,6 @@ void __init bootmem_init(void)
 	zone_sizes_init(min, max);
 
 	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
-	max_pfn = max_low_pfn = max;
 }
 
 #ifndef CONFIG_SPARSEMEM_VMEMMAP
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 58faeaa..44e3854 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -463,6 +463,7 @@ void __init paging_init(void)
 	zero_page = early_alloc(PAGE_SIZE);
 
 	bootmem_init();
+	memblock_dump_all();
 
 	empty_zero_page = virt_to_page(zero_page);
 
diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
new file mode 100644
index 0000000..604e886
--- /dev/null
+++ b/arch/arm64/mm/numa.c
@@ -0,0 +1,403 @@
+/*
+ * NUMA support, based on the x86 implementation.
+ *
+ * Copyright (C) 2015 Cavium Inc.
+ * Author: Ganapatrao Kulkarni <gkulkarni@cavium.com>
+ *
+ * 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/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
+EXPORT_SYMBOL(node_data);
+nodemask_t numa_nodes_parsed __initdata;
+static int cpu_to_node_map[NR_CPUS] = { [0 ... NR_CPUS-1] = NUMA_NO_NODE };
+
+static int numa_off;
+static int numa_distance_cnt;
+static u8 *numa_distance;
+
+static __init int numa_parse_early_param(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_parse_early_param);
+
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+EXPORT_SYMBOL(node_to_cpumask_map);
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+
+/*
+ * Returns a pointer to the bitmask of CPUs on Node 'node'.
+ */
+const struct cpumask *cpumask_of_node(int node)
+{
+	if (WARN_ON(node >= nr_node_ids))
+		return cpu_none_mask;
+
+	if (WARN_ON(node_to_cpumask_map[node] == NULL))
+		return cpu_online_mask;
+
+	return node_to_cpumask_map[node];
+}
+EXPORT_SYMBOL(cpumask_of_node);
+
+#endif
+
+static void map_cpu_to_node(unsigned int cpu, int nid)
+{
+	set_cpu_numa_node(cpu, nid);
+	if (nid >= 0)
+		cpumask_set_cpu(cpu, node_to_cpumask_map[nid]);
+}
+
+static void unmap_cpu_to_node(unsigned int cpu)
+{
+	int nid = cpu_to_node(cpu);
+
+	if (nid >= 0)
+		cpumask_clear_cpu(cpu, node_to_cpumask_map[nid]);
+	set_cpu_numa_node(cpu, NUMA_NO_NODE);
+}
+
+void numa_clear_node(unsigned int cpu)
+{
+	unmap_cpu_to_node(cpu);
+}
+
+/*
+ * 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.)
+ */
+static void __init setup_node_to_cpumask_map(void)
+{
+	unsigned int cpu;
+	int node;
+
+	/* setup nr_node_ids if not done yet */
+	if (nr_node_ids == MAX_NUMNODES)
+		setup_nr_node_ids();
+
+	/* allocate and clear the mapping */
+	for (node = 0; node < nr_node_ids; node++) {
+		alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
+		cpumask_clear(node_to_cpumask_map[node]);
+	}
+
+	for_each_possible_cpu(cpu)
+		set_cpu_numa_node(cpu, NUMA_NO_NODE);
+
+	/* cpumask_of_node() will now work */
+	pr_debug("NUMA: Node to cpumask map for %d nodes\n", nr_node_ids);
+}
+
+/*
+ *  Set the cpu to node and mem mapping
+ */
+void numa_store_cpu_info(unsigned int cpu)
+{
+	map_cpu_to_node(cpu, numa_off ? 0 : cpu_to_node_map[cpu]);
+}
+
+void __init early_map_cpu_to_node(unsigned int cpu, int nid)
+{
+	/* fallback to node 0 */
+	if (nid < 0 || nid >= MAX_NUMNODES)
+		nid = 0;
+
+	cpu_to_node_map[cpu] = nid;
+}
+
+/**
+ * numa_add_memblk - Set node id to memblk
+ * @nid: NUMA node ID of the new memblk
+ * @start: Start address of the new memblk
+ * @size:  Size of the new memblk
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+int __init numa_add_memblk(int nid, u64 start, u64 size)
+{
+	int ret;
+
+	ret = memblock_set_node(start, size, &memblock.memory, nid);
+	if (ret < 0) {
+		pr_err("NUMA: memblock [0x%llx - 0x%llx] failed to add on node %d\n",
+			start, (start + size - 1), nid);
+		return ret;
+	}
+
+	node_set(nid, numa_nodes_parsed);
+	pr_info("NUMA: Adding memblock [0x%llx - 0x%llx] on node %d\n",
+			start, (start + size - 1), nid);
+	return ret;
+}
+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_pfn, u64 end_pfn)
+{
+	const size_t nd_size = roundup(sizeof(pg_data_t), SMP_CACHE_BYTES);
+	u64 nd_pa;
+	void *nd;
+	int tnid;
+
+	pr_info("NUMA: Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
+			nid, start_pfn << PAGE_SHIFT,
+			(end_pfn << PAGE_SHIFT) - 1);
+
+	nd_pa = memblock_alloc_try_nid(nd_size, SMP_CACHE_BYTES, nid);
+	nd = __va(nd_pa);
+
+	/* report and initialize */
+	pr_info("NUMA: 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("NUMA: 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_pfn;
+	NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
+}
+
+/**
+ * numa_free_distance
+ *
+ * The current table is freed.
+ */
+void __init numa_free_distance(void)
+{
+	size_t size;
+
+	if (!numa_distance)
+		return;
+
+	size = numa_distance_cnt * numa_distance_cnt *
+		sizeof(numa_distance[0]);
+
+	memblock_free(__pa(numa_distance), size);
+	numa_distance_cnt = 0;
+	numa_distance = NULL;
+}
+
+/**
+ *
+ * Create a new NUMA distance table.
+ *
+ */
+static int __init numa_alloc_distance(void)
+{
+	size_t size;
+	u64 phys;
+	int i, j;
+
+	size = nr_node_ids * nr_node_ids * sizeof(numa_distance[0]);
+	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
+				      size, PAGE_SIZE);
+	if (WARN_ON(!phys))
+		return -ENOMEM;
+
+	memblock_reserve(phys, size);
+
+	numa_distance = __va(phys);
+	numa_distance_cnt = nr_node_ids;
+
+	/* fill with the default distances */
+	for (i = 0; i < numa_distance_cnt; i++)
+		for (j = 0; j < numa_distance_cnt; j++)
+			numa_distance[i * numa_distance_cnt + j] = i == j ?
+				LOCAL_DISTANCE : REMOTE_DISTANCE;
+
+	pr_debug("NUMA: Initialized distance table, cnt=%d\n",
+			numa_distance_cnt);
+
+	return 0;
+}
+
+/**
+ * numa_set_distance - Set inter node NUMA distance from node to node.
+ * @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, a warning is printed.
+ *
+ * If @from or @to is higher than the highest known node or lower than zero
+ * or @distance doesn't make sense, the call is ignored.
+ *
+ */
+void __init numa_set_distance(int from, int to, int distance)
+{
+	if (!numa_distance) {
+		pr_warn_once("NUMA: Warning: distance table not allocated yet\n");
+		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);
+
+/**
+ * Return NUMA distance @from to @to
+ */
+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_nodes(void)
+{
+	int nid;
+	struct memblock_region *mblk;
+
+	/* Check that valid nid is set to memblks */
+	for_each_memblock(memory, mblk)
+		if (mblk->nid == NUMA_NO_NODE || mblk->nid >= MAX_NUMNODES) {
+			pr_warn("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
+				mblk->nid, mblk->base,
+				mblk->base + mblk->size - 1);
+			return -EINVAL;
+		}
+
+	/* Finally register nodes. */
+	for_each_node_mask(nid, numa_nodes_parsed) {
+		unsigned long start_pfn, end_pfn;
+
+		get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
+		setup_node_data(nid, start_pfn, end_pfn);
+		node_set_online(nid);
+	}
+
+	/* Setup online nodes to actual nodes*/
+	node_possible_map = numa_nodes_parsed;
+
+	return 0;
+}
+
+static int __init numa_init(int (*init_func)(void))
+{
+	int ret;
+
+	nodes_clear(numa_nodes_parsed);
+	nodes_clear(node_possible_map);
+	nodes_clear(node_online_map);
+	numa_free_distance();
+
+	ret = numa_alloc_distance();
+	if (ret < 0)
+		return ret;
+
+	ret = init_func();
+	if (ret < 0)
+		return ret;
+
+	if (nodes_empty(numa_nodes_parsed))
+		return -EINVAL;
+
+	ret = numa_register_nodes();
+	if (ret < 0)
+		return ret;
+
+	setup_node_to_cpumask_map();
+
+	/* init boot processor */
+	cpu_to_node_map[0] = 0;
+	map_cpu_to_node(0, 0);
+
+	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 (node 0) and add memory blocks that cover all
+ * allowed memory. It is unlikely that this function fails.
+ */
+static int __init dummy_numa_init(void)
+{
+	int ret;
+	struct memblock_region *mblk;
+
+	pr_info("%s\n", "No NUMA configuration found");
+	pr_info("NUMA: Faking a node at [mem %#018Lx-%#018Lx]\n",
+	       0LLU, PFN_PHYS(max_pfn) - 1);
+
+	for_each_memblock(memory, mblk) {
+		ret = numa_add_memblk(0, mblk->base, mblk->size);
+		if (!ret)
+			continue;
+
+		pr_err("NUMA init failed\n");
+		return ret;
+	}
+
+	numa_off = 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.
+ */
+void __init arm64_numa_init(void)
+{
+	if (!numa_off) {
+		if (!numa_init(of_numa_init))
+			return;
+	}
+
+	numa_init(dummy_numa_init);
+}
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v11 10/10] arm64, mm, numa: Add NUMA balancing support for arm64.
  2016-02-20  1:13 [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms David Daney
                   ` (8 preceding siblings ...)
  2016-02-20  1:13 ` [PATCH v11 09/10] arm64, numa: Add NUMA support for arm64 platforms David Daney
@ 2016-02-20  1:13 ` David Daney
  2016-02-20  8:20 ` [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms Ard Biesheuvel
  10 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2016-02-20  1:13 UTC (permalink / raw)
  To: Will Deacon, linux-arm-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter
  Cc: linux-kernel, David Daney

From: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>

Enable NUMA balancing for arm64 platforms.
Add pte, pmd protnone helpers for use by automatic NUMA balancing.

Reviewed-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
Signed-off-by: David Daney <david.daney@cavium.com>
---
 arch/arm64/Kconfig               |  1 +
 arch/arm64/include/asm/pgtable.h | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 9f0972a..6e22503 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -11,6 +11,7 @@ config ARM64
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_USE_CMPXCHG_LOCKREF
 	select ARCH_SUPPORTS_ATOMIC_RMW
+	select ARCH_SUPPORTS_NUMA_BALANCING
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
 	select ARCH_WANT_FRAME_POINTERS
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index bf464de..5af9db2 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -346,6 +346,21 @@ static inline pgprot_t mk_sect_prot(pgprot_t prot)
 	return __pgprot(pgprot_val(prot) & ~PTE_TABLE_BIT);
 }
 
+#ifdef CONFIG_NUMA_BALANCING
+/*
+ * See the comment in include/asm-generic/pgtable.h
+ */
+static inline int pte_protnone(pte_t pte)
+{
+	return (pte_val(pte) & (PTE_VALID | PTE_PROT_NONE)) == PTE_PROT_NONE;
+}
+
+static inline int pmd_protnone(pmd_t pmd)
+{
+	return pte_protnone(pmd_pte(pmd));
+}
+#endif
+
 /*
  * THP definitions.
  */
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms
  2016-02-20  1:13 [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms David Daney
                   ` (9 preceding siblings ...)
  2016-02-20  1:13 ` [PATCH v11 10/10] arm64, mm, numa: Add NUMA balancing support for arm64 David Daney
@ 2016-02-20  8:20 ` Ard Biesheuvel
  2016-02-20 10:39   ` Robert Richter
  10 siblings, 1 reply; 22+ messages in thread
From: Ard Biesheuvel @ 2016-02-20  8:20 UTC (permalink / raw)
  To: David Daney, Grant Likely, Rob Herring
  Cc: Will Deacon, linux-arm-kernel, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, devicetree, Frank Rowand,
	Catalin Marinas, Matt Fleming, linux-efi, Ganapatrao Kulkarni,
	Robert Richter, linux-kernel, David Daney

Hello David,

On 20 February 2016 at 02:13, David Daney <ddaney.cavm@gmail.com> wrote:
> From: David Daney <david.daney@cavium.com>
>
> v11:
>         - Dropped cleanup patches for other architectures, they will be
>           submitted as a separate set after more testing.
>
>         - Added patch set from Ard Biesheuvel that are needed to make
>           the whole thing actually work.  Previously this was a
>           separate set.
>

This series is out of date, unfortunately. The EFI init code is now
(as of v4.5-rc1) shared between ARM and arm64, which means that any
changes you make must be made on both sides. This applies to the split
between parsing the EFI dt nodes and performing the actual EFI init,
but also to the early_init_dt_add_memory_arch() changes. I am happy to
have a go at this, but first I need a clear statement from whoever
maintains that area that keeping memory nodes *just* for the
annotations (and otherwise ignore them) is the way forward (Rob?
Grant?)

Also, please drop the 6th patch. As i replied to Robert when he
reposted these patches, we need to honor the /reserved-memory node
rather than remove it. I will follow up with an updated
/reserved-memory node validation patch for the EFI stub once these
changes are in.


>         - Kconfig and other fixes and simplifications as suggested by Rob Herring.
>
>         - Rearranged, refactored and reordered so that we don't patch
>           new files multiple times.
>
>         - Summary:
>
>                 o 6 patches from Ard Biesheuvel to allow use of
>                   "memory" nodes with efi stub.
>
>                 o 2 patches to document and add of_numa.c
>
>                 o 1 patch to add arm64 NUMA support.
>
>                 o 1 patch to add NUMA balancing support for arm64.
>
> v10:
>         - Incorporated review comments from Rob Herring.
>         - Moved numa binding and implementation to devicetree core.
>         - Added cleanup patch to remove redundant NODE_DATA macro from asm header files
>         - Include numa balancing support for arm64 patch in this series.
>         - Fix tile build issue reported by the kbuild robot(patch 7)
>
> v9:     - Added cleanup patch to reuse and avoid redefinition of cpumask_of_pcibus
>           as suggested from Will Deacon and Bjorn Helgaas.
>           - Including patch to Make pci-host-generic driver numa aware.
>           - Incorporated comment from Shannon Zhao.
>
> v8:
>         - Incorporated review comments of Mark Rutland and Will Deacon.
>         - Added pci helper function and macro for numa.
>
> v7:
>         - managing numa memory mapping using memblock.
>         - Incorporated review comments of Mark Rutland.
>
> v6:
>         - defined and implemented the numa dt binding using
>         node property proximity and device node distance-map.
>         - renamed dt_numa to of_numa
>
> 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 and without NUMA with dt
>         (both with and without NUMA bindings) on thunderx single
>         socket and dual socket boards.
>
>
> Ard Biesheuvel (6):
>   of/fdt: make generic early_init_dt_add_memory_arch() a weak alias
>   arm64: override generic version of early_init_dt_add_memory_arch()
>   efi: move FDT handling to separate object file
>   arm64/efi: move EFI /chosen node parsing before early FDT processing
>   arm64/efi: ignore DT memory nodes instead of removing them
>   arm64/efi: ignore DT memreserve entries instead of removing them
>
> Ganapatrao Kulkarni (4):
>   Documentation, dt, numa: dt bindings for NUMA.
>   dt, numa: Add NUMA dt binding implementation.
>   arm64, numa: Add NUMA support for arm64 platforms.
>   arm64, mm, numa: Add NUMA balancing support for arm64.
>
>  Documentation/devicetree/bindings/numa.txt | 272 +++++++++++++++++++
>  arch/arm64/Kconfig                         |  27 ++
>  arch/arm64/include/asm/efi.h               |   2 +
>  arch/arm64/include/asm/mmzone.h            |  12 +
>  arch/arm64/include/asm/numa.h              |  45 ++++
>  arch/arm64/include/asm/pgtable.h           |  15 ++
>  arch/arm64/include/asm/topology.h          |  10 +
>  arch/arm64/kernel/pci.c                    |  10 +
>  arch/arm64/kernel/setup.c                  |   7 +
>  arch/arm64/kernel/smp.c                    |   4 +
>  arch/arm64/mm/Makefile                     |   1 +
>  arch/arm64/mm/init.c                       |  46 +++-
>  arch/arm64/mm/mmu.c                        |   1 +
>  arch/arm64/mm/numa.c                       | 403 +++++++++++++++++++++++++++++
>  drivers/firmware/efi/Makefile              |   1 +
>  drivers/firmware/efi/arm-init.c            |  36 ++-
>  drivers/firmware/efi/efi-fdt.c             |  73 ++++++
>  drivers/firmware/efi/efi.c                 |  84 ------
>  drivers/firmware/efi/libstub/fdt.c         |  33 +--
>  drivers/of/Kconfig                         |   3 +
>  drivers/of/Makefile                        |   1 +
>  drivers/of/fdt.c                           |   7 +-
>  drivers/of/of_numa.c                       | 211 +++++++++++++++
>  include/linux/efi.h                        |   2 +-
>  include/linux/of.h                         |   9 +
>  include/linux/of_fdt.h                     |   1 +
>  26 files changed, 1178 insertions(+), 138 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/numa.txt
>  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
>  create mode 100644 drivers/firmware/efi/efi-fdt.c
>  create mode 100644 drivers/of/of_numa.c
>
> --
> 1.8.3.1
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms
  2016-02-20  8:20 ` [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms Ard Biesheuvel
@ 2016-02-20 10:39   ` Robert Richter
  2016-02-20 10:44     ` Ard Biesheuvel
  0 siblings, 1 reply; 22+ messages in thread
From: Robert Richter @ 2016-02-20 10:39 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: David Daney, Grant Likely, Rob Herring, Will Deacon,
	linux-arm-kernel, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, devicetree, Frank Rowand, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, linux-kernel,
	David Daney

On 20.02.16 09:20:05, Ard Biesheuvel wrote:
> On 20 February 2016 at 02:13, David Daney <ddaney.cavm@gmail.com> wrote:
> > From: David Daney <david.daney@cavium.com>
> >
> > v11:
> >         - Dropped cleanup patches for other architectures, they will be
> >           submitted as a separate set after more testing.
> >
> >         - Added patch set from Ard Biesheuvel that are needed to make
> >           the whole thing actually work.  Previously this was a
> >           separate set.
> >
> 
> This series is out of date, unfortunately. The EFI init code is now
> (as of v4.5-rc1) shared between ARM and arm64, which means that any
> changes you make must be made on both sides. This applies to the split
> between parsing the EFI dt nodes and performing the actual EFI init,
> but also to the early_init_dt_add_memory_arch() changes. I am happy to
> have a go at this, but first I need a clear statement from whoever
> maintains that area that keeping memory nodes *just* for the
> annotations (and otherwise ignore them) is the way forward (Rob?
> Grant?)

Wasn't there the approach to check for consistency between efi tables
and devicetree? Thus, DT is actually not ignored but rather checked if
it is in sync with efi tables.

-Robert

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms
  2016-02-20 10:39   ` Robert Richter
@ 2016-02-20 10:44     ` Ard Biesheuvel
  0 siblings, 0 replies; 22+ messages in thread
From: Ard Biesheuvel @ 2016-02-20 10:44 UTC (permalink / raw)
  To: Robert Richter
  Cc: David Daney, Grant Likely, Rob Herring, Will Deacon,
	linux-arm-kernel, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, devicetree, Frank Rowand, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, linux-kernel,
	David Daney

On 20 February 2016 at 11:39, Robert Richter
<robert.richter@caviumnetworks.com> wrote:
> On 20.02.16 09:20:05, Ard Biesheuvel wrote:
>> On 20 February 2016 at 02:13, David Daney <ddaney.cavm@gmail.com> wrote:
>> > From: David Daney <david.daney@cavium.com>
>> >
>> > v11:
>> >         - Dropped cleanup patches for other architectures, they will be
>> >           submitted as a separate set after more testing.
>> >
>> >         - Added patch set from Ard Biesheuvel that are needed to make
>> >           the whole thing actually work.  Previously this was a
>> >           separate set.
>> >
>>
>> This series is out of date, unfortunately. The EFI init code is now
>> (as of v4.5-rc1) shared between ARM and arm64, which means that any
>> changes you make must be made on both sides. This applies to the split
>> between parsing the EFI dt nodes and performing the actual EFI init,
>> but also to the early_init_dt_add_memory_arch() changes. I am happy to
>> have a go at this, but first I need a clear statement from whoever
>> maintains that area that keeping memory nodes *just* for the
>> annotations (and otherwise ignore them) is the way forward (Rob?
>> Grant?)
>
> Wasn't there the approach to check for consistency between efi tables
> and devicetree? Thus, DT is actually not ignored but rather checked if
> it is in sync with efi tables.
>

I proposed such an approach for the /reserved-memory node, but not for
the memory nodes themselves.

But thinking about this a bit more, I think we can replace the whole 6
piece series with the following patch
(apologies for the mangled whitespace). The reason is that, if we
decide to keep the memory nodes, we might just as well parse them as
usual (and use generic code to spot any problems etc), and just
discard the regions it describes. This completely solves the ARM vs
arm64 problem.


---------8<--------------
Subject: [PATCH] efi: ARM/arm64: ignore DT memory nodes instead of removing
 them

There are two problems with the UEFI stub DT memory node removal
routine:
- it deletes nodes as it traverses the tree, which happens to work
  but is not supported, as deletion invalidates the node iterator;
- deleting memory nodes entirely may discard annotations in the form
  of additional properties on the nodes.

Since the discovery of DT memory nodes occurs strictly before the
UEFI init sequence, we can simply clear the memblock memory table
before parsing the UEFI memory map. This way, it is no longer
necessary to remove the nodes, so we can remove that logic from the
stub as well.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
 drivers/firmware/efi/arm-init.c    |  8 +++++++
 drivers/firmware/efi/libstub/fdt.c | 24 +-------------------
 2 files changed, 9 insertions(+), 23 deletions(-)

diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
index 9e15d571b53c..40c9d8596d69 100644
--- a/drivers/firmware/efi/arm-init.c
+++ b/drivers/firmware/efi/arm-init.c
@@ -143,6 +143,14 @@ static __init void reserve_regions(void)
  if (efi_enabled(EFI_DBG))
  pr_info("Processing EFI memory map:\n");

+ /*
+ * Discard memblocks discovered so far: if there are any at this
+ * point, they originate from memory nodes in the DT, and UEFI
+ * uses its own memory map instead.
+ */
+ memblock_dump_all();
+ memblock_remove(0, ULLONG_MAX);
+
  for_each_efi_memory_desc(&memmap, md) {
  paddr = md->phys_addr;
  npages = md->num_pages;
diff --git a/drivers/firmware/efi/libstub/fdt.c
b/drivers/firmware/efi/libstub/fdt.c
index 6dba78aef337..e58abfa953cc 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -24,7 +24,7 @@ efi_status_t update_fdt(efi_system_table_t
*sys_table, void *orig_fdt,
  unsigned long map_size, unsigned long desc_size,
  u32 desc_ver)
 {
- int node, prev, num_rsv;
+ int node, num_rsv;
  int status;
  u32 fdt_val32;
  u64 fdt_val64;
@@ -54,28 +54,6 @@
  goto fdt_set_fail;

  /*
- * Delete any memory nodes present. We must delete nodes which
- * early_init_dt_scan_memory may try to use.
- */
- prev = 0;
- for (;;) {
- const char *type;
- int len;
-
- node = fdt_next_node(fdt, prev, NULL);
- if (node < 0)
- break;
-
- type = fdt_getprop(fdt, node, "device_type", &len);
- if (type && strncmp(type, "memory", len) == 0) {
- fdt_del_node(fdt, node);
- continue;
- }
-
- prev = node;
- }
-
- /*
  * Delete all memory reserve map entries. When booting via UEFI,
  * kernel will use the UEFI memory map to find reserved regions.
  */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation.
  2016-02-20  1:13 ` [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation David Daney
@ 2016-02-23 19:36   ` Rob Herring
  2016-02-26  1:26     ` David Daney
  0 siblings, 1 reply; 22+ messages in thread
From: Rob Herring @ 2016-02-23 19:36 UTC (permalink / raw)
  To: David Daney
  Cc: Will Deacon, linux-arm-kernel, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, devicetree, Ard Biesheuvel,
	Frank Rowand, Grant Likely, Catalin Marinas, Matt Fleming,
	linux-efi, Ganapatrao Kulkarni, Robert Richter, linux-kernel,
	David Daney

On Fri, Feb 19, 2016 at 05:13:17PM -0800, David Daney wrote:
> From: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
> 
> ADD device tree node parsing for NUMA topology using device
> "numa-node-id" property distance-map.

I still want an adequate explanation why NUMA setup cannot be done with 
an unflattened tree. PowerPC manages to do that and should have a 
similar init flow being memblock based, so I would expect arm64 can too.

Rob

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation.
  2016-02-23 19:36   ` Rob Herring
@ 2016-02-26  1:26     ` David Daney
  2016-02-26 18:27       ` Will Deacon
  2016-03-01 16:47       ` Rob Herring
  0 siblings, 2 replies; 22+ messages in thread
From: David Daney @ 2016-02-26  1:26 UTC (permalink / raw)
  To: Rob Herring
  Cc: David Daney, Will Deacon, linux-arm-kernel, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter,
	linux-kernel, David Daney

On 02/23/2016 11:36 AM, Rob Herring wrote:
> On Fri, Feb 19, 2016 at 05:13:17PM -0800, David Daney wrote:
>> From: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
>>
>> ADD device tree node parsing for NUMA topology using device
>> "numa-node-id" property distance-map.
>
> I still want an adequate explanation why NUMA setup cannot be done with
> an unflattened tree. PowerPC manages to do that and should have a
> similar init flow being memblock based, so I would expect arm64 can too.

Many things could be done.  Really, we want to know what *should* be done.

In the context of the current arm64 memory initialization we (more or 
less) do:

  1) early_init_fdt_scan_reserved_mem();
  2) memory_present()
  3) sparse_init()
  4) other things
  5) unflatten_device_tree()

We are already reading information out of the FDT at #1.

This patch set adds a step between 1 and 2 where we read NUMA 
information out of the FDT.

Hypothetically, it might be possible to rewrite the arm64 setup code so 
that the ordering was different, and the NUMA setup was done on the 
unflattened tree, but that would certainly be a much more invasive patch.

If the arm64 maintainers would like a rewrite of:

   arch/arm64/kernel/setup.c
   arch/arm64/mm/init.c
   arch/arm64/mm/mm/mmu.c
   .
   .
   .

we can discuss doing NUMA setup with the unflattened tree.  With the 
current memory initialization code, I think it makes more sense to parse 
the NUMA information out of the flattened form.

David Daney

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation.
  2016-02-26  1:26     ` David Daney
@ 2016-02-26 18:27       ` Will Deacon
  2016-03-01 16:56         ` Rob Herring
  2016-03-01 16:47       ` Rob Herring
  1 sibling, 1 reply; 22+ messages in thread
From: Will Deacon @ 2016-02-26 18:27 UTC (permalink / raw)
  To: David Daney
  Cc: Rob Herring, David Daney, linux-arm-kernel, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter,
	linux-kernel, David Daney

On Thu, Feb 25, 2016 at 05:26:34PM -0800, David Daney wrote:
> On 02/23/2016 11:36 AM, Rob Herring wrote:
> >On Fri, Feb 19, 2016 at 05:13:17PM -0800, David Daney wrote:
> >>From: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
> >>
> >>ADD device tree node parsing for NUMA topology using device
> >>"numa-node-id" property distance-map.
> >
> >I still want an adequate explanation why NUMA setup cannot be done with
> >an unflattened tree. PowerPC manages to do that and should have a
> >similar init flow being memblock based, so I would expect arm64 can too.
> 
> Many things could be done.  Really, we want to know what *should* be done.
> 
> In the context of the current arm64 memory initialization we (more or less)
> do:
> 
>  1) early_init_fdt_scan_reserved_mem();
>  2) memory_present()
>  3) sparse_init()
>  4) other things
>  5) unflatten_device_tree()
> 
> We are already reading information out of the FDT at #1.
> 
> This patch set adds a step between 1 and 2 where we read NUMA information
> out of the FDT.
> 
> Hypothetically, it might be possible to rewrite the arm64 setup code so that
> the ordering was different, and the NUMA setup was done on the unflattened
> tree, but that would certainly be a much more invasive patch.

I just looked at what PPC get up to, and there's really not an obvious
way we could do that on arm64. They run whole swathes of the kernel
with the MMU off directly from head.S to parse the flattened tree and
get memblock up really early. On arm64, the head.S environment is
considerably more hostile, and I don't think we'd want to do that (not
to mention the interaction with EFI stub).

So I'm perfectly happy for this to operate on the flattened tree.

Will

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation.
  2016-02-26  1:26     ` David Daney
  2016-02-26 18:27       ` Will Deacon
@ 2016-03-01 16:47       ` Rob Herring
  2016-03-01 16:57         ` David Daney
  1 sibling, 1 reply; 22+ messages in thread
From: Rob Herring @ 2016-03-01 16:47 UTC (permalink / raw)
  To: David Daney
  Cc: David Daney, Will Deacon, linux-arm-kernel, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter,
	linux-kernel, David Daney

On Thu, Feb 25, 2016 at 7:26 PM, David Daney <ddaney@caviumnetworks.com> wrote:
> On 02/23/2016 11:36 AM, Rob Herring wrote:
>>
>> On Fri, Feb 19, 2016 at 05:13:17PM -0800, David Daney wrote:
>>>
>>> From: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
>>>
>>> ADD device tree node parsing for NUMA topology using device
>>> "numa-node-id" property distance-map.
>>
>>
>> I still want an adequate explanation why NUMA setup cannot be done with
>> an unflattened tree. PowerPC manages to do that and should have a
>> similar init flow being memblock based, so I would expect arm64 can too.
>
>
> Many things could be done.  Really, we want to know what *should* be done.
>
> In the context of the current arm64 memory initialization we (more or less)
> do:
>
>  1) early_init_fdt_scan_reserved_mem();
>  2) memory_present()
>  3) sparse_init()
>  4) other things
>  5) unflatten_device_tree()
>
> We are already reading information out of the FDT at #1.
>
> This patch set adds a step between 1 and 2 where we read NUMA information
> out of the FDT.

The dependency on unflattening is that memblock is up and we can
allocate a chunk from it. Isn't that dependency met by step 1 or is
there a dependency on sparsemem (or something else)?

Rob

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation.
  2016-02-26 18:27       ` Will Deacon
@ 2016-03-01 16:56         ` Rob Herring
  0 siblings, 0 replies; 22+ messages in thread
From: Rob Herring @ 2016-03-01 16:56 UTC (permalink / raw)
  To: Will Deacon
  Cc: David Daney, David Daney, linux-arm-kernel, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter,
	linux-kernel, David Daney

On Fri, Feb 26, 2016 at 12:27 PM, Will Deacon <will.deacon@arm.com> wrote:
> On Thu, Feb 25, 2016 at 05:26:34PM -0800, David Daney wrote:
>> On 02/23/2016 11:36 AM, Rob Herring wrote:
>> >On Fri, Feb 19, 2016 at 05:13:17PM -0800, David Daney wrote:
>> >>From: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
>> >>
>> >>ADD device tree node parsing for NUMA topology using device
>> >>"numa-node-id" property distance-map.
>> >
>> >I still want an adequate explanation why NUMA setup cannot be done with
>> >an unflattened tree. PowerPC manages to do that and should have a
>> >similar init flow being memblock based, so I would expect arm64 can too.
>>
>> Many things could be done.  Really, we want to know what *should* be done.
>>
>> In the context of the current arm64 memory initialization we (more or less)
>> do:
>>
>>  1) early_init_fdt_scan_reserved_mem();
>>  2) memory_present()
>>  3) sparse_init()
>>  4) other things
>>  5) unflatten_device_tree()
>>
>> We are already reading information out of the FDT at #1.
>>
>> This patch set adds a step between 1 and 2 where we read NUMA information
>> out of the FDT.
>>
>> Hypothetically, it might be possible to rewrite the arm64 setup code so that
>> the ordering was different, and the NUMA setup was done on the unflattened
>> tree, but that would certainly be a much more invasive patch.
>
> I just looked at what PPC get up to, and there's really not an obvious
> way we could do that on arm64. They run whole swathes of the kernel
> with the MMU off directly from head.S to parse the flattened tree and
> get memblock up really early. On arm64, the head.S environment is
> considerably more hostile, and I don't think we'd want to do that (not
> to mention the interaction with EFI stub).
>
> So I'm perfectly happy for this to operate on the flattened tree.

Of course you are. The code is not in your tree. I'm all for keeping
things out of /arch, but just want to understand what are the
dependencies which aren't clearly spelled out here.

Rob

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation.
  2016-03-01 16:47       ` Rob Herring
@ 2016-03-01 16:57         ` David Daney
  2016-03-01 17:43           ` Rob Herring
  0 siblings, 1 reply; 22+ messages in thread
From: David Daney @ 2016-03-01 16:57 UTC (permalink / raw)
  To: Rob Herring
  Cc: David Daney, Will Deacon, linux-arm-kernel, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter,
	linux-kernel, David Daney

On 03/01/2016 08:47 AM, Rob Herring wrote:
> On Thu, Feb 25, 2016 at 7:26 PM, David Daney <ddaney@caviumnetworks.com> wrote:
>> On 02/23/2016 11:36 AM, Rob Herring wrote:
>>>
>>> On Fri, Feb 19, 2016 at 05:13:17PM -0800, David Daney wrote:
>>>>
>>>> From: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
>>>>
>>>> ADD device tree node parsing for NUMA topology using device
>>>> "numa-node-id" property distance-map.
>>>
>>>
>>> I still want an adequate explanation why NUMA setup cannot be done with
>>> an unflattened tree. PowerPC manages to do that and should have a
>>> similar init flow being memblock based, so I would expect arm64 can too.
>>
>>
>> Many things could be done.  Really, we want to know what *should* be done.
>>
>> In the context of the current arm64 memory initialization we (more or less)
>> do:
>>
>>   1) early_init_fdt_scan_reserved_mem();
>>   2) memory_present()
>>   3) sparse_init()
>>   4) other things
>>   5) unflatten_device_tree()
>>
>> We are already reading information out of the FDT at #1.
>>
>> This patch set adds a step between 1 and 2 where we read NUMA information
>> out of the FDT.
>
> The dependency on unflattening is that memblock is up and we can
> allocate a chunk from it. Isn't that dependency met by step 1

No.

> or is
> there a dependency on sparsemem (or something else)?

Will Deacon talked about this over here:

https://lkml.org/lkml/2016/2/26/782

I am happy to modify the patch set, but I don't want to get stuck as an 
intermediary between two opposing blocs.

David Daney

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation.
  2016-03-01 16:57         ` David Daney
@ 2016-03-01 17:43           ` Rob Herring
  2016-03-01 17:58             ` David Daney
  0 siblings, 1 reply; 22+ messages in thread
From: Rob Herring @ 2016-03-01 17:43 UTC (permalink / raw)
  To: David Daney
  Cc: David Daney, Will Deacon, linux-arm-kernel, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, devicetree,
	Ard Biesheuvel, Frank Rowand, Grant Likely, Catalin Marinas,
	Matt Fleming, linux-efi, Ganapatrao Kulkarni, Robert Richter,
	linux-kernel, David Daney

On Tue, Mar 1, 2016 at 10:57 AM, David Daney <ddaney@caviumnetworks.com> wrote:
> On 03/01/2016 08:47 AM, Rob Herring wrote:
>>
>> On Thu, Feb 25, 2016 at 7:26 PM, David Daney <ddaney@caviumnetworks.com>
>> wrote:
>>>
>>> On 02/23/2016 11:36 AM, Rob Herring wrote:
>>>>
>>>>
>>>> On Fri, Feb 19, 2016 at 05:13:17PM -0800, David Daney wrote:
>>>>>
>>>>>
>>>>> From: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
>>>>>
>>>>> ADD device tree node parsing for NUMA topology using device
>>>>> "numa-node-id" property distance-map.
>>>>
>>>>
>>>>
>>>> I still want an adequate explanation why NUMA setup cannot be done with
>>>> an unflattened tree. PowerPC manages to do that and should have a
>>>> similar init flow being memblock based, so I would expect arm64 can too.
>>>
>>>
>>>
>>> Many things could be done.  Really, we want to know what *should* be
>>> done.
>>>
>>> In the context of the current arm64 memory initialization we (more or
>>> less)
>>> do:
>>>
>>>   1) early_init_fdt_scan_reserved_mem();
>>>   2) memory_present()
>>>   3) sparse_init()
>>>   4) other things
>>>   5) unflatten_device_tree()
>>>
>>> We are already reading information out of the FDT at #1.
>>>
>>> This patch set adds a step between 1 and 2 where we read NUMA information
>>> out of the FDT.
>>
>>
>> The dependency on unflattening is that memblock is up and we can
>> allocate a chunk from it. Isn't that dependency met by step 1
>
>
> No.

Really, because it seems that numa_alloc_distance is essentially doing
a memblock alloc and that happens before memory_present.

>
>> or is
>> there a dependency on sparsemem (or something else)?
>
>
> Will Deacon talked about this over here:
>
> https://lkml.org/lkml/2016/2/26/782

I'm not saying to move memblock setup earlier nor before the MMU is
on, so I don't see how Will's reply is relevant other than PPC doesn't
serve as an example. Maybe PPC should be ignored because I think maybe
NUMA is only used on non-FDT systems.

In any case, no one has clearly explained what the dependencies are or
what happens if you moved the unflattening up sooner. You told me what
the current order is which doesn't equate to dependencies. For
example, step 4 may or may not be a dependency of step 5. These are
the dependencies I'm aware of:

memblock dependent on DT memory and reserved-memory parsing
unflattening dependent on memblock_alloc()
sparsemem dependent on NUMA parsing and memblock

What am I missing from here?

Rob

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation.
  2016-03-01 17:43           ` Rob Herring
@ 2016-03-01 17:58             ` David Daney
  0 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2016-03-01 17:58 UTC (permalink / raw)
  To: Rob Herring, Will Deacon
  Cc: David Daney, linux-arm-kernel, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, devicetree, Ard Biesheuvel,
	Frank Rowand, Grant Likely, Catalin Marinas, Matt Fleming,
	linux-efi, Ganapatrao Kulkarni, Robert Richter, linux-kernel,
	David Daney

On 03/01/2016 09:43 AM, Rob Herring wrote:
> On Tue, Mar 1, 2016 at 10:57 AM, David Daney <ddaney@caviumnetworks.com> wrote:
>> On 03/01/2016 08:47 AM, Rob Herring wrote:
>>>
>>> On Thu, Feb 25, 2016 at 7:26 PM, David Daney <ddaney@caviumnetworks.com>
>>> wrote:
>>>>
>>>> On 02/23/2016 11:36 AM, Rob Herring wrote:
>>>>>
>>>>>
>>>>> On Fri, Feb 19, 2016 at 05:13:17PM -0800, David Daney wrote:
>>>>>>
>>>>>>
>>>>>> From: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
>>>>>>
>>>>>> ADD device tree node parsing for NUMA topology using device
>>>>>> "numa-node-id" property distance-map.
>>>>>
>>>>>
>>>>>
>>>>> I still want an adequate explanation why NUMA setup cannot be done with
>>>>> an unflattened tree. PowerPC manages to do that and should have a
>>>>> similar init flow being memblock based, so I would expect arm64 can too.
>>>>
>>>>
>>>>
>>>> Many things could be done.  Really, we want to know what *should* be
>>>> done.
>>>>
>>>> In the context of the current arm64 memory initialization we (more or
>>>> less)
>>>> do:
>>>>
>>>>    1) early_init_fdt_scan_reserved_mem();
>>>>    2) memory_present()
>>>>    3) sparse_init()
>>>>    4) other things
>>>>    5) unflatten_device_tree()
>>>>
>>>> We are already reading information out of the FDT at #1.
>>>>
>>>> This patch set adds a step between 1 and 2 where we read NUMA information
>>>> out of the FDT.
>>>
>>>
>>> The dependency on unflattening is that memblock is up and we can
>>> allocate a chunk from it. Isn't that dependency met by step 1
>>
>>
>> No.
>
> Really, because it seems that numa_alloc_distance is essentially doing
> a memblock alloc and that happens before memory_present.
>
>>
>>> or is
>>> there a dependency on sparsemem (or something else)?
>>
>>
>> Will Deacon talked about this over here:
>>
>> https://lkml.org/lkml/2016/2/26/782
>
> I'm not saying to move memblock setup earlier nor before the MMU is
> on, so I don't see how Will's reply is relevant other than PPC doesn't
> serve as an example. Maybe PPC should be ignored because I think maybe
> NUMA is only used on non-FDT systems.
>
> In any case, no one has clearly explained what the dependencies are or
> what happens if you moved the unflattening up sooner. You told me what
> the current order is which doesn't equate to dependencies. For
> example, step 4 may or may not be a dependency of step 5. These are
> the dependencies I'm aware of:
>
> memblock dependent on DT memory and reserved-memory parsing
> unflattening dependent on memblock_alloc()
> sparsemem dependent on NUMA parsing and memblock
>

I understand what you are saying.

Let me go back over the code looking to separate the issues of the 
inertia of the initial implementation, the need to cleanly support both 
EFI and non-EFI firmware, and your desire to unflatten the device tree 
much earlier than we currently do.

At this point, arm64 is the only user of the of_numa.c file.  So, if you 
think it is not general purpose enough to live in drivers/of we could 
discuss the possibility of moving it under arch/arm64


David.

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2016-03-01 17:58 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-20  1:13 [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms David Daney
2016-02-20  1:13 ` [PATCH v11 01/10] of/fdt: make generic early_init_dt_add_memory_arch() a weak alias David Daney
2016-02-20  1:13 ` [PATCH v11 02/10] arm64: override generic version of early_init_dt_add_memory_arch() David Daney
2016-02-20  1:13 ` [PATCH v11 03/10] efi: move FDT handling to separate object file David Daney
2016-02-20  1:13 ` [PATCH v11 04/10] arm64/efi: move EFI /chosen node parsing before early FDT processing David Daney
2016-02-20  1:13 ` [PATCH v11 05/10] arm64/efi: ignore DT memory nodes instead of removing them David Daney
2016-02-20  1:13 ` [PATCH v11 06/10] arm64/efi: ignore DT memreserve entries " David Daney
2016-02-20  1:13 ` [PATCH v11 07/10] Documentation, dt, numa: dt bindings for NUMA David Daney
2016-02-20  1:13 ` [PATCH v11 08/10] dt, numa: Add NUMA dt binding implementation David Daney
2016-02-23 19:36   ` Rob Herring
2016-02-26  1:26     ` David Daney
2016-02-26 18:27       ` Will Deacon
2016-03-01 16:56         ` Rob Herring
2016-03-01 16:47       ` Rob Herring
2016-03-01 16:57         ` David Daney
2016-03-01 17:43           ` Rob Herring
2016-03-01 17:58             ` David Daney
2016-02-20  1:13 ` [PATCH v11 09/10] arm64, numa: Add NUMA support for arm64 platforms David Daney
2016-02-20  1:13 ` [PATCH v11 10/10] arm64, mm, numa: Add NUMA balancing support for arm64 David Daney
2016-02-20  8:20 ` [PATCH v11 00/10] arm64, numa: Add numa support for arm64 platforms Ard Biesheuvel
2016-02-20 10:39   ` Robert Richter
2016-02-20 10:44     ` Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).