All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v4 0/4] arm64:numa: Add numa support for arm64 platforms.
@ 2015-01-22 11:05 ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-01-22 11:05 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Will.Deacon-5wv7dgnIgG8, catalin.marinas-5wv7dgnIgG8,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	roy.franz-QSEj5FYQhm4dnm+yROfE0A,
	ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	steve.capper-QSEj5FYQhm4dnm+yROfE0A,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
	jchandra-dY08KVG/lbpWk0Htik3J/w, al.stone-QSEj5FYQhm4dnm+yROfE0A,
	arnd-r2nGTMty4D4, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	ddutile-H+wXaHxf7aLQT0dZR+AlfA
  Cc: gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w

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 to each other.

v1:
Initial patchset to support numa on arm64 platforms.

Hi Arnd,
   there are not many common functions to pull to of driver from
   powerpc and arm.

thanks
Ganapat

Ganapatrao Kulkarni (4):
  arm64: defconfig: increase NR_CPUS range to 2-4096.
  Documentation: arm64/arm: dt bindings for numa.
  arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2     Node
    topology.
  arm64:numa: adding numa support for arm64 platforms.

 Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++
 arch/arm64/Kconfig                             |  36 +-
 arch/arm64/boot/dts/thunder-88xx-2n.dts        |  78 +++
 arch/arm64/boot/dts/thunder-88xx-2n.dtsi       | 790 +++++++++++++++++++++++++
 arch/arm64/include/asm/mmzone.h                |  32 +
 arch/arm64/include/asm/numa.h                  |  43 ++
 arch/arm64/kernel/Makefile                     |   1 +
 arch/arm64/kernel/dt_numa.c                    | 302 ++++++++++
 arch/arm64/kernel/setup.c                      |   8 +
 arch/arm64/kernel/smp.c                        |   2 +
 arch/arm64/mm/Makefile                         |   1 +
 arch/arm64/mm/init.c                           |  34 +-
 arch/arm64/mm/numa.c                           | 522 ++++++++++++++++
 13 files changed, 2053 insertions(+), 8 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
 create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dts
 create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dtsi
 create mode 100644 arch/arm64/include/asm/mmzone.h
 create mode 100644 arch/arm64/include/asm/numa.h
 create mode 100644 arch/arm64/kernel/dt_numa.c
 create mode 100644 arch/arm64/mm/numa.c

-- 
1.8.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 0/4] arm64:numa: Add numa support for arm64 platforms.
@ 2015-01-22 11:05 ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-01-22 11:05 UTC (permalink / raw)
  To: linux-arm-kernel

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 to each other.

v1:
Initial patchset to support numa on arm64 platforms.

Hi Arnd,
   there are not many common functions to pull to of driver from
   powerpc and arm.

thanks
Ganapat

Ganapatrao Kulkarni (4):
  arm64: defconfig: increase NR_CPUS range to 2-4096.
  Documentation: arm64/arm: dt bindings for numa.
  arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2     Node
    topology.
  arm64:numa: adding numa support for arm64 platforms.

 Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++
 arch/arm64/Kconfig                             |  36 +-
 arch/arm64/boot/dts/thunder-88xx-2n.dts        |  78 +++
 arch/arm64/boot/dts/thunder-88xx-2n.dtsi       | 790 +++++++++++++++++++++++++
 arch/arm64/include/asm/mmzone.h                |  32 +
 arch/arm64/include/asm/numa.h                  |  43 ++
 arch/arm64/kernel/Makefile                     |   1 +
 arch/arm64/kernel/dt_numa.c                    | 302 ++++++++++
 arch/arm64/kernel/setup.c                      |   8 +
 arch/arm64/kernel/smp.c                        |   2 +
 arch/arm64/mm/Makefile                         |   1 +
 arch/arm64/mm/init.c                           |  34 +-
 arch/arm64/mm/numa.c                           | 522 ++++++++++++++++
 13 files changed, 2053 insertions(+), 8 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
 create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dts
 create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dtsi
 create mode 100644 arch/arm64/include/asm/mmzone.h
 create mode 100644 arch/arm64/include/asm/numa.h
 create mode 100644 arch/arm64/kernel/dt_numa.c
 create mode 100644 arch/arm64/mm/numa.c

-- 
1.8.1.4

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

* [RFC PATCH v4 1/4] arm64: defconfig: increase NR_CPUS range to 2-4096.
  2015-01-22 11:05 ` Ganapatrao Kulkarni
@ 2015-01-22 11:05     ` Ganapatrao Kulkarni
  -1 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-01-22 11:05 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Will.Deacon-5wv7dgnIgG8, catalin.marinas-5wv7dgnIgG8,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	roy.franz-QSEj5FYQhm4dnm+yROfE0A,
	ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	steve.capper-QSEj5FYQhm4dnm+yROfE0A,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
	jchandra-dY08KVG/lbpWk0Htik3J/w, al.stone-QSEj5FYQhm4dnm+yROfE0A,
	arnd-r2nGTMty4D4, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	ddutile-H+wXaHxf7aLQT0dZR+AlfA
  Cc: gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w

From: Ganapatrao Kulkarni <ganapatrao.kulkarni-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>

Raising the maximum limit to 4096.
This is to accomadate up-coming higher multi-core platforms.

Acked-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
Signed-off-by: Ganapatrao Kulkarni <gkulkarni-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>
---
 arch/arm64/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 61fbd1f..242419d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -302,8 +302,8 @@ config SCHED_SMT
 	  places. If unsure say N here.
 
 config NR_CPUS
-	int "Maximum number of CPUs (2-64)"
-	range 2 64
+	int "Maximum number of CPUs (2-4096)"
+	range 2 4096
 	depends on SMP
 	# These have to remain sorted largest to smallest
 	default "64"
-- 
1.8.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 1/4] arm64: defconfig: increase NR_CPUS range to 2-4096.
@ 2015-01-22 11:05     ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-01-22 11:05 UTC (permalink / raw)
  To: linux-arm-kernel

From: Ganapatrao Kulkarni <ganapatrao.kulkarni@caviumnetworks.com>

Raising the maximum limit to 4096.
This is to accomadate up-coming higher multi-core platforms.

Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
---
 arch/arm64/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 61fbd1f..242419d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -302,8 +302,8 @@ config SCHED_SMT
 	  places. If unsure say N here.
 
 config NR_CPUS
-	int "Maximum number of CPUs (2-64)"
-	range 2 64
+	int "Maximum number of CPUs (2-4096)"
+	range 2 4096
 	depends on SMP
 	# These have to remain sorted largest to smallest
 	default "64"
-- 
1.8.1.4

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

* [RFC PATCH v4 2/4] Documentation: arm64/arm: dt bindings for numa.
  2015-01-22 11:05 ` Ganapatrao Kulkarni
@ 2015-01-22 11:05     ` Ganapatrao Kulkarni
  -1 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-01-22 11:05 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Will.Deacon-5wv7dgnIgG8, catalin.marinas-5wv7dgnIgG8,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	roy.franz-QSEj5FYQhm4dnm+yROfE0A,
	ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	steve.capper-QSEj5FYQhm4dnm+yROfE0A,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
	jchandra-dY08KVG/lbpWk0Htik3J/w, al.stone-QSEj5FYQhm4dnm+yROfE0A,
	arnd-r2nGTMty4D4, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	ddutile-H+wXaHxf7aLQT0dZR+AlfA
  Cc: gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w

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

Signed-off-by: Ganapatrao Kulkarni <gkulkarni-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>
---
 Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt

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

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 2/4] Documentation: arm64/arm: dt bindings for numa.
@ 2015-01-22 11:05     ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-01-22 11:05 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
---
 Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt

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

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

* [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
  2015-01-22 11:05 ` Ganapatrao Kulkarni
@ 2015-01-22 11:05     ` Ganapatrao Kulkarni
  -1 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-01-22 11:05 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Will.Deacon-5wv7dgnIgG8, catalin.marinas-5wv7dgnIgG8,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	roy.franz-QSEj5FYQhm4dnm+yROfE0A,
	ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	steve.capper-QSEj5FYQhm4dnm+yROfE0A,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
	jchandra-dY08KVG/lbpWk0Htik3J/w, al.stone-QSEj5FYQhm4dnm+yROfE0A,
	arnd-r2nGTMty4D4, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	ddutile-H+wXaHxf7aLQT0dZR+AlfA
  Cc: gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w

adding dt file for Cavium's Thunder SoC in 2 Node topology
using arm,associativity device node property.

Signed-off-by: Ganapatrao Kulkarni <gkulkarni-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>
---
 arch/arm64/boot/dts/thunder-88xx-2n.dts  |  78 +++
 arch/arm64/boot/dts/thunder-88xx-2n.dtsi | 790 +++++++++++++++++++++++++++++++
 2 files changed, 868 insertions(+)
 create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dts
 create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dtsi

diff --git a/arch/arm64/boot/dts/thunder-88xx-2n.dts b/arch/arm64/boot/dts/thunder-88xx-2n.dts
new file mode 100644
index 0000000..adbd3a9
--- /dev/null
+++ b/arch/arm64/boot/dts/thunder-88xx-2n.dts
@@ -0,0 +1,78 @@
+/*
+ * Cavium Thunder DTS file - Thunder board description
+ *
+ * Copyright (C) 2014, Cavium Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+/include/ "thunder-88xx-2n.dtsi"
+
+/ {
+	model = "Cavium ThunderX CN88XX board";
+	compatible = "cavium,thunder-88xx";
+	arm,associativity-reference-points = <0>;
+
+	aliases {
+		serial0 = &uaa0;
+		serial1 = &uaa1;
+	};
+
+	memory@00000000 {
+		device_type = "memory";
+		reg = <0x0 0x00000000 0x0 0x80000000>;
+		/* socket 0, no specific cluster, core */
+		arm,associativity = <0 0xffff 0xffff>;
+	};
+
+	memory@10000000000 {
+		device_type = "memory";
+		reg = <0x100 0x00000000 0x0 0x80000000>;
+		/* socket 1, no specific cluster, core */
+		arm,associativity = <1 0xffff 0xffff>;
+	};
+
+};
diff --git a/arch/arm64/boot/dts/thunder-88xx-2n.dtsi b/arch/arm64/boot/dts/thunder-88xx-2n.dtsi
new file mode 100644
index 0000000..dc6f8ea
--- /dev/null
+++ b/arch/arm64/boot/dts/thunder-88xx-2n.dtsi
@@ -0,0 +1,790 @@
+/*
+ * Cavium Thunder DTS file - Thunder SoC description
+ *
+ * Copyright (C) 2014, Cavium Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/ {
+	compatible = "cavium,thunder-88xx";
+	interrupt-parent = <&gic0>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu@000 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x000>;
+			enable-method = "psci";
+			/* socket 0, cluster 0, core 0*/
+			arm,associativity = <0 0 0>;
+		};
+		cpu@001 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x001>;
+			enable-method = "psci";
+			arm,associativity = <0 0 1>;
+		};
+		cpu@002 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x002>;
+			enable-method = "psci";
+			arm,associativity = <0 0 2>;
+		};
+		cpu@003 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x003>;
+			enable-method = "psci";
+			arm,associativity = <0 0 3>;
+		};
+		cpu@004 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x004>;
+			enable-method = "psci";
+			arm,associativity = <0 0 4>;
+		};
+		cpu@005 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x005>;
+			enable-method = "psci";
+			arm,associativity = <0 0 5>;
+		};
+		cpu@006 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x006>;
+			enable-method = "psci";
+			arm,associativity = <0 0 6>;
+		};
+		cpu@007 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x007>;
+			enable-method = "psci";
+			arm,associativity = <0 0 7>;
+		};
+		cpu@008 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x008>;
+			enable-method = "psci";
+			arm,associativity = <0 0 8>;
+		};
+		cpu@009 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x009>;
+			enable-method = "psci";
+			arm,associativity = <0 0 9>;
+		};
+		cpu@00a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00a>;
+			enable-method = "psci";
+			arm,associativity = <0 0 10>;
+		};
+		cpu@00b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00b>;
+			enable-method = "psci";
+			arm,associativity = <0 0 11>;
+		};
+		cpu@00c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00c>;
+			enable-method = "psci";
+			arm,associativity = <0 0 12>;
+		};
+		cpu@00d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00d>;
+			enable-method = "psci";
+			arm,associativity = <0 0 13>;
+		};
+		cpu@00e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00e>;
+			enable-method = "psci";
+			arm,associativity = <0 0 14>;
+		};
+		cpu@00f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00f>;
+			enable-method = "psci";
+			arm,associativity = <0 0 15>;
+		};
+		cpu@100 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			arm,associativity = <0 1 0>;
+		};
+		cpu@101 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			arm,associativity = <0 1 1>;
+		};
+		cpu@102 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x102>;
+			enable-method = "psci";
+			arm,associativity = <0 1 2>;
+		};
+		cpu@103 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x103>;
+			enable-method = "psci";
+			arm,associativity = <0 1 3>;
+		};
+		cpu@104 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x104>;
+			enable-method = "psci";
+			arm,associativity = <0 1 4>;
+		};
+		cpu@105 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x105>;
+			enable-method = "psci";
+			arm,associativity = <0 1 5>;
+		};
+		cpu@106 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x106>;
+			enable-method = "psci";
+			arm,associativity = <0 1 6>;
+		};
+		cpu@107 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x107>;
+			enable-method = "psci";
+			arm,associativity = <0 1 7>;
+		};
+		cpu@108 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x108>;
+			enable-method = "psci";
+			arm,associativity = <0 1 8>;
+		};
+		cpu@109 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x109>;
+			enable-method = "psci";
+			arm,associativity = <0 1 9>;
+		};
+		cpu@10a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10a>;
+			enable-method = "psci";
+			arm,associativity = <0 1 10>;
+		};
+		cpu@10b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10b>;
+			enable-method = "psci";
+			arm,associativity = <0 1 11>;
+		};
+		cpu@10c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10c>;
+			enable-method = "psci";
+			arm,associativity = <0 1 12>;
+		};
+		cpu@10d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10d>;
+			enable-method = "psci";
+			arm,associativity = <0 1 13>;
+		};
+		cpu@10e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10e>;
+			enable-method = "psci";
+			arm,associativity = <0 1 14>;
+		};
+		cpu@10f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10f>;
+			enable-method = "psci";
+			arm,associativity = <0 1 15>;
+		};
+		cpu@200 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			arm,associativity = <0 2 0>;
+		};
+		cpu@201 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x201>;
+			enable-method = "psci";
+			arm,associativity = <0 2 1>;
+		};
+		cpu@202 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x202>;
+			enable-method = "psci";
+			arm,associativity = <0 2 2>;
+		};
+		cpu@203 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x203>;
+			enable-method = "psci";
+			arm,associativity = <0 2 3>;
+		};
+		cpu@204 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x204>;
+			enable-method = "psci";
+			arm,associativity = <0 2 4>;
+		};
+		cpu@205 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x205>;
+			enable-method = "psci";
+			arm,associativity = <0 2 5>;
+		};
+		cpu@206 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x206>;
+			enable-method = "psci";
+			arm,associativity = <0 2 6>;
+		};
+		cpu@207 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x207>;
+			enable-method = "psci";
+			arm,associativity = <0 2 7>;
+		};
+		cpu@208 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x208>;
+			enable-method = "psci";
+			arm,associativity = <0 2 8>;
+		};
+		cpu@209 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x209>;
+			enable-method = "psci";
+			arm,associativity = <0 2 9>;
+		};
+		cpu@20a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20a>;
+			enable-method = "psci";
+			arm,associativity = <0 2 10>;
+		};
+		cpu@20b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20b>;
+			enable-method = "psci";
+			arm,associativity = <0 2 11>;
+		};
+		cpu@20c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20c>;
+			enable-method = "psci";
+			arm,associativity = <0 2 12>;
+		};
+		cpu@20d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20d>;
+			enable-method = "psci";
+			arm,associativity = <0 2 13>;
+		};
+		cpu@20e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20e>;
+			enable-method = "psci";
+			arm,associativity = <0 2 14>;
+		};
+		cpu@20f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20f>;
+			enable-method = "psci";
+			arm,associativity = <0 2 15>;
+		};
+		cpu@10000 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10000>;
+			enable-method = "psci";
+			/* socket 1, cluster 0, core 0*/
+			arm,associativity = <1 0 0>;
+		};
+		cpu@10001 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10001>;
+			enable-method = "psci";
+			arm,associativity = <1 0 1>;
+		};
+		cpu@10002 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10002>;
+			enable-method = "psci";
+			arm,associativity = <1 0 2>;
+		};
+		cpu@10003 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10003>;
+			enable-method = "psci";
+			arm,associativity = <1 0 3>;
+		};
+		cpu@10004 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10004>;
+			enable-method = "psci";
+			arm,associativity = <1 0 4>;
+		};
+		cpu@10005 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10005>;
+			enable-method = "psci";
+			arm,associativity = <1 0 5>;
+		};
+		cpu@10006 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10006>;
+			enable-method = "psci";
+			arm,associativity = <1 0 6>;
+		};
+		cpu@10007 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10007>;
+			enable-method = "psci";
+			arm,associativity = <1 0 7>;
+		};
+		cpu@10008 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10008>;
+			enable-method = "psci";
+			arm,associativity = <1 0 8>;
+		};
+		cpu@10009 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10009>;
+			enable-method = "psci";
+			arm,associativity = <1 0 9>;
+		};
+		cpu@1000a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000a>;
+			enable-method = "psci";
+			arm,associativity = <1 0 10>;
+		};
+		cpu@1000b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000b>;
+			enable-method = "psci";
+			arm,associativity = <1 0 11>;
+		};
+		cpu@1000c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000c>;
+			enable-method = "psci";
+			arm,associativity = <1 0 12>;
+		};
+		cpu@1000d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000d>;
+			enable-method = "psci";
+			arm,associativity = <1 0 13>;
+		};
+		cpu@1000e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000e>;
+			enable-method = "psci";
+			arm,associativity = <1 0 14>;
+		};
+		cpu@1000f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000f>;
+			enable-method = "psci";
+			arm,associativity = <1 0 15>;
+		};
+		cpu@10100 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10100>;
+			enable-method = "psci";
+			arm,associativity = <1 1 0>;
+		};
+		cpu@10101 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10101>;
+			enable-method = "psci";
+			arm,associativity = <1 1 1>;
+		};
+		cpu@10102 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10102>;
+			enable-method = "psci";
+			arm,associativity = <1 1 2>;
+		};
+		cpu@10103 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10103>;
+			enable-method = "psci";
+			arm,associativity = <1 1 3>;
+		};
+		cpu@10104 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10104>;
+			enable-method = "psci";
+			arm,associativity = <1 1 4>;
+		};
+		cpu@10105 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10105>;
+			enable-method = "psci";
+			arm,associativity = <1 1 5>;
+		};
+		cpu@10106 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10106>;
+			enable-method = "psci";
+			arm,associativity = <1 1 6>;
+		};
+		cpu@10107 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10107>;
+			enable-method = "psci";
+			arm,associativity = <1 1 7>;
+		};
+		cpu@10108 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10108>;
+			enable-method = "psci";
+			arm,associativity = <1 1 8>;
+		};
+		cpu@10109 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10109>;
+			enable-method = "psci";
+			arm,associativity = <1 1 9>;
+		};
+		cpu@1010a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010a>;
+			enable-method = "psci";
+			arm,associativity = <1 1 10>;
+		};
+		cpu@1010b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010b>;
+			enable-method = "psci";
+			arm,associativity = <1 1 11>;
+		};
+		cpu@1010c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010c>;
+			enable-method = "psci";
+			arm,associativity = <1 1 12>;
+		};
+		cpu@1010d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010d>;
+			enable-method = "psci";
+			arm,associativity = <1 1 13>;
+		};
+		cpu@1010e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010e>;
+			enable-method = "psci";
+			arm,associativity = <1 1 14>;
+		};
+		cpu@1010f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010f>;
+			enable-method = "psci";
+			arm,associativity = <1 1 15>;
+		};
+		cpu@10200 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10200>;
+			enable-method = "psci";
+			arm,associativity = <1 2 0>;
+		};
+		cpu@10201 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10201>;
+			enable-method = "psci";
+			arm,associativity = <1 2 1>;
+		};
+		cpu@10202 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10202>;
+			enable-method = "psci";
+			arm,associativity = <1 2 2>;
+		};
+		cpu@10203 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10203>;
+			enable-method = "psci";
+			arm,associativity = <1 2 3>;
+		};
+		cpu@10204 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10204>;
+			enable-method = "psci";
+			arm,associativity = <1 2 4>;
+		};
+		cpu@10205 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10205>;
+			enable-method = "psci";
+			arm,associativity = <1 2 5>;
+		};
+		cpu@10206 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10206>;
+			enable-method = "psci";
+			arm,associativity = <1 2 6>;
+		};
+		cpu@10207 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10207>;
+			enable-method = "psci";
+			arm,associativity = <1 2 7>;
+		};
+		cpu@10208 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10208>;
+			enable-method = "psci";
+			arm,associativity = <1 2 8>;
+		};
+		cpu@10209 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10209>;
+			enable-method = "psci";
+			arm,associativity = <1 2 9>;
+		};
+		cpu@1020a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020a>;
+			enable-method = "psci";
+			arm,associativity = <1 2 10>;
+		};
+		cpu@1020b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020b>;
+			enable-method = "psci";
+			arm,associativity = <1 2 11>;
+		};
+		cpu@1020c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020c>;
+			enable-method = "psci";
+			arm,associativity = <1 2 12>;
+		};
+		cpu@1020d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020d>;
+			enable-method = "psci";
+			arm,associativity = <1 2 13>;
+		};
+		cpu@1020e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020e>;
+			enable-method = "psci";
+			arm,associativity = <1 2 14>;
+		};
+		cpu@1020f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020f>;
+			enable-method = "psci";
+			arm,associativity = <1 2 15>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff01>,
+		             <1 14 0xff01>,
+		             <1 11 0xff01>,
+		             <1 10 0xff01>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		arm,associativity = <0 0xffff 0xffff>;
+
+		refclk50mhz: refclk50mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <50000000>;
+			clock-output-names = "refclk50mhz";
+		};
+
+		gic0: interrupt-controller@8010,00000000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			#redistributor-regions = <2>;
+			interrupt-controller;
+			reg = <0x8010 0x00000000 0x0 0x010000>, /* GICD */
+			      <0x8010 0x80000000 0x0 0x600000>, /* GICR Node 0 */
+			      <0x9010 0x80000000 0x0 0x600000>; /* GICR Node 1 */
+			interrupts = <1 9 0xf04>;
+		};
+
+		uaa0: serial@87e0,24000000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x87e0 0x24000000 0x0 0x1000>;
+			interrupts = <1 21 4>;
+			clocks = <&refclk50mhz>;
+			clock-names = "apb_pclk";
+		};
+
+		uaa1: serial@87e0,25000000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x87e0 0x25000000 0x0 0x1000>;
+			interrupts = <1 22 4>;
+			clocks = <&refclk50mhz>;
+			clock-names = "apb_pclk";
+		};
+	};
+};
-- 
1.8.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
@ 2015-01-22 11:05     ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-01-22 11:05 UTC (permalink / raw)
  To: linux-arm-kernel

adding dt file for Cavium's Thunder SoC in 2 Node topology
using arm,associativity device node property.

Signed-off-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
---
 arch/arm64/boot/dts/thunder-88xx-2n.dts  |  78 +++
 arch/arm64/boot/dts/thunder-88xx-2n.dtsi | 790 +++++++++++++++++++++++++++++++
 2 files changed, 868 insertions(+)
 create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dts
 create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dtsi

diff --git a/arch/arm64/boot/dts/thunder-88xx-2n.dts b/arch/arm64/boot/dts/thunder-88xx-2n.dts
new file mode 100644
index 0000000..adbd3a9
--- /dev/null
+++ b/arch/arm64/boot/dts/thunder-88xx-2n.dts
@@ -0,0 +1,78 @@
+/*
+ * Cavium Thunder DTS file - Thunder board description
+ *
+ * Copyright (C) 2014, Cavium Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+/include/ "thunder-88xx-2n.dtsi"
+
+/ {
+	model = "Cavium ThunderX CN88XX board";
+	compatible = "cavium,thunder-88xx";
+	arm,associativity-reference-points = <0>;
+
+	aliases {
+		serial0 = &uaa0;
+		serial1 = &uaa1;
+	};
+
+	memory at 00000000 {
+		device_type = "memory";
+		reg = <0x0 0x00000000 0x0 0x80000000>;
+		/* socket 0, no specific cluster, core */
+		arm,associativity = <0 0xffff 0xffff>;
+	};
+
+	memory at 10000000000 {
+		device_type = "memory";
+		reg = <0x100 0x00000000 0x0 0x80000000>;
+		/* socket 1, no specific cluster, core */
+		arm,associativity = <1 0xffff 0xffff>;
+	};
+
+};
diff --git a/arch/arm64/boot/dts/thunder-88xx-2n.dtsi b/arch/arm64/boot/dts/thunder-88xx-2n.dtsi
new file mode 100644
index 0000000..dc6f8ea
--- /dev/null
+++ b/arch/arm64/boot/dts/thunder-88xx-2n.dtsi
@@ -0,0 +1,790 @@
+/*
+ * Cavium Thunder DTS file - Thunder SoC description
+ *
+ * Copyright (C) 2014, Cavium Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This library is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/ {
+	compatible = "cavium,thunder-88xx";
+	interrupt-parent = <&gic0>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu at 000 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x000>;
+			enable-method = "psci";
+			/* socket 0, cluster 0, core 0*/
+			arm,associativity = <0 0 0>;
+		};
+		cpu at 001 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x001>;
+			enable-method = "psci";
+			arm,associativity = <0 0 1>;
+		};
+		cpu at 002 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x002>;
+			enable-method = "psci";
+			arm,associativity = <0 0 2>;
+		};
+		cpu at 003 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x003>;
+			enable-method = "psci";
+			arm,associativity = <0 0 3>;
+		};
+		cpu at 004 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x004>;
+			enable-method = "psci";
+			arm,associativity = <0 0 4>;
+		};
+		cpu at 005 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x005>;
+			enable-method = "psci";
+			arm,associativity = <0 0 5>;
+		};
+		cpu at 006 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x006>;
+			enable-method = "psci";
+			arm,associativity = <0 0 6>;
+		};
+		cpu at 007 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x007>;
+			enable-method = "psci";
+			arm,associativity = <0 0 7>;
+		};
+		cpu at 008 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x008>;
+			enable-method = "psci";
+			arm,associativity = <0 0 8>;
+		};
+		cpu at 009 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x009>;
+			enable-method = "psci";
+			arm,associativity = <0 0 9>;
+		};
+		cpu at 00a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00a>;
+			enable-method = "psci";
+			arm,associativity = <0 0 10>;
+		};
+		cpu at 00b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00b>;
+			enable-method = "psci";
+			arm,associativity = <0 0 11>;
+		};
+		cpu at 00c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00c>;
+			enable-method = "psci";
+			arm,associativity = <0 0 12>;
+		};
+		cpu at 00d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00d>;
+			enable-method = "psci";
+			arm,associativity = <0 0 13>;
+		};
+		cpu at 00e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00e>;
+			enable-method = "psci";
+			arm,associativity = <0 0 14>;
+		};
+		cpu at 00f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00f>;
+			enable-method = "psci";
+			arm,associativity = <0 0 15>;
+		};
+		cpu at 100 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			arm,associativity = <0 1 0>;
+		};
+		cpu at 101 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			arm,associativity = <0 1 1>;
+		};
+		cpu at 102 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x102>;
+			enable-method = "psci";
+			arm,associativity = <0 1 2>;
+		};
+		cpu at 103 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x103>;
+			enable-method = "psci";
+			arm,associativity = <0 1 3>;
+		};
+		cpu at 104 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x104>;
+			enable-method = "psci";
+			arm,associativity = <0 1 4>;
+		};
+		cpu at 105 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x105>;
+			enable-method = "psci";
+			arm,associativity = <0 1 5>;
+		};
+		cpu at 106 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x106>;
+			enable-method = "psci";
+			arm,associativity = <0 1 6>;
+		};
+		cpu at 107 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x107>;
+			enable-method = "psci";
+			arm,associativity = <0 1 7>;
+		};
+		cpu at 108 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x108>;
+			enable-method = "psci";
+			arm,associativity = <0 1 8>;
+		};
+		cpu at 109 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x109>;
+			enable-method = "psci";
+			arm,associativity = <0 1 9>;
+		};
+		cpu at 10a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10a>;
+			enable-method = "psci";
+			arm,associativity = <0 1 10>;
+		};
+		cpu at 10b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10b>;
+			enable-method = "psci";
+			arm,associativity = <0 1 11>;
+		};
+		cpu at 10c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10c>;
+			enable-method = "psci";
+			arm,associativity = <0 1 12>;
+		};
+		cpu at 10d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10d>;
+			enable-method = "psci";
+			arm,associativity = <0 1 13>;
+		};
+		cpu at 10e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10e>;
+			enable-method = "psci";
+			arm,associativity = <0 1 14>;
+		};
+		cpu at 10f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10f>;
+			enable-method = "psci";
+			arm,associativity = <0 1 15>;
+		};
+		cpu at 200 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			arm,associativity = <0 2 0>;
+		};
+		cpu at 201 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x201>;
+			enable-method = "psci";
+			arm,associativity = <0 2 1>;
+		};
+		cpu at 202 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x202>;
+			enable-method = "psci";
+			arm,associativity = <0 2 2>;
+		};
+		cpu at 203 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x203>;
+			enable-method = "psci";
+			arm,associativity = <0 2 3>;
+		};
+		cpu at 204 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x204>;
+			enable-method = "psci";
+			arm,associativity = <0 2 4>;
+		};
+		cpu at 205 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x205>;
+			enable-method = "psci";
+			arm,associativity = <0 2 5>;
+		};
+		cpu at 206 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x206>;
+			enable-method = "psci";
+			arm,associativity = <0 2 6>;
+		};
+		cpu at 207 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x207>;
+			enable-method = "psci";
+			arm,associativity = <0 2 7>;
+		};
+		cpu at 208 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x208>;
+			enable-method = "psci";
+			arm,associativity = <0 2 8>;
+		};
+		cpu at 209 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x209>;
+			enable-method = "psci";
+			arm,associativity = <0 2 9>;
+		};
+		cpu at 20a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20a>;
+			enable-method = "psci";
+			arm,associativity = <0 2 10>;
+		};
+		cpu at 20b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20b>;
+			enable-method = "psci";
+			arm,associativity = <0 2 11>;
+		};
+		cpu at 20c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20c>;
+			enable-method = "psci";
+			arm,associativity = <0 2 12>;
+		};
+		cpu at 20d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20d>;
+			enable-method = "psci";
+			arm,associativity = <0 2 13>;
+		};
+		cpu at 20e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20e>;
+			enable-method = "psci";
+			arm,associativity = <0 2 14>;
+		};
+		cpu at 20f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20f>;
+			enable-method = "psci";
+			arm,associativity = <0 2 15>;
+		};
+		cpu at 10000 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10000>;
+			enable-method = "psci";
+			/* socket 1, cluster 0, core 0*/
+			arm,associativity = <1 0 0>;
+		};
+		cpu at 10001 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10001>;
+			enable-method = "psci";
+			arm,associativity = <1 0 1>;
+		};
+		cpu at 10002 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10002>;
+			enable-method = "psci";
+			arm,associativity = <1 0 2>;
+		};
+		cpu at 10003 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10003>;
+			enable-method = "psci";
+			arm,associativity = <1 0 3>;
+		};
+		cpu at 10004 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10004>;
+			enable-method = "psci";
+			arm,associativity = <1 0 4>;
+		};
+		cpu at 10005 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10005>;
+			enable-method = "psci";
+			arm,associativity = <1 0 5>;
+		};
+		cpu at 10006 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10006>;
+			enable-method = "psci";
+			arm,associativity = <1 0 6>;
+		};
+		cpu at 10007 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10007>;
+			enable-method = "psci";
+			arm,associativity = <1 0 7>;
+		};
+		cpu at 10008 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10008>;
+			enable-method = "psci";
+			arm,associativity = <1 0 8>;
+		};
+		cpu at 10009 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10009>;
+			enable-method = "psci";
+			arm,associativity = <1 0 9>;
+		};
+		cpu at 1000a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000a>;
+			enable-method = "psci";
+			arm,associativity = <1 0 10>;
+		};
+		cpu at 1000b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000b>;
+			enable-method = "psci";
+			arm,associativity = <1 0 11>;
+		};
+		cpu at 1000c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000c>;
+			enable-method = "psci";
+			arm,associativity = <1 0 12>;
+		};
+		cpu at 1000d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000d>;
+			enable-method = "psci";
+			arm,associativity = <1 0 13>;
+		};
+		cpu at 1000e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000e>;
+			enable-method = "psci";
+			arm,associativity = <1 0 14>;
+		};
+		cpu at 1000f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000f>;
+			enable-method = "psci";
+			arm,associativity = <1 0 15>;
+		};
+		cpu at 10100 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10100>;
+			enable-method = "psci";
+			arm,associativity = <1 1 0>;
+		};
+		cpu at 10101 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10101>;
+			enable-method = "psci";
+			arm,associativity = <1 1 1>;
+		};
+		cpu at 10102 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10102>;
+			enable-method = "psci";
+			arm,associativity = <1 1 2>;
+		};
+		cpu at 10103 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10103>;
+			enable-method = "psci";
+			arm,associativity = <1 1 3>;
+		};
+		cpu at 10104 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10104>;
+			enable-method = "psci";
+			arm,associativity = <1 1 4>;
+		};
+		cpu at 10105 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10105>;
+			enable-method = "psci";
+			arm,associativity = <1 1 5>;
+		};
+		cpu at 10106 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10106>;
+			enable-method = "psci";
+			arm,associativity = <1 1 6>;
+		};
+		cpu at 10107 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10107>;
+			enable-method = "psci";
+			arm,associativity = <1 1 7>;
+		};
+		cpu at 10108 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10108>;
+			enable-method = "psci";
+			arm,associativity = <1 1 8>;
+		};
+		cpu at 10109 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10109>;
+			enable-method = "psci";
+			arm,associativity = <1 1 9>;
+		};
+		cpu at 1010a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010a>;
+			enable-method = "psci";
+			arm,associativity = <1 1 10>;
+		};
+		cpu at 1010b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010b>;
+			enable-method = "psci";
+			arm,associativity = <1 1 11>;
+		};
+		cpu at 1010c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010c>;
+			enable-method = "psci";
+			arm,associativity = <1 1 12>;
+		};
+		cpu at 1010d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010d>;
+			enable-method = "psci";
+			arm,associativity = <1 1 13>;
+		};
+		cpu at 1010e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010e>;
+			enable-method = "psci";
+			arm,associativity = <1 1 14>;
+		};
+		cpu at 1010f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010f>;
+			enable-method = "psci";
+			arm,associativity = <1 1 15>;
+		};
+		cpu at 10200 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10200>;
+			enable-method = "psci";
+			arm,associativity = <1 2 0>;
+		};
+		cpu at 10201 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10201>;
+			enable-method = "psci";
+			arm,associativity = <1 2 1>;
+		};
+		cpu at 10202 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10202>;
+			enable-method = "psci";
+			arm,associativity = <1 2 2>;
+		};
+		cpu at 10203 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10203>;
+			enable-method = "psci";
+			arm,associativity = <1 2 3>;
+		};
+		cpu at 10204 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10204>;
+			enable-method = "psci";
+			arm,associativity = <1 2 4>;
+		};
+		cpu at 10205 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10205>;
+			enable-method = "psci";
+			arm,associativity = <1 2 5>;
+		};
+		cpu at 10206 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10206>;
+			enable-method = "psci";
+			arm,associativity = <1 2 6>;
+		};
+		cpu at 10207 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10207>;
+			enable-method = "psci";
+			arm,associativity = <1 2 7>;
+		};
+		cpu at 10208 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10208>;
+			enable-method = "psci";
+			arm,associativity = <1 2 8>;
+		};
+		cpu at 10209 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10209>;
+			enable-method = "psci";
+			arm,associativity = <1 2 9>;
+		};
+		cpu at 1020a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020a>;
+			enable-method = "psci";
+			arm,associativity = <1 2 10>;
+		};
+		cpu at 1020b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020b>;
+			enable-method = "psci";
+			arm,associativity = <1 2 11>;
+		};
+		cpu at 1020c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020c>;
+			enable-method = "psci";
+			arm,associativity = <1 2 12>;
+		};
+		cpu at 1020d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020d>;
+			enable-method = "psci";
+			arm,associativity = <1 2 13>;
+		};
+		cpu at 1020e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020e>;
+			enable-method = "psci";
+			arm,associativity = <1 2 14>;
+		};
+		cpu at 1020f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020f>;
+			enable-method = "psci";
+			arm,associativity = <1 2 15>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff01>,
+		             <1 14 0xff01>,
+		             <1 11 0xff01>,
+		             <1 10 0xff01>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		arm,associativity = <0 0xffff 0xffff>;
+
+		refclk50mhz: refclk50mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <50000000>;
+			clock-output-names = "refclk50mhz";
+		};
+
+		gic0: interrupt-controller at 8010,00000000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			#redistributor-regions = <2>;
+			interrupt-controller;
+			reg = <0x8010 0x00000000 0x0 0x010000>, /* GICD */
+			      <0x8010 0x80000000 0x0 0x600000>, /* GICR Node 0 */
+			      <0x9010 0x80000000 0x0 0x600000>; /* GICR Node 1 */
+			interrupts = <1 9 0xf04>;
+		};
+
+		uaa0: serial at 87e0,24000000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x87e0 0x24000000 0x0 0x1000>;
+			interrupts = <1 21 4>;
+			clocks = <&refclk50mhz>;
+			clock-names = "apb_pclk";
+		};
+
+		uaa1: serial at 87e0,25000000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x87e0 0x25000000 0x0 0x1000>;
+			interrupts = <1 22 4>;
+			clocks = <&refclk50mhz>;
+			clock-names = "apb_pclk";
+		};
+	};
+};
-- 
1.8.1.4

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

* [RFC PATCH v4 4/4] arm64:numa: adding numa support for arm64 platforms.
  2015-01-22 11:05 ` Ganapatrao Kulkarni
@ 2015-01-22 11:05   ` Ganapatrao Kulkarni
  -1 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-01-22 11:05 UTC (permalink / raw)
  To: linux-arm-kernel, Will.Deacon, catalin.marinas, grant.likely,
	devicetree, leif.lindholm, roy.franz, ard.biesheuvel, msalter,
	robh+dt, steve.capper, hanjun.guo, jchandra, al.stone, arnd, jcm,
	ddutile
  Cc: gpkulkarni

Adding numa support for arm64 based platforms.
Adding dt node pasring for numa topology using property arm,associativity.

Signed-off-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
---
 arch/arm64/Kconfig              |  32 +++
 arch/arm64/include/asm/mmzone.h |  32 +++
 arch/arm64/include/asm/numa.h   |  43 ++++
 arch/arm64/kernel/Makefile      |   1 +
 arch/arm64/kernel/dt_numa.c     | 302 +++++++++++++++++++++++
 arch/arm64/kernel/setup.c       |   8 +
 arch/arm64/kernel/smp.c         |   2 +
 arch/arm64/mm/Makefile          |   1 +
 arch/arm64/mm/init.c            |  34 ++-
 arch/arm64/mm/numa.c            | 522 ++++++++++++++++++++++++++++++++++++++++
 10 files changed, 971 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm64/include/asm/mmzone.h
 create mode 100644 arch/arm64/include/asm/numa.h
 create mode 100644 arch/arm64/kernel/dt_numa.c
 create mode 100644 arch/arm64/mm/numa.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 242419d..6d262b1 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -59,6 +59,7 @@ config ARM64
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_RCU_TABLE_FREE
 	select HAVE_SYSCALL_TRACEPOINTS
+	select HAVE_MEMBLOCK_NODE_MAP if NUMA
 	select IRQ_DOMAIN
 	select MODULES_USE_ELF_RELA
 	select NO_BOOTMEM
@@ -315,6 +316,37 @@ config HOTPLUG_CPU
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
 	  can be controlled through /sys/devices/system/cpu.
 
+# Common NUMA Features
+config NUMA
+	bool "Numa Memory Allocation and Scheduler Support"
+	depends on SMP
+	---help---
+	  Enable NUMA (Non Uniform Memory Access) support.
+
+	  The kernel will try to allocate memory used by a CPU on the
+	  local memory controller of the CPU and add some more
+	  NUMA awareness to the kernel.
+
+config ARM64_DT_NUMA
+	def_bool n
+	prompt "DT NUMA detection"
+	---help---
+	  Enable DT based numa.
+
+config NODES_SHIFT
+	int "Maximum NUMA Nodes (as a power of 2)"
+	range 1 10
+	default "2"
+	depends on NEED_MULTIPLE_NODES
+	---help---
+	  Specify the maximum number of NUMA Nodes available on the target
+	  system.  Increases memory reserved to accommodate various tables.
+
+config USE_PERCPU_NUMA_NODE_ID
+	def_bool y
+	depends on NUMA
+
+
 source kernel/Kconfig.preempt
 
 config HZ
diff --git a/arch/arm64/include/asm/mmzone.h b/arch/arm64/include/asm/mmzone.h
new file mode 100644
index 0000000..d27ee66
--- /dev/null
+++ b/arch/arm64/include/asm/mmzone.h
@@ -0,0 +1,32 @@
+#ifndef __ASM_ARM64_MMZONE_H_
+#define __ASM_ARM64_MMZONE_H_
+
+#ifdef CONFIG_NUMA
+
+#include <linux/mmdebug.h>
+#include <asm/smp.h>
+#include <linux/types.h>
+#include <asm/numa.h>
+
+extern struct pglist_data *node_data[];
+
+#define NODE_DATA(nid)		(node_data[nid])
+
+
+struct numa_memblk {
+	u64			start;
+	u64			end;
+	int			nid;
+};
+
+struct numa_meminfo {
+	int			nr_blks;
+	struct numa_memblk	blk[NR_NODE_MEMBLKS];
+};
+
+void __init numa_remove_memblk_from(int idx, struct numa_meminfo *mi);
+int __init numa_cleanup_meminfo(struct numa_meminfo *mi);
+void __init numa_reset_distance(void);
+
+#endif /* CONFIG_NUMA */
+#endif /* __ASM_ARM64_MMZONE_H_ */
diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h
new file mode 100644
index 0000000..8be5cb1
--- /dev/null
+++ b/arch/arm64/include/asm/numa.h
@@ -0,0 +1,43 @@
+#ifndef _ASM_ARM64_NUMA_H
+#define _ASM_ARM64_NUMA_H
+
+#include <linux/nodemask.h>
+#include <asm/topology.h>
+
+#ifdef CONFIG_NUMA
+
+#define NR_NODE_MEMBLKS		(MAX_NUMNODES * 2)
+#define ZONE_ALIGN (1UL << (MAX_ORDER + PAGE_SHIFT))
+
+/* currently, arm64 implements flat NUMA topology */
+#define parent_node(node)	(node)
+
+/* dummy definitions for pci functions */
+#define pcibus_to_node(node)	0
+#define cpumask_of_pcibus(bus)	0
+
+struct __node_cpu_hwid {
+	u32 node_id;    /* logical node containing this CPU */
+	u64 cpu_hwid;   /* MPIDR for this CPU */
+};
+
+const struct cpumask *cpumask_of_node(int node);
+/* Mappings between node number and cpus on that node. */
+extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+
+void __init arm64_numa_init(void);
+int __init numa_add_memblk(u32 nodeid, u64 start, u64 end);
+void numa_store_cpu_info(int cpu);
+void numa_set_node(int cpu, int node);
+void numa_clear_node(int cpu);
+void numa_add_cpu(int cpu);
+void numa_remove_cpu(int cpu);
+void __init numa_set_distance(int from, int to, int distance);
+int dt_get_cpu_node_id(int cpu);
+int __init arm64_dt_numa_init(void);
+#else	/* CONFIG_NUMA */
+static inline void arm64_numa_init(void);
+static inline void numa_store_cpu_info(int cpu)		{ }
+static inline void arm64_numa_init(void)		{ }
+#endif	/* CONFIG_NUMA */
+#endif	/* _ASM_ARM64_NUMA_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 5bd029b..39451df 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -31,6 +31,7 @@ arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
 arm64-obj-$(CONFIG_PCI)			+= pci.o
+arm64-obj-$(CONFIG_ARM64_DT_NUMA)	+= dt_numa.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/dt_numa.c b/arch/arm64/kernel/dt_numa.c
new file mode 100644
index 0000000..7c418e2
--- /dev/null
+++ b/arch/arm64/kernel/dt_numa.c
@@ -0,0 +1,302 @@
+/*
+ * DT NUMA Parsing support, based on the powerpc 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/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <asm/smp_plat.h>
+
+#define MAX_DISTANCE_REF_POINTS 8
+static int min_common_depth;
+static int distance_ref_points_depth;
+static const __be32 *distance_ref_points;
+static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS];
+static int default_nid;
+static int of_node_to_nid_single(struct device_node *device);
+static struct device_node *of_cpu_to_node(int cpu);
+extern nodemask_t numa_nodes_parsed __initdata;
+
+static void initialize_distance_lookup_table(int nid,
+		const __be32 *associativity)
+{
+	int i;
+
+	for (i = 0; i < distance_ref_points_depth; i++) {
+		const __be32 *entry;
+
+		entry = &associativity[be32_to_cpu(distance_ref_points[i])];
+		distance_lookup_table[nid][i] = of_read_number(entry, 1);
+	}
+}
+
+/* must hold reference to node during call */
+static const __be32 *of_get_associativity(struct device_node *dev)
+{
+	return of_get_property(dev, "arm,associativity", NULL);
+}
+
+/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
+ * info is found.
+ */
+static int associativity_to_nid(const __be32 *associativity)
+{
+	int nid = NUMA_NO_NODE;
+
+	if (min_common_depth == -1)
+		goto out;
+
+	if (of_read_number(associativity, 1) >= min_common_depth)
+		nid = of_read_number(&associativity[min_common_depth], 1);
+
+	/* set 0xffff as invalid node */
+	if (nid == 0xffff || nid >= MAX_NUMNODES)
+		nid = NUMA_NO_NODE;
+
+	if (nid != NUMA_NO_NODE)
+		initialize_distance_lookup_table(nid, associativity);
+out:
+	return nid;
+}
+
+/* Returns the nid associated with the given device tree node,
+ * or -1 if not found.
+ */
+static int of_node_to_nid_single(struct device_node *device)
+{
+	int nid = default_nid;
+	const __be32 *tmp;
+
+	tmp = of_get_associativity(device);
+	if (tmp)
+		nid = associativity_to_nid(tmp);
+	return nid;
+}
+
+/* Walk the device tree upwards, looking for an associativity id */
+int of_node_to_nid(struct device_node *device)
+{
+	struct device_node *tmp;
+	int nid = NUMA_NO_NODE;
+
+	of_node_get(device);
+	while (device) {
+		nid = of_node_to_nid_single(device);
+		if (nid != NUMA_NO_NODE)
+			break;
+
+		tmp = device;
+		device = of_get_parent(tmp);
+		of_node_put(tmp);
+	}
+	of_node_put(device);
+
+	return nid;
+}
+
+static int __init find_min_common_depth(unsigned long node)
+{
+	int depth;
+	const __be32 *numa_prop;
+	int nr_address_cells;
+
+	/*
+	 * This property is a set of 32-bit integers, each representing
+	 * an index into the arm,associativity nodes.
+	 *
+	 * With form 1 affinity the first integer is the most significant
+	 * NUMA boundary and the following are progressively less significant
+	 * boundaries. There can be more than one level of NUMA.
+	 */
+
+	distance_ref_points = of_get_flat_dt_prop(node,
+			"arm,associativity-reference-points",
+			&distance_ref_points_depth);
+	numa_prop = distance_ref_points;
+
+	if (numa_prop) {
+		nr_address_cells = dt_mem_next_cell(
+				OF_ROOT_NODE_ADDR_CELLS_DEFAULT, &numa_prop);
+		nr_address_cells = dt_mem_next_cell(
+				OF_ROOT_NODE_ADDR_CELLS_DEFAULT, &numa_prop);
+	}
+	if (!distance_ref_points) {
+		pr_debug("NUMA: arm,associativity-reference-points not found.\n");
+		goto err;
+	}
+
+	distance_ref_points_depth /= sizeof(__be32);
+
+	if (!distance_ref_points_depth) {
+		pr_err("NUMA: missing arm,associativity-reference-points\n");
+		goto err;
+	}
+	depth = of_read_number(distance_ref_points, 1);
+
+	/*
+	 * Warn and cap if the hardware supports more than
+	 * MAX_DISTANCE_REF_POINTS domains.
+	 */
+	if (distance_ref_points_depth > MAX_DISTANCE_REF_POINTS) {
+		pr_debug("NUMA: distance array capped at %d entries\n", MAX_DISTANCE_REF_POINTS);
+		distance_ref_points_depth = MAX_DISTANCE_REF_POINTS;
+	}
+
+	return depth;
+err:
+	return -1;
+}
+
+int dt_get_cpu_node_id(int cpu)
+{
+	struct device_node *dn = NULL;
+	int nid = default_nid;
+
+	dn =  of_cpu_to_node(cpu);
+	if (dn)
+		nid = of_node_to_nid_single(dn);
+	return nid;
+}
+
+static struct device_node *of_cpu_to_node(int cpu)
+{
+	struct device_node *dn = NULL;
+
+	while ((dn = of_find_node_by_type(dn, "cpu"))) {
+		const u32 *cell;
+		u64 hwid;
+
+		/*
+		 * A cpu node with missing "reg" property is
+		 * considered invalid to build a cpu_logical_map
+		 * entry.
+		 */
+		cell = of_get_property(dn, "reg", NULL);
+		if (!cell) {
+			pr_err("%s: missing reg property\n", dn->full_name);
+			return NULL;
+		}
+		hwid = of_read_number(cell, of_n_addr_cells(dn));
+
+		if (cpu_logical_map(cpu) == hwid)
+			return dn;
+	}
+	return NULL;
+}
+
+static int __init parse_memory_node(unsigned long node)
+{
+	const __be32 *reg, *endp, *associativity;
+	int length;
+	int nid = default_nid;
+
+	associativity = of_get_flat_dt_prop(node, "arm,associativity", &length);
+
+	if (associativity)
+		nid = associativity_to_nid(associativity);
+
+	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;
+		struct memblock_region *mblk;
+
+		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
+		size = dt_mem_next_cell(dt_root_size_cells, &reg);
+		pr_debug("NUMA-DT:  base = %llx , node = %u\n",
+				base, nid);
+		for_each_memblock(memory, mblk) {
+			if (mblk->base == base) {
+				node_set(nid, numa_nodes_parsed);
+				numa_add_memblk(nid, mblk->base, mblk->size);
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * early_init_dt_scan_numa_map - parse memory node and map nid to memory range.
+ */
+int __init early_init_dt_scan_numa_map(unsigned long node, const char *uname,
+				     int depth, void *data)
+{
+	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+
+	if (depth == 0) {
+		min_common_depth = find_min_common_depth(node);
+		if (min_common_depth < 0)
+			return min_common_depth;
+		pr_debug("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
+		return 0;
+	}
+
+	if (type) {
+		if (strcmp(type, "memory") == 0)
+			parse_memory_node(node);
+	}
+	return 0;
+}
+
+int dt_get_node_distance(int a, int b)
+{
+	int i;
+	int distance = LOCAL_DISTANCE;
+
+	for (i = 0; i < distance_ref_points_depth; i++) {
+		if (distance_lookup_table[a][i] == distance_lookup_table[b][i])
+			break;
+
+		/* Double the distance for each NUMA level */
+		distance *= 2;
+	}
+	return distance;
+}
+
+/* DT node mapping is done already early_init_dt_scan_memory */
+int __init arm64_dt_numa_init(void)
+{
+	int i;
+	u32 nodea, nodeb, distance, node_count = 0;
+
+	of_scan_flat_dt(early_init_dt_scan_numa_map, NULL);
+
+	for_each_node_mask(i, numa_nodes_parsed)
+		node_count = i;
+	node_count++;
+
+	for (nodea =  0; nodea < node_count; nodea++) {
+		for (nodeb = 0; nodeb < node_count; nodeb++) {
+			distance = dt_get_node_distance(nodea, nodeb);
+			numa_set_distance(nodea, nodeb, distance);
+		}
+	}
+	return 0;
+}
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 2437196..80b4a9e 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -425,6 +425,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;
@@ -461,7 +464,12 @@ static int c_show(struct seq_file *m, void *v)
 		 * "processor".  Give glibc what it expects.
 		 */
 #ifdef CONFIG_SMP
+	if (IS_ENABLED(CONFIG_NUMA)) {
+		seq_printf(m, "processor\t: %d", i);
+		seq_printf(m, " [nid: %d]\n", cpu_to_node(i));
+	} else {
 		seq_printf(m, "processor\t: %d\n", i);
+	}
 #endif
 	}
 
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index b06d1d9..1d1e86f 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -50,6 +50,7 @@
 #include <asm/sections.h>
 #include <asm/tlbflush.h>
 #include <asm/ptrace.h>
+#include <asm/numa.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/ipi.h>
@@ -123,6 +124,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 static void smp_store_cpu_info(unsigned int cpuid)
 {
 	store_cpu_topology(cpuid);
+	numa_store_cpu_info(cpuid);
 }
 
 /*
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index c56179e..c86e6de 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -3,3 +3,4 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
 				   ioremap.o mmap.o pgd.o mmu.o \
 				   context.o proc.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
+obj-$(CONFIG_NUMA)		+= numa.o
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 494297c..6fd6802 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -39,6 +39,7 @@
 #include <asm/setup.h>
 #include <asm/sizes.h>
 #include <asm/tlb.h>
+#include <asm/numa.h>
 
 #include "mm.h"
 
@@ -73,6 +74,20 @@ static phys_addr_t max_zone_dma_phys(void)
 	return min(offset + (1ULL << 32), memblock_end_of_DRAM());
 }
 
+#ifdef CONFIG_NUMA
+static void __init zone_sizes_init(unsigned long min, unsigned long max)
+{
+	unsigned long max_zone_pfns[MAX_NR_ZONES];
+
+	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+	if (IS_ENABLED(CONFIG_ZONE_DMA))
+		max_zone_pfns[ZONE_DMA] = PFN_DOWN(max_zone_dma_phys());
+	max_zone_pfns[ZONE_NORMAL] = max;
+
+	free_area_init_nodes(max_zone_pfns);
+}
+
+#else
 static void __init zone_sizes_init(unsigned long min, unsigned long max)
 {
 	struct memblock_region *reg;
@@ -111,6 +126,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 
 	free_area_init_node(0, zone_size, min, zhole_size);
 }
+#endif /* CONFIG_NUMA */
 
 #ifdef CONFIG_HAVE_ARCH_PFN_VALID
 int pfn_valid(unsigned long pfn)
@@ -128,10 +144,15 @@ static void arm64_memory_present(void)
 static void arm64_memory_present(void)
 {
 	struct memblock_region *reg;
+	int nid = 0;
 
-	for_each_memblock(memory, reg)
-		memory_present(0, memblock_region_memory_base_pfn(reg),
-			       memblock_region_memory_end_pfn(reg));
+	for_each_memblock(memory, reg) {
+#ifdef CONFIG_NUMA
+		nid = reg->nid;
+#endif
+		memory_present(nid, memblock_region_memory_base_pfn(reg),
+				memblock_region_memory_end_pfn(reg));
+	}
 }
 #endif
 
@@ -167,6 +188,10 @@ void __init bootmem_init(void)
 	min = PFN_UP(memblock_start_of_DRAM());
 	max = PFN_DOWN(memblock_end_of_DRAM());
 
+	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
+	max_pfn = max_low_pfn = max;
+
+	arm64_numa_init();
 	/*
 	 * Sparsemem tries to allocate bootmem in memory_present(), so must be
 	 * done after the fixed reservations.
@@ -175,9 +200,6 @@ void __init bootmem_init(void)
 
 	sparse_init();
 	zone_sizes_init(min, max);
-
-	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
-	max_pfn = max_low_pfn = max;
 }
 
 #ifndef CONFIG_SPARSEMEM_VMEMMAP
diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
new file mode 100644
index 0000000..da1d301
--- /dev/null
+++ b/arch/arm64/mm/numa.c
@@ -0,0 +1,522 @@
+/*
+ * 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/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/mmzone.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+#include <linux/topology.h>
+#include <linux/of.h>
+#include <asm/smp_plat.h>
+
+int __initdata numa_off;
+nodemask_t numa_nodes_parsed __initdata;
+static int numa_distance_cnt;
+static u8 *numa_distance;
+
+struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
+EXPORT_SYMBOL(node_data);
+
+static struct __node_cpu_hwid node_cpu_hwid[NR_CPUS];
+static struct numa_meminfo numa_meminfo;
+
+static __init int numa_setup(char *opt)
+{
+	if (!opt)
+		return -EINVAL;
+	if (!strncmp(opt, "off", 3)) {
+		pr_info("%s\n", "NUMA turned off");
+		numa_off = 1;
+	}
+	return 0;
+}
+early_param("numa", numa_setup);
+
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+EXPORT_SYMBOL(node_to_cpumask_map);
+
+/*
+ * Returns a pointer to the bitmask of CPUs on Node 'node'.
+ */
+const struct cpumask *cpumask_of_node(int node)
+{
+	if (node >= nr_node_ids) {
+		pr_warn("cpumask_of_node(%d): node > nr_node_ids(%d)\n",
+			node, nr_node_ids);
+		dump_stack();
+		return cpu_none_mask;
+	}
+	if (node_to_cpumask_map[node] == NULL) {
+		pr_warn("cpumask_of_node(%d): no node_to_cpumask_map!\n",
+			node);
+		dump_stack();
+		return cpu_online_mask;
+	}
+	return node_to_cpumask_map[node];
+}
+EXPORT_SYMBOL(cpumask_of_node);
+
+void numa_clear_node(int cpu)
+{
+	node_cpu_hwid[cpu].node_id = NUMA_NO_NODE;
+}
+
+/*
+ * Allocate node_to_cpumask_map based on number of available nodes
+ * Requires node_possible_map to be valid.
+ *
+ * Note: cpumask_of_node() is not valid until after this is done.
+ * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
+ */
+void __init setup_node_to_cpumask_map(void)
+{
+	unsigned int node;
+
+	/* setup nr_node_ids if not done yet */
+	if (nr_node_ids == MAX_NUMNODES)
+		setup_nr_node_ids();
+
+	/* allocate the map */
+	for (node = 0; node < nr_node_ids; node++)
+		alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
+
+	/* cpumask_of_node() will now work */
+	pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
+}
+
+/*
+ *  Set the cpu to node and mem mapping
+ */
+void numa_store_cpu_info(int cpu)
+{
+	if (IS_ENABLED(CONFIG_ARM64_DT_NUMA))
+		node_cpu_hwid[cpu].node_id  =  dt_get_cpu_node_id(cpu);
+	else
+		node_cpu_hwid[cpu].node_id  =  0;
+
+	/* mapping of MPIDR/hwid, node and logical cpu id */
+	node_cpu_hwid[cpu].cpu_hwid = cpu_logical_map(cpu);
+	cpumask_set_cpu(cpu, node_to_cpumask_map[node_cpu_hwid[cpu].node_id]);
+	set_numa_node(node_cpu_hwid[cpu].node_id);
+	set_numa_mem(local_memory_node(node_cpu_hwid[cpu].node_id));
+}
+
+/**
+ * numa_add_memblk_to - Add one numa_memblk to a numa_meminfo
+ */
+
+static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
+				     struct numa_meminfo *mi)
+{
+	/* ignore zero length blks */
+	if (start == end)
+		return 0;
+
+	/* whine about and ignore invalid blks */
+	if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
+		pr_warn("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
+				nid, start, end - 1);
+		return 0;
+	}
+
+	if (mi->nr_blks >= NR_NODE_MEMBLKS) {
+		pr_err("NUMA: too many memblk ranges\n");
+		return -EINVAL;
+	}
+
+	pr_info("NUMA: Adding memblock %d [0x%llx - 0x%llx] on node %d\n",
+			mi->nr_blks, start, end, nid);
+	mi->blk[mi->nr_blks].start = start;
+	mi->blk[mi->nr_blks].end = end;
+	mi->blk[mi->nr_blks].nid = nid;
+	mi->nr_blks++;
+	return 0;
+}
+
+/**
+ * numa_add_memblk - Add one numa_memblk to numa_meminfo
+ * @nid: NUMA node ID of the new memblk
+ * @start: Start address of the new memblk
+ * @end: End address of the new memblk
+ *
+ * Add a new memblk to the default numa_meminfo.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+#define MAX_PHYS_ADDR	((phys_addr_t)~0)
+
+int __init numa_add_memblk(u32 nid, u64 base, u64 size)
+{
+	const u64 phys_offset = __pa(PAGE_OFFSET);
+
+	base &= PAGE_MASK;
+	size &= PAGE_MASK;
+
+	if (base > MAX_PHYS_ADDR) {
+		pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
+				base, base + size);
+		return -ENOMEM;
+	}
+
+	if (base + size > MAX_PHYS_ADDR) {
+		pr_info("NUMA: Ignoring memory range 0x%lx - 0x%llx\n",
+				ULONG_MAX, base + size);
+		size = MAX_PHYS_ADDR - base;
+	}
+
+	if (base + size < phys_offset) {
+		pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
+			   base, base + size);
+		return -ENOMEM;
+	}
+	if (base < phys_offset) {
+		pr_info("NUMA: Ignoring memory range 0x%llx - 0x%llx\n",
+			   base, phys_offset);
+		size -= phys_offset - base;
+		base = phys_offset;
+	}
+
+	return numa_add_memblk_to(nid, base, base+size, &numa_meminfo);
+}
+EXPORT_SYMBOL(numa_add_memblk);
+
+/* Initialize NODE_DATA for a node on the local memory */
+static void __init setup_node_data(int nid, u64 start, u64 end)
+{
+	const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
+	u64 nd_pa;
+	void *nd;
+	int tnid;
+
+	start = roundup(start, ZONE_ALIGN);
+
+	pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
+	       nid, start, end - 1);
+
+	/*
+	 * Allocate node data.  Try node-local memory and then any node.
+	 */
+	nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid);
+	if (!nd_pa) {
+		nd_pa = __memblock_alloc_base(nd_size, SMP_CACHE_BYTES,
+					      MEMBLOCK_ALLOC_ACCESSIBLE);
+		if (!nd_pa) {
+			pr_err("Cannot find %zu bytes in node %d\n",
+			       nd_size, nid);
+			return;
+		}
+	}
+	nd = __va(nd_pa);
+
+	/* report and initialize */
+	pr_info("  NODE_DATA [mem %#010Lx-%#010Lx]\n",
+	       nd_pa, nd_pa + nd_size - 1);
+	tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
+	if (tnid != nid)
+		pr_info("    NODE_DATA(%d) on node %d\n", nid, tnid);
+
+	node_data[nid] = nd;
+	memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
+	NODE_DATA(nid)->node_id = nid;
+	NODE_DATA(nid)->node_start_pfn = start >> PAGE_SHIFT;
+	NODE_DATA(nid)->node_spanned_pages = (end - start) >> PAGE_SHIFT;
+
+	node_set_online(nid);
+}
+
+/*
+ * Set nodes, which have memory in @mi, in *@nodemask.
+ */
+static void __init numa_nodemask_from_meminfo(nodemask_t *nodemask,
+					      const struct numa_meminfo *mi)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mi->blk); i++)
+		if (mi->blk[i].start != mi->blk[i].end &&
+		    mi->blk[i].nid != NUMA_NO_NODE)
+			node_set(mi->blk[i].nid, *nodemask);
+}
+
+/*
+ * Sanity check to catch more bad NUMA configurations (they are amazingly
+ * common).  Make sure the nodes cover all memory.
+ */
+static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
+{
+	u64 numaram, totalram;
+	int i;
+
+	numaram = 0;
+	for (i = 0; i < mi->nr_blks; i++) {
+		u64 s = mi->blk[i].start >> PAGE_SHIFT;
+		u64 e = mi->blk[i].end >> PAGE_SHIFT;
+
+		numaram += e - s;
+		numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e);
+		if ((s64)numaram < 0)
+			numaram = 0;
+	}
+
+	totalram = max_pfn - absent_pages_in_range(0, max_pfn);
+
+	/* We seem to lose 3 pages somewhere. Allow 1M of slack. */
+	if ((s64)(totalram - numaram) >= (1 << (20 - PAGE_SHIFT))) {
+		pr_err("NUMA: nodes only cover %lluMB of your %lluMB Total RAM. Not used.\n",
+		       (numaram << PAGE_SHIFT) >> 20,
+		       (totalram << PAGE_SHIFT) >> 20);
+		return false;
+	}
+	return true;
+}
+
+/**
+ * numa_reset_distance - Reset NUMA distance table
+ *
+ * The current table is freed.  The next numa_set_distance() call will
+ * create a new one.
+ */
+void __init numa_reset_distance(void)
+{
+	size_t size = numa_distance_cnt * numa_distance_cnt *
+		sizeof(numa_distance[0]);
+
+	/* numa_distance could be 1LU marking allocation failure, test cnt */
+	if (numa_distance_cnt)
+		memblock_free(__pa(numa_distance), size);
+	numa_distance_cnt = 0;
+	numa_distance = NULL;	/* enable table creation */
+}
+
+static int __init numa_alloc_distance(void)
+{
+	nodemask_t nodes_parsed;
+	size_t size;
+	int i, j, cnt = 0;
+	u64 phys;
+
+	/* size the new table and allocate it */
+	nodes_parsed = numa_nodes_parsed;
+	numa_nodemask_from_meminfo(&nodes_parsed, &numa_meminfo);
+
+	for_each_node_mask(i, nodes_parsed)
+		cnt = i;
+	cnt++;
+	size = cnt * cnt * sizeof(numa_distance[0]);
+
+	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
+				      size, PAGE_SIZE);
+	if (!phys) {
+		pr_warning("NUMA: Warning: can't allocate distance table!\n");
+		/* don't retry until explicitly reset */
+		numa_distance = (void *)1LU;
+		return -ENOMEM;
+	}
+	memblock_reserve(phys, size);
+
+	numa_distance = __va(phys);
+	numa_distance_cnt = cnt;
+
+	/* fill with the default distances */
+	for (i = 0; i < cnt; i++)
+		for (j = 0; j < cnt; j++)
+			numa_distance[i * cnt + j] = i == j ?
+				LOCAL_DISTANCE : REMOTE_DISTANCE;
+	pr_debug("NUMA: Initialized distance table, cnt=%d\n", cnt);
+
+	return 0;
+}
+
+/**
+ * numa_set_distance - Set NUMA distance from one NUMA to another
+ * @from: the 'from' node to set distance
+ * @to: the 'to'  node to set distance
+ * @distance: NUMA distance
+ *
+ * Set the distance from node @from to @to to @distance.  If distance table
+ * doesn't exist, one which is large enough to accommodate all the currently
+ * known nodes will be created.
+ *
+ * If such table cannot be allocated, a warning is printed and further
+ * calls are ignored until the distance table is reset with
+ * numa_reset_distance().
+ *
+ * If @from or @to is higher than the highest known node or lower than zero
+ * at the time of table creation or @distance doesn't make sense, the call
+ * is ignored.
+ * This is to allow simplification of specific NUMA config implementations.
+ */
+void __init numa_set_distance(int from, int to, int distance)
+{
+	if (!numa_distance && numa_alloc_distance() < 0)
+		return;
+
+	if (from >= numa_distance_cnt || to >= numa_distance_cnt ||
+			from < 0 || to < 0) {
+		pr_warn_once("NUMA: Warning: node ids are out of bound, from=%d to=%d distance=%d\n",
+			    from, to, distance);
+		return;
+	}
+
+	if ((u8)distance != distance ||
+	    (from == to && distance != LOCAL_DISTANCE)) {
+		pr_warn_once("NUMA: Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
+			     from, to, distance);
+		return;
+	}
+
+	numa_distance[from * numa_distance_cnt + to] = distance;
+}
+EXPORT_SYMBOL(numa_set_distance);
+
+int __node_distance(int from, int to)
+{
+	if (from >= numa_distance_cnt || to >= numa_distance_cnt)
+		return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
+	return numa_distance[from * numa_distance_cnt + to];
+}
+EXPORT_SYMBOL(__node_distance);
+
+static int __init numa_register_memblks(struct numa_meminfo *mi)
+{
+	unsigned long uninitialized_var(pfn_align);
+	int i, nid;
+
+	/* Account for nodes with cpus and no memory */
+	node_possible_map = numa_nodes_parsed;
+	numa_nodemask_from_meminfo(&node_possible_map, mi);
+	if (WARN_ON(nodes_empty(node_possible_map)))
+		return -EINVAL;
+
+	for (i = 0; i < mi->nr_blks; i++) {
+		struct numa_memblk *mb = &mi->blk[i];
+
+		memblock_set_node(mb->start, mb->end - mb->start,
+				  &memblock.memory, mb->nid);
+	}
+
+	/*
+	 * If sections array is gonna be used for pfn -> nid mapping, check
+	 * whether its granularity is fine enough.
+	 */
+#ifdef NODE_NOT_IN_PAGE_FLAGS
+	pfn_align = node_map_pfn_alignment();
+	if (pfn_align && pfn_align < PAGES_PER_SECTION) {
+		pr_warn("Node alignment %lluMB < min %lluMB, rejecting NUMA config\n",
+		       PFN_PHYS(pfn_align) >> 20,
+		       PFN_PHYS(PAGES_PER_SECTION) >> 20);
+		return -EINVAL;
+	}
+#endif
+	if (!numa_meminfo_cover_memory(mi))
+		return -EINVAL;
+
+	/* Finally register nodes. */
+	for_each_node_mask(nid, node_possible_map) {
+		u64 start = PFN_PHYS(max_pfn);
+		u64 end = 0;
+
+		for (i = 0; i < mi->nr_blks; i++) {
+			if (nid != mi->blk[i].nid)
+				continue;
+			start = min(mi->blk[i].start, start);
+			end = max(mi->blk[i].end, end);
+		}
+
+		if (start < end)
+			setup_node_data(nid, start, end);
+	}
+
+	/* Dump memblock with node info and return. */
+	memblock_dump_all();
+	return 0;
+}
+
+static int __init numa_init(int (*init_func)(void))
+{
+	int ret, i;
+
+	nodes_clear(numa_nodes_parsed);
+	nodes_clear(node_possible_map);
+	nodes_clear(node_online_map);
+
+	ret = init_func();
+	if (ret < 0)
+		return ret;
+
+	ret = numa_register_memblks(&numa_meminfo);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < nr_cpu_ids; i++)
+		numa_clear_node(i);
+
+	setup_node_to_cpumask_map();
+	return 0;
+}
+
+/**
+ * dummy_numa_init - Fallback dummy NUMA init
+ *
+ * Used if there's no underlying NUMA architecture, NUMA initialization
+ * fails, or NUMA is disabled on the command line.
+ *
+ * Must online at least one node and add memory blocks that cover all
+ * allowed memory.  This function must not fail.
+ */
+static int __init dummy_numa_init(void)
+{
+	pr_info("%s\n", "No NUMA configuration found");
+	pr_info("Faking a node at [mem %#018Lx-%#018Lx]\n",
+	       0LLU, PFN_PHYS(max_pfn) - 1);
+	node_set(0, numa_nodes_parsed);
+	numa_add_memblk(0, 0, PFN_PHYS(max_pfn));
+
+	return 0;
+}
+
+/**
+ * arm64_numa_init - Initialize NUMA
+ *
+ * Try each configured NUMA initialization method until one succeeds.  The
+ * last fallback is dummy single node config encomapssing whole memory and
+ * never fails.
+ */
+void __init arm64_numa_init(void)
+{
+	int (*init_func)(void) = NULL;
+
+	if (IS_ENABLED(CONFIG_ARM64_DT_NUMA))
+		init_func = arm64_dt_numa_init;
+
+	if (!numa_off && init_func) {
+		if (!numa_init(init_func))
+			return;
+	}
+
+	numa_init(dummy_numa_init);
+}
-- 
1.8.1.4

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

* [RFC PATCH v4 4/4] arm64:numa: adding numa support for arm64 platforms.
@ 2015-01-22 11:05   ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-01-22 11:05 UTC (permalink / raw)
  To: linux-arm-kernel

Adding numa support for arm64 based platforms.
Adding dt node pasring for numa topology using property arm,associativity.

Signed-off-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
---
 arch/arm64/Kconfig              |  32 +++
 arch/arm64/include/asm/mmzone.h |  32 +++
 arch/arm64/include/asm/numa.h   |  43 ++++
 arch/arm64/kernel/Makefile      |   1 +
 arch/arm64/kernel/dt_numa.c     | 302 +++++++++++++++++++++++
 arch/arm64/kernel/setup.c       |   8 +
 arch/arm64/kernel/smp.c         |   2 +
 arch/arm64/mm/Makefile          |   1 +
 arch/arm64/mm/init.c            |  34 ++-
 arch/arm64/mm/numa.c            | 522 ++++++++++++++++++++++++++++++++++++++++
 10 files changed, 971 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm64/include/asm/mmzone.h
 create mode 100644 arch/arm64/include/asm/numa.h
 create mode 100644 arch/arm64/kernel/dt_numa.c
 create mode 100644 arch/arm64/mm/numa.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 242419d..6d262b1 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -59,6 +59,7 @@ config ARM64
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_RCU_TABLE_FREE
 	select HAVE_SYSCALL_TRACEPOINTS
+	select HAVE_MEMBLOCK_NODE_MAP if NUMA
 	select IRQ_DOMAIN
 	select MODULES_USE_ELF_RELA
 	select NO_BOOTMEM
@@ -315,6 +316,37 @@ config HOTPLUG_CPU
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
 	  can be controlled through /sys/devices/system/cpu.
 
+# Common NUMA Features
+config NUMA
+	bool "Numa Memory Allocation and Scheduler Support"
+	depends on SMP
+	---help---
+	  Enable NUMA (Non Uniform Memory Access) support.
+
+	  The kernel will try to allocate memory used by a CPU on the
+	  local memory controller of the CPU and add some more
+	  NUMA awareness to the kernel.
+
+config ARM64_DT_NUMA
+	def_bool n
+	prompt "DT NUMA detection"
+	---help---
+	  Enable DT based numa.
+
+config NODES_SHIFT
+	int "Maximum NUMA Nodes (as a power of 2)"
+	range 1 10
+	default "2"
+	depends on NEED_MULTIPLE_NODES
+	---help---
+	  Specify the maximum number of NUMA Nodes available on the target
+	  system.  Increases memory reserved to accommodate various tables.
+
+config USE_PERCPU_NUMA_NODE_ID
+	def_bool y
+	depends on NUMA
+
+
 source kernel/Kconfig.preempt
 
 config HZ
diff --git a/arch/arm64/include/asm/mmzone.h b/arch/arm64/include/asm/mmzone.h
new file mode 100644
index 0000000..d27ee66
--- /dev/null
+++ b/arch/arm64/include/asm/mmzone.h
@@ -0,0 +1,32 @@
+#ifndef __ASM_ARM64_MMZONE_H_
+#define __ASM_ARM64_MMZONE_H_
+
+#ifdef CONFIG_NUMA
+
+#include <linux/mmdebug.h>
+#include <asm/smp.h>
+#include <linux/types.h>
+#include <asm/numa.h>
+
+extern struct pglist_data *node_data[];
+
+#define NODE_DATA(nid)		(node_data[nid])
+
+
+struct numa_memblk {
+	u64			start;
+	u64			end;
+	int			nid;
+};
+
+struct numa_meminfo {
+	int			nr_blks;
+	struct numa_memblk	blk[NR_NODE_MEMBLKS];
+};
+
+void __init numa_remove_memblk_from(int idx, struct numa_meminfo *mi);
+int __init numa_cleanup_meminfo(struct numa_meminfo *mi);
+void __init numa_reset_distance(void);
+
+#endif /* CONFIG_NUMA */
+#endif /* __ASM_ARM64_MMZONE_H_ */
diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h
new file mode 100644
index 0000000..8be5cb1
--- /dev/null
+++ b/arch/arm64/include/asm/numa.h
@@ -0,0 +1,43 @@
+#ifndef _ASM_ARM64_NUMA_H
+#define _ASM_ARM64_NUMA_H
+
+#include <linux/nodemask.h>
+#include <asm/topology.h>
+
+#ifdef CONFIG_NUMA
+
+#define NR_NODE_MEMBLKS		(MAX_NUMNODES * 2)
+#define ZONE_ALIGN (1UL << (MAX_ORDER + PAGE_SHIFT))
+
+/* currently, arm64 implements flat NUMA topology */
+#define parent_node(node)	(node)
+
+/* dummy definitions for pci functions */
+#define pcibus_to_node(node)	0
+#define cpumask_of_pcibus(bus)	0
+
+struct __node_cpu_hwid {
+	u32 node_id;    /* logical node containing this CPU */
+	u64 cpu_hwid;   /* MPIDR for this CPU */
+};
+
+const struct cpumask *cpumask_of_node(int node);
+/* Mappings between node number and cpus on that node. */
+extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+
+void __init arm64_numa_init(void);
+int __init numa_add_memblk(u32 nodeid, u64 start, u64 end);
+void numa_store_cpu_info(int cpu);
+void numa_set_node(int cpu, int node);
+void numa_clear_node(int cpu);
+void numa_add_cpu(int cpu);
+void numa_remove_cpu(int cpu);
+void __init numa_set_distance(int from, int to, int distance);
+int dt_get_cpu_node_id(int cpu);
+int __init arm64_dt_numa_init(void);
+#else	/* CONFIG_NUMA */
+static inline void arm64_numa_init(void);
+static inline void numa_store_cpu_info(int cpu)		{ }
+static inline void arm64_numa_init(void)		{ }
+#endif	/* CONFIG_NUMA */
+#endif	/* _ASM_ARM64_NUMA_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 5bd029b..39451df 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -31,6 +31,7 @@ arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
 arm64-obj-$(CONFIG_PCI)			+= pci.o
+arm64-obj-$(CONFIG_ARM64_DT_NUMA)	+= dt_numa.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/dt_numa.c b/arch/arm64/kernel/dt_numa.c
new file mode 100644
index 0000000..7c418e2
--- /dev/null
+++ b/arch/arm64/kernel/dt_numa.c
@@ -0,0 +1,302 @@
+/*
+ * DT NUMA Parsing support, based on the powerpc 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/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <asm/smp_plat.h>
+
+#define MAX_DISTANCE_REF_POINTS 8
+static int min_common_depth;
+static int distance_ref_points_depth;
+static const __be32 *distance_ref_points;
+static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS];
+static int default_nid;
+static int of_node_to_nid_single(struct device_node *device);
+static struct device_node *of_cpu_to_node(int cpu);
+extern nodemask_t numa_nodes_parsed __initdata;
+
+static void initialize_distance_lookup_table(int nid,
+		const __be32 *associativity)
+{
+	int i;
+
+	for (i = 0; i < distance_ref_points_depth; i++) {
+		const __be32 *entry;
+
+		entry = &associativity[be32_to_cpu(distance_ref_points[i])];
+		distance_lookup_table[nid][i] = of_read_number(entry, 1);
+	}
+}
+
+/* must hold reference to node during call */
+static const __be32 *of_get_associativity(struct device_node *dev)
+{
+	return of_get_property(dev, "arm,associativity", NULL);
+}
+
+/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
+ * info is found.
+ */
+static int associativity_to_nid(const __be32 *associativity)
+{
+	int nid = NUMA_NO_NODE;
+
+	if (min_common_depth == -1)
+		goto out;
+
+	if (of_read_number(associativity, 1) >= min_common_depth)
+		nid = of_read_number(&associativity[min_common_depth], 1);
+
+	/* set 0xffff as invalid node */
+	if (nid == 0xffff || nid >= MAX_NUMNODES)
+		nid = NUMA_NO_NODE;
+
+	if (nid != NUMA_NO_NODE)
+		initialize_distance_lookup_table(nid, associativity);
+out:
+	return nid;
+}
+
+/* Returns the nid associated with the given device tree node,
+ * or -1 if not found.
+ */
+static int of_node_to_nid_single(struct device_node *device)
+{
+	int nid = default_nid;
+	const __be32 *tmp;
+
+	tmp = of_get_associativity(device);
+	if (tmp)
+		nid = associativity_to_nid(tmp);
+	return nid;
+}
+
+/* Walk the device tree upwards, looking for an associativity id */
+int of_node_to_nid(struct device_node *device)
+{
+	struct device_node *tmp;
+	int nid = NUMA_NO_NODE;
+
+	of_node_get(device);
+	while (device) {
+		nid = of_node_to_nid_single(device);
+		if (nid != NUMA_NO_NODE)
+			break;
+
+		tmp = device;
+		device = of_get_parent(tmp);
+		of_node_put(tmp);
+	}
+	of_node_put(device);
+
+	return nid;
+}
+
+static int __init find_min_common_depth(unsigned long node)
+{
+	int depth;
+	const __be32 *numa_prop;
+	int nr_address_cells;
+
+	/*
+	 * This property is a set of 32-bit integers, each representing
+	 * an index into the arm,associativity nodes.
+	 *
+	 * With form 1 affinity the first integer is the most significant
+	 * NUMA boundary and the following are progressively less significant
+	 * boundaries. There can be more than one level of NUMA.
+	 */
+
+	distance_ref_points = of_get_flat_dt_prop(node,
+			"arm,associativity-reference-points",
+			&distance_ref_points_depth);
+	numa_prop = distance_ref_points;
+
+	if (numa_prop) {
+		nr_address_cells = dt_mem_next_cell(
+				OF_ROOT_NODE_ADDR_CELLS_DEFAULT, &numa_prop);
+		nr_address_cells = dt_mem_next_cell(
+				OF_ROOT_NODE_ADDR_CELLS_DEFAULT, &numa_prop);
+	}
+	if (!distance_ref_points) {
+		pr_debug("NUMA: arm,associativity-reference-points not found.\n");
+		goto err;
+	}
+
+	distance_ref_points_depth /= sizeof(__be32);
+
+	if (!distance_ref_points_depth) {
+		pr_err("NUMA: missing arm,associativity-reference-points\n");
+		goto err;
+	}
+	depth = of_read_number(distance_ref_points, 1);
+
+	/*
+	 * Warn and cap if the hardware supports more than
+	 * MAX_DISTANCE_REF_POINTS domains.
+	 */
+	if (distance_ref_points_depth > MAX_DISTANCE_REF_POINTS) {
+		pr_debug("NUMA: distance array capped at %d entries\n", MAX_DISTANCE_REF_POINTS);
+		distance_ref_points_depth = MAX_DISTANCE_REF_POINTS;
+	}
+
+	return depth;
+err:
+	return -1;
+}
+
+int dt_get_cpu_node_id(int cpu)
+{
+	struct device_node *dn = NULL;
+	int nid = default_nid;
+
+	dn =  of_cpu_to_node(cpu);
+	if (dn)
+		nid = of_node_to_nid_single(dn);
+	return nid;
+}
+
+static struct device_node *of_cpu_to_node(int cpu)
+{
+	struct device_node *dn = NULL;
+
+	while ((dn = of_find_node_by_type(dn, "cpu"))) {
+		const u32 *cell;
+		u64 hwid;
+
+		/*
+		 * A cpu node with missing "reg" property is
+		 * considered invalid to build a cpu_logical_map
+		 * entry.
+		 */
+		cell = of_get_property(dn, "reg", NULL);
+		if (!cell) {
+			pr_err("%s: missing reg property\n", dn->full_name);
+			return NULL;
+		}
+		hwid = of_read_number(cell, of_n_addr_cells(dn));
+
+		if (cpu_logical_map(cpu) == hwid)
+			return dn;
+	}
+	return NULL;
+}
+
+static int __init parse_memory_node(unsigned long node)
+{
+	const __be32 *reg, *endp, *associativity;
+	int length;
+	int nid = default_nid;
+
+	associativity = of_get_flat_dt_prop(node, "arm,associativity", &length);
+
+	if (associativity)
+		nid = associativity_to_nid(associativity);
+
+	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;
+		struct memblock_region *mblk;
+
+		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
+		size = dt_mem_next_cell(dt_root_size_cells, &reg);
+		pr_debug("NUMA-DT:  base = %llx , node = %u\n",
+				base, nid);
+		for_each_memblock(memory, mblk) {
+			if (mblk->base == base) {
+				node_set(nid, numa_nodes_parsed);
+				numa_add_memblk(nid, mblk->base, mblk->size);
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * early_init_dt_scan_numa_map - parse memory node and map nid to memory range.
+ */
+int __init early_init_dt_scan_numa_map(unsigned long node, const char *uname,
+				     int depth, void *data)
+{
+	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+
+	if (depth == 0) {
+		min_common_depth = find_min_common_depth(node);
+		if (min_common_depth < 0)
+			return min_common_depth;
+		pr_debug("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
+		return 0;
+	}
+
+	if (type) {
+		if (strcmp(type, "memory") == 0)
+			parse_memory_node(node);
+	}
+	return 0;
+}
+
+int dt_get_node_distance(int a, int b)
+{
+	int i;
+	int distance = LOCAL_DISTANCE;
+
+	for (i = 0; i < distance_ref_points_depth; i++) {
+		if (distance_lookup_table[a][i] == distance_lookup_table[b][i])
+			break;
+
+		/* Double the distance for each NUMA level */
+		distance *= 2;
+	}
+	return distance;
+}
+
+/* DT node mapping is done already early_init_dt_scan_memory */
+int __init arm64_dt_numa_init(void)
+{
+	int i;
+	u32 nodea, nodeb, distance, node_count = 0;
+
+	of_scan_flat_dt(early_init_dt_scan_numa_map, NULL);
+
+	for_each_node_mask(i, numa_nodes_parsed)
+		node_count = i;
+	node_count++;
+
+	for (nodea =  0; nodea < node_count; nodea++) {
+		for (nodeb = 0; nodeb < node_count; nodeb++) {
+			distance = dt_get_node_distance(nodea, nodeb);
+			numa_set_distance(nodea, nodeb, distance);
+		}
+	}
+	return 0;
+}
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 2437196..80b4a9e 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -425,6 +425,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;
@@ -461,7 +464,12 @@ static int c_show(struct seq_file *m, void *v)
 		 * "processor".  Give glibc what it expects.
 		 */
 #ifdef CONFIG_SMP
+	if (IS_ENABLED(CONFIG_NUMA)) {
+		seq_printf(m, "processor\t: %d", i);
+		seq_printf(m, " [nid: %d]\n", cpu_to_node(i));
+	} else {
 		seq_printf(m, "processor\t: %d\n", i);
+	}
 #endif
 	}
 
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index b06d1d9..1d1e86f 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -50,6 +50,7 @@
 #include <asm/sections.h>
 #include <asm/tlbflush.h>
 #include <asm/ptrace.h>
+#include <asm/numa.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/ipi.h>
@@ -123,6 +124,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 static void smp_store_cpu_info(unsigned int cpuid)
 {
 	store_cpu_topology(cpuid);
+	numa_store_cpu_info(cpuid);
 }
 
 /*
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index c56179e..c86e6de 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -3,3 +3,4 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
 				   ioremap.o mmap.o pgd.o mmu.o \
 				   context.o proc.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
+obj-$(CONFIG_NUMA)		+= numa.o
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 494297c..6fd6802 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -39,6 +39,7 @@
 #include <asm/setup.h>
 #include <asm/sizes.h>
 #include <asm/tlb.h>
+#include <asm/numa.h>
 
 #include "mm.h"
 
@@ -73,6 +74,20 @@ static phys_addr_t max_zone_dma_phys(void)
 	return min(offset + (1ULL << 32), memblock_end_of_DRAM());
 }
 
+#ifdef CONFIG_NUMA
+static void __init zone_sizes_init(unsigned long min, unsigned long max)
+{
+	unsigned long max_zone_pfns[MAX_NR_ZONES];
+
+	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+	if (IS_ENABLED(CONFIG_ZONE_DMA))
+		max_zone_pfns[ZONE_DMA] = PFN_DOWN(max_zone_dma_phys());
+	max_zone_pfns[ZONE_NORMAL] = max;
+
+	free_area_init_nodes(max_zone_pfns);
+}
+
+#else
 static void __init zone_sizes_init(unsigned long min, unsigned long max)
 {
 	struct memblock_region *reg;
@@ -111,6 +126,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 
 	free_area_init_node(0, zone_size, min, zhole_size);
 }
+#endif /* CONFIG_NUMA */
 
 #ifdef CONFIG_HAVE_ARCH_PFN_VALID
 int pfn_valid(unsigned long pfn)
@@ -128,10 +144,15 @@ static void arm64_memory_present(void)
 static void arm64_memory_present(void)
 {
 	struct memblock_region *reg;
+	int nid = 0;
 
-	for_each_memblock(memory, reg)
-		memory_present(0, memblock_region_memory_base_pfn(reg),
-			       memblock_region_memory_end_pfn(reg));
+	for_each_memblock(memory, reg) {
+#ifdef CONFIG_NUMA
+		nid = reg->nid;
+#endif
+		memory_present(nid, memblock_region_memory_base_pfn(reg),
+				memblock_region_memory_end_pfn(reg));
+	}
 }
 #endif
 
@@ -167,6 +188,10 @@ void __init bootmem_init(void)
 	min = PFN_UP(memblock_start_of_DRAM());
 	max = PFN_DOWN(memblock_end_of_DRAM());
 
+	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
+	max_pfn = max_low_pfn = max;
+
+	arm64_numa_init();
 	/*
 	 * Sparsemem tries to allocate bootmem in memory_present(), so must be
 	 * done after the fixed reservations.
@@ -175,9 +200,6 @@ void __init bootmem_init(void)
 
 	sparse_init();
 	zone_sizes_init(min, max);
-
-	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
-	max_pfn = max_low_pfn = max;
 }
 
 #ifndef CONFIG_SPARSEMEM_VMEMMAP
diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
new file mode 100644
index 0000000..da1d301
--- /dev/null
+++ b/arch/arm64/mm/numa.c
@@ -0,0 +1,522 @@
+/*
+ * 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/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/mmzone.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+#include <linux/topology.h>
+#include <linux/of.h>
+#include <asm/smp_plat.h>
+
+int __initdata numa_off;
+nodemask_t numa_nodes_parsed __initdata;
+static int numa_distance_cnt;
+static u8 *numa_distance;
+
+struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
+EXPORT_SYMBOL(node_data);
+
+static struct __node_cpu_hwid node_cpu_hwid[NR_CPUS];
+static struct numa_meminfo numa_meminfo;
+
+static __init int numa_setup(char *opt)
+{
+	if (!opt)
+		return -EINVAL;
+	if (!strncmp(opt, "off", 3)) {
+		pr_info("%s\n", "NUMA turned off");
+		numa_off = 1;
+	}
+	return 0;
+}
+early_param("numa", numa_setup);
+
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+EXPORT_SYMBOL(node_to_cpumask_map);
+
+/*
+ * Returns a pointer to the bitmask of CPUs on Node 'node'.
+ */
+const struct cpumask *cpumask_of_node(int node)
+{
+	if (node >= nr_node_ids) {
+		pr_warn("cpumask_of_node(%d): node > nr_node_ids(%d)\n",
+			node, nr_node_ids);
+		dump_stack();
+		return cpu_none_mask;
+	}
+	if (node_to_cpumask_map[node] == NULL) {
+		pr_warn("cpumask_of_node(%d): no node_to_cpumask_map!\n",
+			node);
+		dump_stack();
+		return cpu_online_mask;
+	}
+	return node_to_cpumask_map[node];
+}
+EXPORT_SYMBOL(cpumask_of_node);
+
+void numa_clear_node(int cpu)
+{
+	node_cpu_hwid[cpu].node_id = NUMA_NO_NODE;
+}
+
+/*
+ * Allocate node_to_cpumask_map based on number of available nodes
+ * Requires node_possible_map to be valid.
+ *
+ * Note: cpumask_of_node() is not valid until after this is done.
+ * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
+ */
+void __init setup_node_to_cpumask_map(void)
+{
+	unsigned int node;
+
+	/* setup nr_node_ids if not done yet */
+	if (nr_node_ids == MAX_NUMNODES)
+		setup_nr_node_ids();
+
+	/* allocate the map */
+	for (node = 0; node < nr_node_ids; node++)
+		alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
+
+	/* cpumask_of_node() will now work */
+	pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
+}
+
+/*
+ *  Set the cpu to node and mem mapping
+ */
+void numa_store_cpu_info(int cpu)
+{
+	if (IS_ENABLED(CONFIG_ARM64_DT_NUMA))
+		node_cpu_hwid[cpu].node_id  =  dt_get_cpu_node_id(cpu);
+	else
+		node_cpu_hwid[cpu].node_id  =  0;
+
+	/* mapping of MPIDR/hwid, node and logical cpu id */
+	node_cpu_hwid[cpu].cpu_hwid = cpu_logical_map(cpu);
+	cpumask_set_cpu(cpu, node_to_cpumask_map[node_cpu_hwid[cpu].node_id]);
+	set_numa_node(node_cpu_hwid[cpu].node_id);
+	set_numa_mem(local_memory_node(node_cpu_hwid[cpu].node_id));
+}
+
+/**
+ * numa_add_memblk_to - Add one numa_memblk to a numa_meminfo
+ */
+
+static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
+				     struct numa_meminfo *mi)
+{
+	/* ignore zero length blks */
+	if (start == end)
+		return 0;
+
+	/* whine about and ignore invalid blks */
+	if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
+		pr_warn("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
+				nid, start, end - 1);
+		return 0;
+	}
+
+	if (mi->nr_blks >= NR_NODE_MEMBLKS) {
+		pr_err("NUMA: too many memblk ranges\n");
+		return -EINVAL;
+	}
+
+	pr_info("NUMA: Adding memblock %d [0x%llx - 0x%llx] on node %d\n",
+			mi->nr_blks, start, end, nid);
+	mi->blk[mi->nr_blks].start = start;
+	mi->blk[mi->nr_blks].end = end;
+	mi->blk[mi->nr_blks].nid = nid;
+	mi->nr_blks++;
+	return 0;
+}
+
+/**
+ * numa_add_memblk - Add one numa_memblk to numa_meminfo
+ * @nid: NUMA node ID of the new memblk
+ * @start: Start address of the new memblk
+ * @end: End address of the new memblk
+ *
+ * Add a new memblk to the default numa_meminfo.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+#define MAX_PHYS_ADDR	((phys_addr_t)~0)
+
+int __init numa_add_memblk(u32 nid, u64 base, u64 size)
+{
+	const u64 phys_offset = __pa(PAGE_OFFSET);
+
+	base &= PAGE_MASK;
+	size &= PAGE_MASK;
+
+	if (base > MAX_PHYS_ADDR) {
+		pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
+				base, base + size);
+		return -ENOMEM;
+	}
+
+	if (base + size > MAX_PHYS_ADDR) {
+		pr_info("NUMA: Ignoring memory range 0x%lx - 0x%llx\n",
+				ULONG_MAX, base + size);
+		size = MAX_PHYS_ADDR - base;
+	}
+
+	if (base + size < phys_offset) {
+		pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
+			   base, base + size);
+		return -ENOMEM;
+	}
+	if (base < phys_offset) {
+		pr_info("NUMA: Ignoring memory range 0x%llx - 0x%llx\n",
+			   base, phys_offset);
+		size -= phys_offset - base;
+		base = phys_offset;
+	}
+
+	return numa_add_memblk_to(nid, base, base+size, &numa_meminfo);
+}
+EXPORT_SYMBOL(numa_add_memblk);
+
+/* Initialize NODE_DATA for a node on the local memory */
+static void __init setup_node_data(int nid, u64 start, u64 end)
+{
+	const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
+	u64 nd_pa;
+	void *nd;
+	int tnid;
+
+	start = roundup(start, ZONE_ALIGN);
+
+	pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
+	       nid, start, end - 1);
+
+	/*
+	 * Allocate node data.  Try node-local memory and then any node.
+	 */
+	nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid);
+	if (!nd_pa) {
+		nd_pa = __memblock_alloc_base(nd_size, SMP_CACHE_BYTES,
+					      MEMBLOCK_ALLOC_ACCESSIBLE);
+		if (!nd_pa) {
+			pr_err("Cannot find %zu bytes in node %d\n",
+			       nd_size, nid);
+			return;
+		}
+	}
+	nd = __va(nd_pa);
+
+	/* report and initialize */
+	pr_info("  NODE_DATA [mem %#010Lx-%#010Lx]\n",
+	       nd_pa, nd_pa + nd_size - 1);
+	tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
+	if (tnid != nid)
+		pr_info("    NODE_DATA(%d) on node %d\n", nid, tnid);
+
+	node_data[nid] = nd;
+	memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
+	NODE_DATA(nid)->node_id = nid;
+	NODE_DATA(nid)->node_start_pfn = start >> PAGE_SHIFT;
+	NODE_DATA(nid)->node_spanned_pages = (end - start) >> PAGE_SHIFT;
+
+	node_set_online(nid);
+}
+
+/*
+ * Set nodes, which have memory in @mi, in *@nodemask.
+ */
+static void __init numa_nodemask_from_meminfo(nodemask_t *nodemask,
+					      const struct numa_meminfo *mi)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mi->blk); i++)
+		if (mi->blk[i].start != mi->blk[i].end &&
+		    mi->blk[i].nid != NUMA_NO_NODE)
+			node_set(mi->blk[i].nid, *nodemask);
+}
+
+/*
+ * Sanity check to catch more bad NUMA configurations (they are amazingly
+ * common).  Make sure the nodes cover all memory.
+ */
+static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
+{
+	u64 numaram, totalram;
+	int i;
+
+	numaram = 0;
+	for (i = 0; i < mi->nr_blks; i++) {
+		u64 s = mi->blk[i].start >> PAGE_SHIFT;
+		u64 e = mi->blk[i].end >> PAGE_SHIFT;
+
+		numaram += e - s;
+		numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e);
+		if ((s64)numaram < 0)
+			numaram = 0;
+	}
+
+	totalram = max_pfn - absent_pages_in_range(0, max_pfn);
+
+	/* We seem to lose 3 pages somewhere. Allow 1M of slack. */
+	if ((s64)(totalram - numaram) >= (1 << (20 - PAGE_SHIFT))) {
+		pr_err("NUMA: nodes only cover %lluMB of your %lluMB Total RAM. Not used.\n",
+		       (numaram << PAGE_SHIFT) >> 20,
+		       (totalram << PAGE_SHIFT) >> 20);
+		return false;
+	}
+	return true;
+}
+
+/**
+ * numa_reset_distance - Reset NUMA distance table
+ *
+ * The current table is freed.  The next numa_set_distance() call will
+ * create a new one.
+ */
+void __init numa_reset_distance(void)
+{
+	size_t size = numa_distance_cnt * numa_distance_cnt *
+		sizeof(numa_distance[0]);
+
+	/* numa_distance could be 1LU marking allocation failure, test cnt */
+	if (numa_distance_cnt)
+		memblock_free(__pa(numa_distance), size);
+	numa_distance_cnt = 0;
+	numa_distance = NULL;	/* enable table creation */
+}
+
+static int __init numa_alloc_distance(void)
+{
+	nodemask_t nodes_parsed;
+	size_t size;
+	int i, j, cnt = 0;
+	u64 phys;
+
+	/* size the new table and allocate it */
+	nodes_parsed = numa_nodes_parsed;
+	numa_nodemask_from_meminfo(&nodes_parsed, &numa_meminfo);
+
+	for_each_node_mask(i, nodes_parsed)
+		cnt = i;
+	cnt++;
+	size = cnt * cnt * sizeof(numa_distance[0]);
+
+	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
+				      size, PAGE_SIZE);
+	if (!phys) {
+		pr_warning("NUMA: Warning: can't allocate distance table!\n");
+		/* don't retry until explicitly reset */
+		numa_distance = (void *)1LU;
+		return -ENOMEM;
+	}
+	memblock_reserve(phys, size);
+
+	numa_distance = __va(phys);
+	numa_distance_cnt = cnt;
+
+	/* fill with the default distances */
+	for (i = 0; i < cnt; i++)
+		for (j = 0; j < cnt; j++)
+			numa_distance[i * cnt + j] = i == j ?
+				LOCAL_DISTANCE : REMOTE_DISTANCE;
+	pr_debug("NUMA: Initialized distance table, cnt=%d\n", cnt);
+
+	return 0;
+}
+
+/**
+ * numa_set_distance - Set NUMA distance from one NUMA to another
+ * @from: the 'from' node to set distance
+ * @to: the 'to'  node to set distance
+ * @distance: NUMA distance
+ *
+ * Set the distance from node @from to @to to @distance.  If distance table
+ * doesn't exist, one which is large enough to accommodate all the currently
+ * known nodes will be created.
+ *
+ * If such table cannot be allocated, a warning is printed and further
+ * calls are ignored until the distance table is reset with
+ * numa_reset_distance().
+ *
+ * If @from or @to is higher than the highest known node or lower than zero
+ *@the time of table creation or @distance doesn't make sense, the call
+ * is ignored.
+ * This is to allow simplification of specific NUMA config implementations.
+ */
+void __init numa_set_distance(int from, int to, int distance)
+{
+	if (!numa_distance && numa_alloc_distance() < 0)
+		return;
+
+	if (from >= numa_distance_cnt || to >= numa_distance_cnt ||
+			from < 0 || to < 0) {
+		pr_warn_once("NUMA: Warning: node ids are out of bound, from=%d to=%d distance=%d\n",
+			    from, to, distance);
+		return;
+	}
+
+	if ((u8)distance != distance ||
+	    (from == to && distance != LOCAL_DISTANCE)) {
+		pr_warn_once("NUMA: Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
+			     from, to, distance);
+		return;
+	}
+
+	numa_distance[from * numa_distance_cnt + to] = distance;
+}
+EXPORT_SYMBOL(numa_set_distance);
+
+int __node_distance(int from, int to)
+{
+	if (from >= numa_distance_cnt || to >= numa_distance_cnt)
+		return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
+	return numa_distance[from * numa_distance_cnt + to];
+}
+EXPORT_SYMBOL(__node_distance);
+
+static int __init numa_register_memblks(struct numa_meminfo *mi)
+{
+	unsigned long uninitialized_var(pfn_align);
+	int i, nid;
+
+	/* Account for nodes with cpus and no memory */
+	node_possible_map = numa_nodes_parsed;
+	numa_nodemask_from_meminfo(&node_possible_map, mi);
+	if (WARN_ON(nodes_empty(node_possible_map)))
+		return -EINVAL;
+
+	for (i = 0; i < mi->nr_blks; i++) {
+		struct numa_memblk *mb = &mi->blk[i];
+
+		memblock_set_node(mb->start, mb->end - mb->start,
+				  &memblock.memory, mb->nid);
+	}
+
+	/*
+	 * If sections array is gonna be used for pfn -> nid mapping, check
+	 * whether its granularity is fine enough.
+	 */
+#ifdef NODE_NOT_IN_PAGE_FLAGS
+	pfn_align = node_map_pfn_alignment();
+	if (pfn_align && pfn_align < PAGES_PER_SECTION) {
+		pr_warn("Node alignment %lluMB < min %lluMB, rejecting NUMA config\n",
+		       PFN_PHYS(pfn_align) >> 20,
+		       PFN_PHYS(PAGES_PER_SECTION) >> 20);
+		return -EINVAL;
+	}
+#endif
+	if (!numa_meminfo_cover_memory(mi))
+		return -EINVAL;
+
+	/* Finally register nodes. */
+	for_each_node_mask(nid, node_possible_map) {
+		u64 start = PFN_PHYS(max_pfn);
+		u64 end = 0;
+
+		for (i = 0; i < mi->nr_blks; i++) {
+			if (nid != mi->blk[i].nid)
+				continue;
+			start = min(mi->blk[i].start, start);
+			end = max(mi->blk[i].end, end);
+		}
+
+		if (start < end)
+			setup_node_data(nid, start, end);
+	}
+
+	/* Dump memblock with node info and return. */
+	memblock_dump_all();
+	return 0;
+}
+
+static int __init numa_init(int (*init_func)(void))
+{
+	int ret, i;
+
+	nodes_clear(numa_nodes_parsed);
+	nodes_clear(node_possible_map);
+	nodes_clear(node_online_map);
+
+	ret = init_func();
+	if (ret < 0)
+		return ret;
+
+	ret = numa_register_memblks(&numa_meminfo);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < nr_cpu_ids; i++)
+		numa_clear_node(i);
+
+	setup_node_to_cpumask_map();
+	return 0;
+}
+
+/**
+ * dummy_numa_init - Fallback dummy NUMA init
+ *
+ * Used if there's no underlying NUMA architecture, NUMA initialization
+ * fails, or NUMA is disabled on the command line.
+ *
+ * Must online at least one node and add memory blocks that cover all
+ * allowed memory.  This function must not fail.
+ */
+static int __init dummy_numa_init(void)
+{
+	pr_info("%s\n", "No NUMA configuration found");
+	pr_info("Faking a node@[mem %#018Lx-%#018Lx]\n",
+	       0LLU, PFN_PHYS(max_pfn) - 1);
+	node_set(0, numa_nodes_parsed);
+	numa_add_memblk(0, 0, PFN_PHYS(max_pfn));
+
+	return 0;
+}
+
+/**
+ * arm64_numa_init - Initialize NUMA
+ *
+ * Try each configured NUMA initialization method until one succeeds.  The
+ * last fallback is dummy single node config encomapssing whole memory and
+ * never fails.
+ */
+void __init arm64_numa_init(void)
+{
+	int (*init_func)(void) = NULL;
+
+	if (IS_ENABLED(CONFIG_ARM64_DT_NUMA))
+		init_func = arm64_dt_numa_init;
+
+	if (!numa_off && init_func) {
+		if (!numa_init(init_func))
+			return;
+	}
+
+	numa_init(dummy_numa_init);
+}
-- 
1.8.1.4

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

* Re: [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
  2015-01-22 11:05     ` Ganapatrao Kulkarni
@ 2015-01-22 16:47         ` Arnd Bergmann
  -1 siblings, 0 replies; 36+ messages in thread
From: Arnd Bergmann @ 2015-01-22 16:47 UTC (permalink / raw)
  To: Ganapatrao Kulkarni
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Will.Deacon-5wv7dgnIgG8, catalin.marinas-5wv7dgnIgG8,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	roy.franz-QSEj5FYQhm4dnm+yROfE0A,
	ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	steve.capper-QSEj5FYQhm4dnm+yROfE0A,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
	jchandra-dY08KVG/lbpWk0Htik3J/w, al.stone-QSEj5FYQhm4dnm+yROfE0A,
	jcm-H+wXaHxf7aLQT0dZR+AlfA, ddutile-H+wXaHxf7aLQT0dZR+AlfA,
	gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w

On Thursday 22 January 2015 16:35:54 Ganapatrao Kulkarni wrote:
> +
> +		cpu@000 {
> +			device_type = "cpu";
> +			compatible = "cavium,thunder", "arm,armv8";
> +			reg = <0x0 0x000>;
> +			enable-method = "psci";
> +			/* socket 0, cluster 0, core 0*/
> +			arm,associativity = <0 0 0>;
> +		};
...
> +             cpu@20f {
> +                     device_type = "cpu";
> +                     compatible = "cavium,thunder", "arm,armv8";
> +                     reg = <0x0 0x20f>;
> +                     enable-method = "psci";
> +                     arm,associativity = <0 2 15>;
> +		};
> +		cpu@10000 {
> +			device_type = "cpu";
> +			compatible = "cavium,thunder", "arm,armv8";
> +			reg = <0x0 0x10000>;
> +			enable-method = "psci";
> +			/* socket 1, cluster 0, core 0*/
> +			arm,associativity = <1 0 0>;
> +		};

This seems wrong still: The clusters and cores do not have unique
numbers. I believe the code will not work correctly, and it won't
be compliant with the binding from patch 2.

I think the right way here would be to use 

	arm,associativity = <0 2 47>;

for cpu@20f, and

	arm,associativity = <1 3 48>;

for cpu@10000. Your previous version used the numbers from 
the reg property, which should be fine as well if that helps:


	arm,associativity = <0x0 0x200 0x20f>;

	arm,associativity = <0x10000 0x10000 0x10000>;

which should have the same effect as above, as long as the code
can handle the numbers not being consecutive.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
@ 2015-01-22 16:47         ` Arnd Bergmann
  0 siblings, 0 replies; 36+ messages in thread
From: Arnd Bergmann @ 2015-01-22 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 22 January 2015 16:35:54 Ganapatrao Kulkarni wrote:
> +
> +		cpu at 000 {
> +			device_type = "cpu";
> +			compatible = "cavium,thunder", "arm,armv8";
> +			reg = <0x0 0x000>;
> +			enable-method = "psci";
> +			/* socket 0, cluster 0, core 0*/
> +			arm,associativity = <0 0 0>;
> +		};
...
> +             cpu at 20f {
> +                     device_type = "cpu";
> +                     compatible = "cavium,thunder", "arm,armv8";
> +                     reg = <0x0 0x20f>;
> +                     enable-method = "psci";
> +                     arm,associativity = <0 2 15>;
> +		};
> +		cpu at 10000 {
> +			device_type = "cpu";
> +			compatible = "cavium,thunder", "arm,armv8";
> +			reg = <0x0 0x10000>;
> +			enable-method = "psci";
> +			/* socket 1, cluster 0, core 0*/
> +			arm,associativity = <1 0 0>;
> +		};

This seems wrong still: The clusters and cores do not have unique
numbers. I believe the code will not work correctly, and it won't
be compliant with the binding from patch 2.

I think the right way here would be to use 

	arm,associativity = <0 2 47>;

for cpu at 20f, and

	arm,associativity = <1 3 48>;

for cpu at 10000. Your previous version used the numbers from 
the reg property, which should be fine as well if that helps:


	arm,associativity = <0x0 0x200 0x20f>;

	arm,associativity = <0x10000 0x10000 0x10000>;

which should have the same effect as above, as long as the code
can handle the numbers not being consecutive.

	Arnd

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

* Re: [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
  2015-01-22 16:47         ` Arnd Bergmann
@ 2015-01-22 18:26           ` Arnd Bergmann
  -1 siblings, 0 replies; 36+ messages in thread
From: Arnd Bergmann @ 2015-01-22 18:26 UTC (permalink / raw)
  To: Ganapatrao Kulkarni
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Will.Deacon-5wv7dgnIgG8, catalin.marinas-5wv7dgnIgG8,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	roy.franz-QSEj5FYQhm4dnm+yROfE0A,
	ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	steve.capper-QSEj5FYQhm4dnm+yROfE0A,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
	jchandra-dY08KVG/lbpWk0Htik3J/w, al.stone-QSEj5FYQhm4dnm+yROfE0A,
	jcm-H+wXaHxf7aLQT0dZR+AlfA, ddutile-H+wXaHxf7aLQT0dZR+AlfA,
	gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w

On Thursday 22 January 2015 17:47:13 Arnd Bergmann wrote:
> 
> This seems wrong still: The clusters and cores do not have unique
> numbers. I believe the code will not work correctly, and it won't
> be compliant with the binding from patch 2.
> 
> I think the right way here would be to use 
> 
>         arm,associativity = <0 2 47>;
> 
> for cpu@20f, and
> 
>         arm,associativity = <1 3 48>;
> 
> for cpu@10000. Your previous version used the numbers from 
> the reg property, which should be fine as well if that helps:
> 
> 
>         arm,associativity = <0x0 0x200 0x20f>;
> 
>         arm,associativity = <0x10000 0x10000 0x10000>;
> 
> which should have the same effect as above, as long as the code
> can handle the numbers not being consecutive.
> 
> 

Upon further consideration, I think your patch is correct after
all, but let me check again on PowerPC machines.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
@ 2015-01-22 18:26           ` Arnd Bergmann
  0 siblings, 0 replies; 36+ messages in thread
From: Arnd Bergmann @ 2015-01-22 18:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday 22 January 2015 17:47:13 Arnd Bergmann wrote:
> 
> This seems wrong still: The clusters and cores do not have unique
> numbers. I believe the code will not work correctly, and it won't
> be compliant with the binding from patch 2.
> 
> I think the right way here would be to use 
> 
>         arm,associativity = <0 2 47>;
> 
> for cpu at 20f, and
> 
>         arm,associativity = <1 3 48>;
> 
> for cpu at 10000. Your previous version used the numbers from 
> the reg property, which should be fine as well if that helps:
> 
> 
>         arm,associativity = <0x0 0x200 0x20f>;
> 
>         arm,associativity = <0x10000 0x10000 0x10000>;
> 
> which should have the same effect as above, as long as the code
> can handle the numbers not being consecutive.
> 
> 

Upon further consideration, I think your patch is correct after
all, but let me check again on PowerPC machines.

	Arnd

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

* Re: [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
  2015-01-22 18:26           ` Arnd Bergmann
@ 2015-01-23 12:37             ` Ganapatrao Kulkarni
  -1 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-01-23 12:37 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Ganapatrao Kulkarni,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Will Deacon,
	Catalin Marinas, Grant Likely, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Leif Lindholm, Roy Franz, Ard Biesheuvel,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, Rob Herring, Steve Capper,
	Hanjun Guo, jchandra-dY08KVG/lbpWk0Htik3J/w, Al Stone,
	jcm-H+wXaHxf7aLQT0dZR+AlfA, ddutile-H+wXaHxf7aLQT0dZR+AlfA

Hi Arnd,

On Thu, Jan 22, 2015 at 11:56 PM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Thursday 22 January 2015 17:47:13 Arnd Bergmann wrote:
>>
>> This seems wrong still: The clusters and cores do not have unique
>> numbers. I believe the code will not work correctly, and it won't
>> be compliant with the binding from patch 2.
>>
>> I think the right way here would be to use
>>
>>         arm,associativity = <0 2 47>;
>>
>> for cpu@20f, and
>>
>>         arm,associativity = <1 3 48>;
>>
>> for cpu@10000. Your previous version used the numbers from
>> the reg property, which should be fine as well if that helps:
>>
>>
>>         arm,associativity = <0x0 0x200 0x20f>;
>>
>>         arm,associativity = <0x10000 0x10000 0x10000>;
>>
>> which should have the same effect as above, as long as the code
>> can handle the numbers not being consecutive.
>>
>>
>
> Upon further consideration, I think your patch is correct after
> all, but let me check again on PowerPC machines.
i have removed, board id which was in previous patch, to keep the
associativity aligned to mpidr, ie. socket,cluster id and core id.
both previous and current mappings holds good for our design.
our topology is 2 sockets(aff2=0and 1) , each having 3
clusters(aff1=0to2)and each cluster having 16 cores(aff0:0to15)
in associativity property, for our case, only first id(socket id) is
mapped to numa, others are mentioned only to describe the topology.
>
>         Arnd
thanks
Ganapat
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
@ 2015-01-23 12:37             ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-01-23 12:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

On Thu, Jan 22, 2015 at 11:56 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 22 January 2015 17:47:13 Arnd Bergmann wrote:
>>
>> This seems wrong still: The clusters and cores do not have unique
>> numbers. I believe the code will not work correctly, and it won't
>> be compliant with the binding from patch 2.
>>
>> I think the right way here would be to use
>>
>>         arm,associativity = <0 2 47>;
>>
>> for cpu at 20f, and
>>
>>         arm,associativity = <1 3 48>;
>>
>> for cpu at 10000. Your previous version used the numbers from
>> the reg property, which should be fine as well if that helps:
>>
>>
>>         arm,associativity = <0x0 0x200 0x20f>;
>>
>>         arm,associativity = <0x10000 0x10000 0x10000>;
>>
>> which should have the same effect as above, as long as the code
>> can handle the numbers not being consecutive.
>>
>>
>
> Upon further consideration, I think your patch is correct after
> all, but let me check again on PowerPC machines.
i have removed, board id which was in previous patch, to keep the
associativity aligned to mpidr, ie. socket,cluster id and core id.
both previous and current mappings holds good for our design.
our topology is 2 sockets(aff2=0and 1) , each having 3
clusters(aff1=0to2)and each cluster having 16 cores(aff0:0to15)
in associativity property, for our case, only first id(socket id) is
mapped to numa, others are mentioned only to describe the topology.
>
>         Arnd
thanks
Ganapat

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

* Re: [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
  2015-01-23 12:37             ` Ganapatrao Kulkarni
@ 2015-02-24  8:52                 ` Ganapatrao Kulkarni
  -1 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-02-24  8:52 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Ganapatrao Kulkarni,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Will Deacon,
	Catalin Marinas, Grant Likely, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Leif Lindholm, Roy Franz, Ard Biesheuvel,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, Rob Herring, Steve Capper,
	Hanjun Guo, jchandra-dY08KVG/lbpWk0Htik3J/w, Al Stone,
	jcm-H+wXaHxf7aLQT0dZR+AlfA, ddutile-H+wXaHxf7aLQT0dZR+AlfA

Hi Arnd,

On Fri, Jan 23, 2015 at 6:07 PM, Ganapatrao Kulkarni
<gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Hi Arnd,
>
> On Thu, Jan 22, 2015 at 11:56 PM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
>> On Thursday 22 January 2015 17:47:13 Arnd Bergmann wrote:
>>>
>>> This seems wrong still: The clusters and cores do not have unique
>>> numbers. I believe the code will not work correctly, and it won't
>>> be compliant with the binding from patch 2.
>>>
>>> I think the right way here would be to use
>>>
>>>         arm,associativity = <0 2 47>;
>>>
>>> for cpu@20f, and
>>>
>>>         arm,associativity = <1 3 48>;
>>>
>>> for cpu@10000. Your previous version used the numbers from
>>> the reg property, which should be fine as well if that helps:
>>>
>>>
>>>         arm,associativity = <0x0 0x200 0x20f>;
>>>
>>>         arm,associativity = <0x10000 0x10000 0x10000>;
>>>
>>> which should have the same effect as above, as long as the code
>>> can handle the numbers not being consecutive.
>>>
>>>
>>
>> Upon further consideration, I think your patch is correct after
>> all, but let me check again on PowerPC machines.
> i have removed, board id which was in previous patch, to keep the
> associativity aligned to mpidr, ie. socket,cluster id and core id.
> both previous and current mappings holds good for our design.
> our topology is 2 sockets(aff2=0and 1) , each having 3
> clusters(aff1=0to2)and each cluster having 16 cores(aff0:0to15)
> in associativity property, for our case, only first id(socket id) is
> mapped to numa, others are mentioned only to describe the topology.
>>
>>         Arnd
any further comments, how we go about these patches?
please suggest.

> thanks
> Ganapat

thanks
Ganapat
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
@ 2015-02-24  8:52                 ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-02-24  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

On Fri, Jan 23, 2015 at 6:07 PM, Ganapatrao Kulkarni
<gpkulkarni@gmail.com> wrote:
> Hi Arnd,
>
> On Thu, Jan 22, 2015 at 11:56 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Thursday 22 January 2015 17:47:13 Arnd Bergmann wrote:
>>>
>>> This seems wrong still: The clusters and cores do not have unique
>>> numbers. I believe the code will not work correctly, and it won't
>>> be compliant with the binding from patch 2.
>>>
>>> I think the right way here would be to use
>>>
>>>         arm,associativity = <0 2 47>;
>>>
>>> for cpu at 20f, and
>>>
>>>         arm,associativity = <1 3 48>;
>>>
>>> for cpu at 10000. Your previous version used the numbers from
>>> the reg property, which should be fine as well if that helps:
>>>
>>>
>>>         arm,associativity = <0x0 0x200 0x20f>;
>>>
>>>         arm,associativity = <0x10000 0x10000 0x10000>;
>>>
>>> which should have the same effect as above, as long as the code
>>> can handle the numbers not being consecutive.
>>>
>>>
>>
>> Upon further consideration, I think your patch is correct after
>> all, but let me check again on PowerPC machines.
> i have removed, board id which was in previous patch, to keep the
> associativity aligned to mpidr, ie. socket,cluster id and core id.
> both previous and current mappings holds good for our design.
> our topology is 2 sockets(aff2=0and 1) , each having 3
> clusters(aff1=0to2)and each cluster having 16 cores(aff0:0to15)
> in associativity property, for our case, only first id(socket id) is
> mapped to numa, others are mentioned only to describe the topology.
>>
>>         Arnd
any further comments, how we go about these patches?
please suggest.

> thanks
> Ganapat

thanks
Ganapat

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

* Re: [RFC PATCH v4 4/4] arm64:numa: adding numa support for arm64 platforms.
  2015-01-22 11:05   ` Ganapatrao Kulkarni
@ 2015-02-27  9:08       ` Hanjun Guo
  -1 siblings, 0 replies; 36+ messages in thread
From: Hanjun Guo @ 2015-02-27  9:08 UTC (permalink / raw)
  To: Ganapatrao Kulkarni,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Will.Deacon-5wv7dgnIgG8, catalin.marinas-5wv7dgnIgG8,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	leif.lindholm-QSEj5FYQhm4dnm+yROfE0A,
	roy.franz-QSEj5FYQhm4dnm+yROfE0A,
	ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	steve.capper-QSEj5FYQhm4dnm+yROfE0A,
	jchandra-dY08KVG/lbpWk0Htik3J/w, al.stone-QSEj5FYQhm4dnm+yROfE0A,
	arnd-r2nGTMty4D4, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	ddutile-H+wXaHxf7aLQT0dZR+AlfA
  Cc: gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w

Hi Ganapatrao,

On 2015年01月22日 19:05, Ganapatrao Kulkarni wrote:
> Adding numa support for arm64 based platforms.
> Adding dt node pasring for numa topology using property arm,associativity.
>
> Signed-off-by: Ganapatrao Kulkarni <gkulkarni-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>
> ---
>   arch/arm64/Kconfig              |  32 +++
>   arch/arm64/include/asm/mmzone.h |  32 +++
>   arch/arm64/include/asm/numa.h   |  43 ++++
>   arch/arm64/kernel/Makefile      |   1 +
>   arch/arm64/kernel/dt_numa.c     | 302 +++++++++++++++++++++++
>   arch/arm64/kernel/setup.c       |   8 +
>   arch/arm64/kernel/smp.c         |   2 +
>   arch/arm64/mm/Makefile          |   1 +
>   arch/arm64/mm/init.c            |  34 ++-
>   arch/arm64/mm/numa.c            | 522 ++++++++++++++++++++++++++++++++++++++++
>   10 files changed, 971 insertions(+), 6 deletions(-)
>   create mode 100644 arch/arm64/include/asm/mmzone.h
>   create mode 100644 arch/arm64/include/asm/numa.h
>   create mode 100644 arch/arm64/kernel/dt_numa.c
>   create mode 100644 arch/arm64/mm/numa.c
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 242419d..6d262b1 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -59,6 +59,7 @@ config ARM64
>   	select HAVE_PERF_USER_STACK_DUMP
>   	select HAVE_RCU_TABLE_FREE
>   	select HAVE_SYSCALL_TRACEPOINTS
> +	select HAVE_MEMBLOCK_NODE_MAP if NUMA
>   	select IRQ_DOMAIN
>   	select MODULES_USE_ELF_RELA
>   	select NO_BOOTMEM
> @@ -315,6 +316,37 @@ config HOTPLUG_CPU
>   	  Say Y here to experiment with turning CPUs off and on.  CPUs
>   	  can be controlled through /sys/devices/system/cpu.
>
> +# Common NUMA Features
> +config NUMA
> +	bool "Numa Memory Allocation and Scheduler Support"
> +	depends on SMP
> +	---help---
> +	  Enable NUMA (Non Uniform Memory Access) support.
> +
> +	  The kernel will try to allocate memory used by a CPU on the
> +	  local memory controller of the CPU and add some more
> +	  NUMA awareness to the kernel.
> +
> +config ARM64_DT_NUMA
> +	def_bool n
> +	prompt "DT NUMA detection"
> +	---help---
> +	  Enable DT based numa.
> +
> +config NODES_SHIFT
> +	int "Maximum NUMA Nodes (as a power of 2)"
> +	range 1 10
> +	default "2"
> +	depends on NEED_MULTIPLE_NODES
> +	---help---
> +	  Specify the maximum number of NUMA Nodes available on the target
> +	  system.  Increases memory reserved to accommodate various tables.
> +
> +config USE_PERCPU_NUMA_NODE_ID
> +	def_bool y
> +	depends on NUMA
> +
> +
>   source kernel/Kconfig.preempt
>
>   config HZ
> diff --git a/arch/arm64/include/asm/mmzone.h b/arch/arm64/include/asm/mmzone.h
> new file mode 100644
> index 0000000..d27ee66
> --- /dev/null
> +++ b/arch/arm64/include/asm/mmzone.h
> @@ -0,0 +1,32 @@
> +#ifndef __ASM_ARM64_MMZONE_H_
> +#define __ASM_ARM64_MMZONE_H_
> +
> +#ifdef CONFIG_NUMA
> +
> +#include <linux/mmdebug.h>
> +#include <asm/smp.h>
> +#include <linux/types.h>
> +#include <asm/numa.h>
> +
> +extern struct pglist_data *node_data[];
> +
> +#define NODE_DATA(nid)		(node_data[nid])
> +
> +
> +struct numa_memblk {
> +	u64			start;
> +	u64			end;
> +	int			nid;
> +};
> +
> +struct numa_meminfo {
> +	int			nr_blks;
> +	struct numa_memblk	blk[NR_NODE_MEMBLKS];
> +};
> +
> +void __init numa_remove_memblk_from(int idx, struct numa_meminfo *mi);
> +int __init numa_cleanup_meminfo(struct numa_meminfo *mi);
> +void __init numa_reset_distance(void);
> +
> +#endif /* CONFIG_NUMA */
> +#endif /* __ASM_ARM64_MMZONE_H_ */
> diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h
> new file mode 100644
> index 0000000..8be5cb1
> --- /dev/null
> +++ b/arch/arm64/include/asm/numa.h
> @@ -0,0 +1,43 @@
> +#ifndef _ASM_ARM64_NUMA_H
> +#define _ASM_ARM64_NUMA_H

Use _ASM_NUMA_H please.

> +
> +#include <linux/nodemask.h>
> +#include <asm/topology.h>
> +
> +#ifdef CONFIG_NUMA
> +
> +#define NR_NODE_MEMBLKS		(MAX_NUMNODES * 2)
> +#define ZONE_ALIGN (1UL << (MAX_ORDER + PAGE_SHIFT))
> +
> +/* currently, arm64 implements flat NUMA topology */
> +#define parent_node(node)	(node)
> +
> +/* dummy definitions for pci functions */
> +#define pcibus_to_node(node)	0
> +#define cpumask_of_pcibus(bus)	0
> +
> +struct __node_cpu_hwid {
> +	u32 node_id;    /* logical node containing this CPU */
> +	u64 cpu_hwid;   /* MPIDR for this CPU */
> +};
> +
> +const struct cpumask *cpumask_of_node(int node);
> +/* Mappings between node number and cpus on that node. */
> +extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
> +
> +void __init arm64_numa_init(void);
> +int __init numa_add_memblk(u32 nodeid, u64 start, u64 end);
> +void numa_store_cpu_info(int cpu);
> +void numa_set_node(int cpu, int node);
> +void numa_clear_node(int cpu);
> +void numa_add_cpu(int cpu);
> +void numa_remove_cpu(int cpu);
> +void __init numa_set_distance(int from, int to, int distance);
> +int dt_get_cpu_node_id(int cpu);
> +int __init arm64_dt_numa_init(void);

Do we really need all those function declared here?

> +#else	/* CONFIG_NUMA */
> +static inline void arm64_numa_init(void);

Compile error when !CONFIG_NUMA, should be

static inline void arm64_numa_init(void) { }

> +static inline void numa_store_cpu_info(int cpu)		{ }
> +static inline void arm64_numa_init(void)		{ }

duplicate one.

> +#endif	/* CONFIG_NUMA */
> +#endif	/* _ASM_ARM64_NUMA_H */
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index 5bd029b..39451df 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -31,6 +31,7 @@ arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
>   arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
>   arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
>   arm64-obj-$(CONFIG_PCI)			+= pci.o
> +arm64-obj-$(CONFIG_ARM64_DT_NUMA)	+= dt_numa.o
>
>   obj-y					+= $(arm64-obj-y) vdso/
>   obj-m					+= $(arm64-obj-m)
> diff --git a/arch/arm64/kernel/dt_numa.c b/arch/arm64/kernel/dt_numa.c
> new file mode 100644
> index 0000000..7c418e2
> --- /dev/null
> +++ b/arch/arm64/kernel/dt_numa.c
> @@ -0,0 +1,302 @@
> +/*
> + * DT NUMA Parsing support, based on the powerpc implementation.
> + *
> + * Copyright (C) 2015 Cavium Inc.
> + * Author: Ganapatrao Kulkarni <gkulkarni-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/string.h>
> +#include <linux/init.h>
> +#include <linux/bootmem.h>
> +#include <linux/memblock.h>
> +#include <linux/ctype.h>
> +#include <linux/module.h>
> +#include <linux/nodemask.h>
> +#include <linux/sched.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <asm/smp_plat.h>
> +
> +#define MAX_DISTANCE_REF_POINTS 8
> +static int min_common_depth;
> +static int distance_ref_points_depth;
> +static const __be32 *distance_ref_points;
> +static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS];
> +static int default_nid;
> +static int of_node_to_nid_single(struct device_node *device);
> +static struct device_node *of_cpu_to_node(int cpu);
> +extern nodemask_t numa_nodes_parsed __initdata;
> +
> +static void initialize_distance_lookup_table(int nid,
> +		const __be32 *associativity)
> +{
> +	int i;
> +
> +	for (i = 0; i < distance_ref_points_depth; i++) {
> +		const __be32 *entry;
> +
> +		entry = &associativity[be32_to_cpu(distance_ref_points[i])];
> +		distance_lookup_table[nid][i] = of_read_number(entry, 1);
> +	}
> +}
> +
> +/* must hold reference to node during call */
> +static const __be32 *of_get_associativity(struct device_node *dev)
> +{
> +	return of_get_property(dev, "arm,associativity", NULL);
> +}
> +
> +/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
> + * info is found.
> + */
> +static int associativity_to_nid(const __be32 *associativity)
> +{
> +	int nid = NUMA_NO_NODE;
> +
> +	if (min_common_depth == -1)
> +		goto out;
> +
> +	if (of_read_number(associativity, 1) >= min_common_depth)
> +		nid = of_read_number(&associativity[min_common_depth], 1);
> +
> +	/* set 0xffff as invalid node */
> +	if (nid == 0xffff || nid >= MAX_NUMNODES)
> +		nid = NUMA_NO_NODE;
> +
> +	if (nid != NUMA_NO_NODE)
> +		initialize_distance_lookup_table(nid, associativity);
> +out:
> +	return nid;
> +}
> +
> +/* Returns the nid associated with the given device tree node,
> + * or -1 if not found.
> + */
> +static int of_node_to_nid_single(struct device_node *device)
> +{
> +	int nid = default_nid;
> +	const __be32 *tmp;
> +
> +	tmp = of_get_associativity(device);
> +	if (tmp)
> +		nid = associativity_to_nid(tmp);
> +	return nid;
> +}
> +
> +/* Walk the device tree upwards, looking for an associativity id */
> +int of_node_to_nid(struct device_node *device)
> +{
> +	struct device_node *tmp;
> +	int nid = NUMA_NO_NODE;
> +
> +	of_node_get(device);
> +	while (device) {
> +		nid = of_node_to_nid_single(device);
> +		if (nid != NUMA_NO_NODE)
> +			break;
> +
> +		tmp = device;
> +		device = of_get_parent(tmp);
> +		of_node_put(tmp);
> +	}
> +	of_node_put(device);
> +
> +	return nid;
> +}
> +
> +static int __init find_min_common_depth(unsigned long node)
> +{
> +	int depth;
> +	const __be32 *numa_prop;
> +	int nr_address_cells;
> +
> +	/*
> +	 * This property is a set of 32-bit integers, each representing
> +	 * an index into the arm,associativity nodes.
> +	 *
> +	 * With form 1 affinity the first integer is the most significant
> +	 * NUMA boundary and the following are progressively less significant
> +	 * boundaries. There can be more than one level of NUMA.
> +	 */
> +
> +	distance_ref_points = of_get_flat_dt_prop(node,
> +			"arm,associativity-reference-points",
> +			&distance_ref_points_depth);
> +	numa_prop = distance_ref_points;
> +
> +	if (numa_prop) {
> +		nr_address_cells = dt_mem_next_cell(
> +				OF_ROOT_NODE_ADDR_CELLS_DEFAULT, &numa_prop);
> +		nr_address_cells = dt_mem_next_cell(
> +				OF_ROOT_NODE_ADDR_CELLS_DEFAULT, &numa_prop);
> +	}
> +	if (!distance_ref_points) {
> +		pr_debug("NUMA: arm,associativity-reference-points not found.\n");
> +		goto err;
> +	}
> +
> +	distance_ref_points_depth /= sizeof(__be32);
> +
> +	if (!distance_ref_points_depth) {
> +		pr_err("NUMA: missing arm,associativity-reference-points\n");
> +		goto err;
> +	}
> +	depth = of_read_number(distance_ref_points, 1);
> +
> +	/*
> +	 * Warn and cap if the hardware supports more than
> +	 * MAX_DISTANCE_REF_POINTS domains.
> +	 */
> +	if (distance_ref_points_depth > MAX_DISTANCE_REF_POINTS) {
> +		pr_debug("NUMA: distance array capped at %d entries\n", MAX_DISTANCE_REF_POINTS);
> +		distance_ref_points_depth = MAX_DISTANCE_REF_POINTS;
> +	}
> +
> +	return depth;
> +err:
> +	return -1;
> +}
> +
> +int dt_get_cpu_node_id(int cpu)
> +{
> +	struct device_node *dn = NULL;
> +	int nid = default_nid;
> +
> +	dn =  of_cpu_to_node(cpu);
> +	if (dn)
> +		nid = of_node_to_nid_single(dn);
> +	return nid;
> +}
> +
> +static struct device_node *of_cpu_to_node(int cpu)
> +{
> +	struct device_node *dn = NULL;
> +
> +	while ((dn = of_find_node_by_type(dn, "cpu"))) {
> +		const u32 *cell;
> +		u64 hwid;
> +
> +		/*
> +		 * A cpu node with missing "reg" property is
> +		 * considered invalid to build a cpu_logical_map
> +		 * entry.
> +		 */
> +		cell = of_get_property(dn, "reg", NULL);
> +		if (!cell) {
> +			pr_err("%s: missing reg property\n", dn->full_name);
> +			return NULL;
> +		}
> +		hwid = of_read_number(cell, of_n_addr_cells(dn));
> +
> +		if (cpu_logical_map(cpu) == hwid)
> +			return dn;
> +	}
> +	return NULL;
> +}
> +
> +static int __init parse_memory_node(unsigned long node)
> +{
> +	const __be32 *reg, *endp, *associativity;
> +	int length;
> +	int nid = default_nid;
> +
> +	associativity = of_get_flat_dt_prop(node, "arm,associativity", &length);
> +
> +	if (associativity)
> +		nid = associativity_to_nid(associativity);
> +
> +	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;
> +		struct memblock_region *mblk;
> +
> +		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
> +		size = dt_mem_next_cell(dt_root_size_cells, &reg);
> +		pr_debug("NUMA-DT:  base = %llx , node = %u\n",
> +				base, nid);
> +		for_each_memblock(memory, mblk) {
> +			if (mblk->base == base) {
> +				node_set(nid, numa_nodes_parsed);
> +				numa_add_memblk(nid, mblk->base, mblk->size);
> +				break;
> +			}
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * early_init_dt_scan_numa_map - parse memory node and map nid to memory range.
> + */
> +int __init early_init_dt_scan_numa_map(unsigned long node, const char *uname,
> +				     int depth, void *data)
> +{
> +	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
> +
> +	if (depth == 0) {
> +		min_common_depth = find_min_common_depth(node);
> +		if (min_common_depth < 0)
> +			return min_common_depth;
> +		pr_debug("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
> +		return 0;
> +	}
> +
> +	if (type) {
> +		if (strcmp(type, "memory") == 0)
> +			parse_memory_node(node);
> +	}
> +	return 0;
> +}
> +
> +int dt_get_node_distance(int a, int b)
> +{
> +	int i;
> +	int distance = LOCAL_DISTANCE;
> +
> +	for (i = 0; i < distance_ref_points_depth; i++) {
> +		if (distance_lookup_table[a][i] == distance_lookup_table[b][i])
> +			break;
> +
> +		/* Double the distance for each NUMA level */
> +		distance *= 2;
> +	}
> +	return distance;
> +}
> +
> +/* DT node mapping is done already early_init_dt_scan_memory */
> +int __init arm64_dt_numa_init(void)
> +{
> +	int i;
> +	u32 nodea, nodeb, distance, node_count = 0;
> +
> +	of_scan_flat_dt(early_init_dt_scan_numa_map, NULL);
> +
> +	for_each_node_mask(i, numa_nodes_parsed)
> +		node_count = i;
> +	node_count++;
> +
> +	for (nodea =  0; nodea < node_count; nodea++) {
> +		for (nodeb = 0; nodeb < node_count; nodeb++) {
> +			distance = dt_get_node_distance(nodea, nodeb);
> +			numa_set_distance(nodea, nodeb, distance);
> +		}
> +	}
> +	return 0;
> +}
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 2437196..80b4a9e 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -425,6 +425,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;
> @@ -461,7 +464,12 @@ static int c_show(struct seq_file *m, void *v)
>   		 * "processor".  Give glibc what it expects.
>   		 */
>   #ifdef CONFIG_SMP
> +	if (IS_ENABLED(CONFIG_NUMA)) {
> +		seq_printf(m, "processor\t: %d", i);
> +		seq_printf(m, " [nid: %d]\n", cpu_to_node(i));
> +	} else {
>   		seq_printf(m, "processor\t: %d\n", i);
> +	}
>   #endif
>   	}
>
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index b06d1d9..1d1e86f 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -50,6 +50,7 @@
>   #include <asm/sections.h>
>   #include <asm/tlbflush.h>
>   #include <asm/ptrace.h>
> +#include <asm/numa.h>
>
>   #define CREATE_TRACE_POINTS
>   #include <trace/events/ipi.h>
> @@ -123,6 +124,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
>   static void smp_store_cpu_info(unsigned int cpuid)
>   {
>   	store_cpu_topology(cpuid);
> +	numa_store_cpu_info(cpuid);
>   }
>
>   /*
> diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
> index c56179e..c86e6de 100644
> --- a/arch/arm64/mm/Makefile
> +++ b/arch/arm64/mm/Makefile
> @@ -3,3 +3,4 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
>   				   ioremap.o mmap.o pgd.o mmu.o \
>   				   context.o proc.o pageattr.o
>   obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
> +obj-$(CONFIG_NUMA)		+= numa.o
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 494297c..6fd6802 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -39,6 +39,7 @@
>   #include <asm/setup.h>
>   #include <asm/sizes.h>
>   #include <asm/tlb.h>
> +#include <asm/numa.h>
>
>   #include "mm.h"
>
> @@ -73,6 +74,20 @@ static phys_addr_t max_zone_dma_phys(void)
>   	return min(offset + (1ULL << 32), memblock_end_of_DRAM());
>   }
>
> +#ifdef CONFIG_NUMA
> +static void __init zone_sizes_init(unsigned long min, unsigned long max)
> +{
> +	unsigned long max_zone_pfns[MAX_NR_ZONES];
> +
> +	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
> +	if (IS_ENABLED(CONFIG_ZONE_DMA))
> +		max_zone_pfns[ZONE_DMA] = PFN_DOWN(max_zone_dma_phys());
> +	max_zone_pfns[ZONE_NORMAL] = max;
> +
> +	free_area_init_nodes(max_zone_pfns);
> +}
> +
> +#else
>   static void __init zone_sizes_init(unsigned long min, unsigned long max)
>   {
>   	struct memblock_region *reg;
> @@ -111,6 +126,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
>
>   	free_area_init_node(0, zone_size, min, zhole_size);
>   }
> +#endif /* CONFIG_NUMA */
>
>   #ifdef CONFIG_HAVE_ARCH_PFN_VALID
>   int pfn_valid(unsigned long pfn)
> @@ -128,10 +144,15 @@ static void arm64_memory_present(void)
>   static void arm64_memory_present(void)
>   {
>   	struct memblock_region *reg;
> +	int nid = 0;
>
> -	for_each_memblock(memory, reg)
> -		memory_present(0, memblock_region_memory_base_pfn(reg),
> -			       memblock_region_memory_end_pfn(reg));
> +	for_each_memblock(memory, reg) {
> +#ifdef CONFIG_NUMA
> +		nid = reg->nid;
> +#endif
> +		memory_present(nid, memblock_region_memory_base_pfn(reg),
> +				memblock_region_memory_end_pfn(reg));
> +	}
>   }
>   #endif
>
> @@ -167,6 +188,10 @@ void __init bootmem_init(void)
>   	min = PFN_UP(memblock_start_of_DRAM());
>   	max = PFN_DOWN(memblock_end_of_DRAM());
>
> +	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
> +	max_pfn = max_low_pfn = max;
> +
> +	arm64_numa_init();
>   	/*
>   	 * Sparsemem tries to allocate bootmem in memory_present(), so must be
>   	 * done after the fixed reservations.
> @@ -175,9 +200,6 @@ void __init bootmem_init(void)
>
>   	sparse_init();
>   	zone_sizes_init(min, max);
> -
> -	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
> -	max_pfn = max_low_pfn = max;
>   }
>
>   #ifndef CONFIG_SPARSEMEM_VMEMMAP
> diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
> new file mode 100644
> index 0000000..da1d301
> --- /dev/null
> +++ b/arch/arm64/mm/numa.c
> @@ -0,0 +1,522 @@
> +/*
> + * NUMA support, based on the x86 implementation.
> + *
> + * Copyright (C) 2015 Cavium Inc.
> + * Author: Ganapatrao Kulkarni <gkulkarni-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/string.h>
> +#include <linux/init.h>
> +#include <linux/bootmem.h>
> +#include <linux/memblock.h>
> +#include <linux/mmzone.h>
> +#include <linux/ctype.h>
> +#include <linux/module.h>
> +#include <linux/nodemask.h>
> +#include <linux/sched.h>
> +#include <linux/topology.h>
> +#include <linux/of.h>
> +#include <asm/smp_plat.h>
> +
> +int __initdata numa_off;
> +nodemask_t numa_nodes_parsed __initdata;
> +static int numa_distance_cnt;
> +static u8 *numa_distance;
> +
> +struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
> +EXPORT_SYMBOL(node_data);
> +
> +static struct __node_cpu_hwid node_cpu_hwid[NR_CPUS];
> +static struct numa_meminfo numa_meminfo;
> +
> +static __init int numa_setup(char *opt)
> +{
> +	if (!opt)
> +		return -EINVAL;
> +	if (!strncmp(opt, "off", 3)) {
> +		pr_info("%s\n", "NUMA turned off");
> +		numa_off = 1;
> +	}
> +	return 0;
> +}
> +early_param("numa", numa_setup);
> +
> +cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
> +EXPORT_SYMBOL(node_to_cpumask_map);
> +
> +/*
> + * Returns a pointer to the bitmask of CPUs on Node 'node'.
> + */
> +const struct cpumask *cpumask_of_node(int node)
> +{
> +	if (node >= nr_node_ids) {
> +		pr_warn("cpumask_of_node(%d): node > nr_node_ids(%d)\n",
> +			node, nr_node_ids);
> +		dump_stack();
> +		return cpu_none_mask;
> +	}
> +	if (node_to_cpumask_map[node] == NULL) {
> +		pr_warn("cpumask_of_node(%d): no node_to_cpumask_map!\n",
> +			node);
> +		dump_stack();
> +		return cpu_online_mask;
> +	}
> +	return node_to_cpumask_map[node];
> +}
> +EXPORT_SYMBOL(cpumask_of_node);
> +
> +void numa_clear_node(int cpu)
> +{
> +	node_cpu_hwid[cpu].node_id = NUMA_NO_NODE;
> +}
> +
> +/*
> + * Allocate node_to_cpumask_map based on number of available nodes
> + * Requires node_possible_map to be valid.
> + *
> + * Note: cpumask_of_node() is not valid until after this is done.
> + * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
> + */
> +void __init setup_node_to_cpumask_map(void)
> +{
> +	unsigned int node;
> +
> +	/* setup nr_node_ids if not done yet */
> +	if (nr_node_ids == MAX_NUMNODES)
> +		setup_nr_node_ids();
> +
> +	/* allocate the map */
> +	for (node = 0; node < nr_node_ids; node++)
> +		alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
> +
> +	/* cpumask_of_node() will now work */
> +	pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
> +}
> +
> +/*
> + *  Set the cpu to node and mem mapping
> + */
> +void numa_store_cpu_info(int cpu)
> +{
> +	if (IS_ENABLED(CONFIG_ARM64_DT_NUMA))
> +		node_cpu_hwid[cpu].node_id  =  dt_get_cpu_node_id(cpu);
> +	else
> +		node_cpu_hwid[cpu].node_id  =  0;
> +
> +	/* mapping of MPIDR/hwid, node and logical cpu id */
> +	node_cpu_hwid[cpu].cpu_hwid = cpu_logical_map(cpu);
> +	cpumask_set_cpu(cpu, node_to_cpumask_map[node_cpu_hwid[cpu].node_id]);
> +	set_numa_node(node_cpu_hwid[cpu].node_id);
> +	set_numa_mem(local_memory_node(node_cpu_hwid[cpu].node_id));
> +}
> +
> +/**
> + * numa_add_memblk_to - Add one numa_memblk to a numa_meminfo
> + */
> +
> +static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
> +				     struct numa_meminfo *mi)
> +{
> +	/* ignore zero length blks */
> +	if (start == end)
> +		return 0;
> +
> +	/* whine about and ignore invalid blks */
> +	if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
> +		pr_warn("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
> +				nid, start, end - 1);
> +		return 0;
> +	}
> +
> +	if (mi->nr_blks >= NR_NODE_MEMBLKS) {
> +		pr_err("NUMA: too many memblk ranges\n");
> +		return -EINVAL;
> +	}
> +
> +	pr_info("NUMA: Adding memblock %d [0x%llx - 0x%llx] on node %d\n",
> +			mi->nr_blks, start, end, nid);
> +	mi->blk[mi->nr_blks].start = start;
> +	mi->blk[mi->nr_blks].end = end;
> +	mi->blk[mi->nr_blks].nid = nid;
> +	mi->nr_blks++;
> +	return 0;
> +}
> +
> +/**
> + * numa_add_memblk - Add one numa_memblk to numa_meminfo
> + * @nid: NUMA node ID of the new memblk
> + * @start: Start address of the new memblk
> + * @end: End address of the new memblk
> + *
> + * Add a new memblk to the default numa_meminfo.
> + *
> + * RETURNS:
> + * 0 on success, -errno on failure.
> + */
> +#define MAX_PHYS_ADDR	((phys_addr_t)~0)
> +
> +int __init numa_add_memblk(u32 nid, u64 base, u64 size)

In the comments, it says "@end: End address of the new memblk",
I think it's better to be consistent with other archs, just
use "end" instead of "size" here.

Thanks
Hanjun

> +{
> +	const u64 phys_offset = __pa(PAGE_OFFSET);
> +
> +	base &= PAGE_MASK;
> +	size &= PAGE_MASK;
> +
> +	if (base > MAX_PHYS_ADDR) {
> +		pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
> +				base, base + size);
> +		return -ENOMEM;
> +	}
> +
> +	if (base + size > MAX_PHYS_ADDR) {
> +		pr_info("NUMA: Ignoring memory range 0x%lx - 0x%llx\n",
> +				ULONG_MAX, base + size);
> +		size = MAX_PHYS_ADDR - base;
> +	}
> +
> +	if (base + size < phys_offset) {
> +		pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
> +			   base, base + size);
> +		return -ENOMEM;
> +	}
> +	if (base < phys_offset) {
> +		pr_info("NUMA: Ignoring memory range 0x%llx - 0x%llx\n",
> +			   base, phys_offset);
> +		size -= phys_offset - base;
> +		base = phys_offset;
> +	}
> +
> +	return numa_add_memblk_to(nid, base, base+size, &numa_meminfo);
> +}
> +EXPORT_SYMBOL(numa_add_memblk);
> +
> +/* Initialize NODE_DATA for a node on the local memory */
> +static void __init setup_node_data(int nid, u64 start, u64 end)
> +{
> +	const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
> +	u64 nd_pa;
> +	void *nd;
> +	int tnid;
> +
> +	start = roundup(start, ZONE_ALIGN);
> +
> +	pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
> +	       nid, start, end - 1);
> +
> +	/*
> +	 * Allocate node data.  Try node-local memory and then any node.
> +	 */
> +	nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid);
> +	if (!nd_pa) {
> +		nd_pa = __memblock_alloc_base(nd_size, SMP_CACHE_BYTES,
> +					      MEMBLOCK_ALLOC_ACCESSIBLE);
> +		if (!nd_pa) {
> +			pr_err("Cannot find %zu bytes in node %d\n",
> +			       nd_size, nid);
> +			return;
> +		}
> +	}
> +	nd = __va(nd_pa);
> +
> +	/* report and initialize */
> +	pr_info("  NODE_DATA [mem %#010Lx-%#010Lx]\n",
> +	       nd_pa, nd_pa + nd_size - 1);
> +	tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
> +	if (tnid != nid)
> +		pr_info("    NODE_DATA(%d) on node %d\n", nid, tnid);
> +
> +	node_data[nid] = nd;
> +	memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
> +	NODE_DATA(nid)->node_id = nid;
> +	NODE_DATA(nid)->node_start_pfn = start >> PAGE_SHIFT;
> +	NODE_DATA(nid)->node_spanned_pages = (end - start) >> PAGE_SHIFT;
> +
> +	node_set_online(nid);
> +}
> +
> +/*
> + * Set nodes, which have memory in @mi, in *@nodemask.
> + */
> +static void __init numa_nodemask_from_meminfo(nodemask_t *nodemask,
> +					      const struct numa_meminfo *mi)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(mi->blk); i++)
> +		if (mi->blk[i].start != mi->blk[i].end &&
> +		    mi->blk[i].nid != NUMA_NO_NODE)
> +			node_set(mi->blk[i].nid, *nodemask);
> +}
> +
> +/*
> + * Sanity check to catch more bad NUMA configurations (they are amazingly
> + * common).  Make sure the nodes cover all memory.
> + */
> +static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
> +{
> +	u64 numaram, totalram;
> +	int i;
> +
> +	numaram = 0;
> +	for (i = 0; i < mi->nr_blks; i++) {
> +		u64 s = mi->blk[i].start >> PAGE_SHIFT;
> +		u64 e = mi->blk[i].end >> PAGE_SHIFT;
> +
> +		numaram += e - s;
> +		numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e);
> +		if ((s64)numaram < 0)
> +			numaram = 0;
> +	}
> +
> +	totalram = max_pfn - absent_pages_in_range(0, max_pfn);
> +
> +	/* We seem to lose 3 pages somewhere. Allow 1M of slack. */
> +	if ((s64)(totalram - numaram) >= (1 << (20 - PAGE_SHIFT))) {
> +		pr_err("NUMA: nodes only cover %lluMB of your %lluMB Total RAM. Not used.\n",
> +		       (numaram << PAGE_SHIFT) >> 20,
> +		       (totalram << PAGE_SHIFT) >> 20);
> +		return false;
> +	}
> +	return true;
> +}
> +
> +/**
> + * numa_reset_distance - Reset NUMA distance table
> + *
> + * The current table is freed.  The next numa_set_distance() call will
> + * create a new one.
> + */
> +void __init numa_reset_distance(void)
> +{
> +	size_t size = numa_distance_cnt * numa_distance_cnt *
> +		sizeof(numa_distance[0]);
> +
> +	/* numa_distance could be 1LU marking allocation failure, test cnt */
> +	if (numa_distance_cnt)
> +		memblock_free(__pa(numa_distance), size);
> +	numa_distance_cnt = 0;
> +	numa_distance = NULL;	/* enable table creation */
> +}
> +
> +static int __init numa_alloc_distance(void)
> +{
> +	nodemask_t nodes_parsed;
> +	size_t size;
> +	int i, j, cnt = 0;
> +	u64 phys;
> +
> +	/* size the new table and allocate it */
> +	nodes_parsed = numa_nodes_parsed;
> +	numa_nodemask_from_meminfo(&nodes_parsed, &numa_meminfo);
> +
> +	for_each_node_mask(i, nodes_parsed)
> +		cnt = i;
> +	cnt++;
> +	size = cnt * cnt * sizeof(numa_distance[0]);
> +
> +	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
> +				      size, PAGE_SIZE);
> +	if (!phys) {
> +		pr_warning("NUMA: Warning: can't allocate distance table!\n");
> +		/* don't retry until explicitly reset */
> +		numa_distance = (void *)1LU;
> +		return -ENOMEM;
> +	}
> +	memblock_reserve(phys, size);
> +
> +	numa_distance = __va(phys);
> +	numa_distance_cnt = cnt;
> +
> +	/* fill with the default distances */
> +	for (i = 0; i < cnt; i++)
> +		for (j = 0; j < cnt; j++)
> +			numa_distance[i * cnt + j] = i == j ?
> +				LOCAL_DISTANCE : REMOTE_DISTANCE;
> +	pr_debug("NUMA: Initialized distance table, cnt=%d\n", cnt);
> +
> +	return 0;
> +}
> +
> +/**
> + * numa_set_distance - Set NUMA distance from one NUMA to another
> + * @from: the 'from' node to set distance
> + * @to: the 'to'  node to set distance
> + * @distance: NUMA distance
> + *
> + * Set the distance from node @from to @to to @distance.  If distance table
> + * doesn't exist, one which is large enough to accommodate all the currently
> + * known nodes will be created.
> + *
> + * If such table cannot be allocated, a warning is printed and further
> + * calls are ignored until the distance table is reset with
> + * numa_reset_distance().
> + *
> + * If @from or @to is higher than the highest known node or lower than zero
> + * at the time of table creation or @distance doesn't make sense, the call
> + * is ignored.
> + * This is to allow simplification of specific NUMA config implementations.
> + */
> +void __init numa_set_distance(int from, int to, int distance)
> +{
> +	if (!numa_distance && numa_alloc_distance() < 0)
> +		return;
> +
> +	if (from >= numa_distance_cnt || to >= numa_distance_cnt ||
> +			from < 0 || to < 0) {
> +		pr_warn_once("NUMA: Warning: node ids are out of bound, from=%d to=%d distance=%d\n",
> +			    from, to, distance);
> +		return;
> +	}
> +
> +	if ((u8)distance != distance ||
> +	    (from == to && distance != LOCAL_DISTANCE)) {
> +		pr_warn_once("NUMA: Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
> +			     from, to, distance);
> +		return;
> +	}
> +
> +	numa_distance[from * numa_distance_cnt + to] = distance;
> +}
> +EXPORT_SYMBOL(numa_set_distance);
> +
> +int __node_distance(int from, int to)
> +{
> +	if (from >= numa_distance_cnt || to >= numa_distance_cnt)
> +		return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
> +	return numa_distance[from * numa_distance_cnt + to];
> +}
> +EXPORT_SYMBOL(__node_distance);
> +
> +static int __init numa_register_memblks(struct numa_meminfo *mi)
> +{
> +	unsigned long uninitialized_var(pfn_align);
> +	int i, nid;
> +
> +	/* Account for nodes with cpus and no memory */
> +	node_possible_map = numa_nodes_parsed;
> +	numa_nodemask_from_meminfo(&node_possible_map, mi);
> +	if (WARN_ON(nodes_empty(node_possible_map)))
> +		return -EINVAL;
> +
> +	for (i = 0; i < mi->nr_blks; i++) {
> +		struct numa_memblk *mb = &mi->blk[i];
> +
> +		memblock_set_node(mb->start, mb->end - mb->start,
> +				  &memblock.memory, mb->nid);
> +	}
> +
> +	/*
> +	 * If sections array is gonna be used for pfn -> nid mapping, check
> +	 * whether its granularity is fine enough.
> +	 */
> +#ifdef NODE_NOT_IN_PAGE_FLAGS
> +	pfn_align = node_map_pfn_alignment();
> +	if (pfn_align && pfn_align < PAGES_PER_SECTION) {
> +		pr_warn("Node alignment %lluMB < min %lluMB, rejecting NUMA config\n",
> +		       PFN_PHYS(pfn_align) >> 20,
> +		       PFN_PHYS(PAGES_PER_SECTION) >> 20);
> +		return -EINVAL;
> +	}
> +#endif
> +	if (!numa_meminfo_cover_memory(mi))
> +		return -EINVAL;
> +
> +	/* Finally register nodes. */
> +	for_each_node_mask(nid, node_possible_map) {
> +		u64 start = PFN_PHYS(max_pfn);
> +		u64 end = 0;
> +
> +		for (i = 0; i < mi->nr_blks; i++) {
> +			if (nid != mi->blk[i].nid)
> +				continue;
> +			start = min(mi->blk[i].start, start);
> +			end = max(mi->blk[i].end, end);
> +		}
> +
> +		if (start < end)
> +			setup_node_data(nid, start, end);
> +	}
> +
> +	/* Dump memblock with node info and return. */
> +	memblock_dump_all();
> +	return 0;
> +}
> +
> +static int __init numa_init(int (*init_func)(void))
> +{
> +	int ret, i;
> +
> +	nodes_clear(numa_nodes_parsed);
> +	nodes_clear(node_possible_map);
> +	nodes_clear(node_online_map);
> +
> +	ret = init_func();
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = numa_register_memblks(&numa_meminfo);
> +	if (ret < 0)
> +		return ret;
> +
> +	for (i = 0; i < nr_cpu_ids; i++)
> +		numa_clear_node(i);
> +
> +	setup_node_to_cpumask_map();
> +	return 0;
> +}
> +
> +/**
> + * dummy_numa_init - Fallback dummy NUMA init
> + *
> + * Used if there's no underlying NUMA architecture, NUMA initialization
> + * fails, or NUMA is disabled on the command line.
> + *
> + * Must online at least one node and add memory blocks that cover all
> + * allowed memory.  This function must not fail.
> + */
> +static int __init dummy_numa_init(void)
> +{
> +	pr_info("%s\n", "No NUMA configuration found");
> +	pr_info("Faking a node at [mem %#018Lx-%#018Lx]\n",
> +	       0LLU, PFN_PHYS(max_pfn) - 1);
> +	node_set(0, numa_nodes_parsed);
> +	numa_add_memblk(0, 0, PFN_PHYS(max_pfn));
> +
> +	return 0;
> +}
> +
> +/**
> + * arm64_numa_init - Initialize NUMA
> + *
> + * Try each configured NUMA initialization method until one succeeds.  The
> + * last fallback is dummy single node config encomapssing whole memory and
> + * never fails.
> + */
> +void __init arm64_numa_init(void)
> +{
> +	int (*init_func)(void) = NULL;
> +
> +	if (IS_ENABLED(CONFIG_ARM64_DT_NUMA))
> +		init_func = arm64_dt_numa_init;
> +
> +	if (!numa_off && init_func) {
> +		if (!numa_init(init_func))
> +			return;
> +	}
> +
> +	numa_init(dummy_numa_init);
> +}
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 4/4] arm64:numa: adding numa support for arm64 platforms.
@ 2015-02-27  9:08       ` Hanjun Guo
  0 siblings, 0 replies; 36+ messages in thread
From: Hanjun Guo @ 2015-02-27  9:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Ganapatrao,

On 2015?01?22? 19:05, Ganapatrao Kulkarni wrote:
> Adding numa support for arm64 based platforms.
> Adding dt node pasring for numa topology using property arm,associativity.
>
> Signed-off-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
> ---
>   arch/arm64/Kconfig              |  32 +++
>   arch/arm64/include/asm/mmzone.h |  32 +++
>   arch/arm64/include/asm/numa.h   |  43 ++++
>   arch/arm64/kernel/Makefile      |   1 +
>   arch/arm64/kernel/dt_numa.c     | 302 +++++++++++++++++++++++
>   arch/arm64/kernel/setup.c       |   8 +
>   arch/arm64/kernel/smp.c         |   2 +
>   arch/arm64/mm/Makefile          |   1 +
>   arch/arm64/mm/init.c            |  34 ++-
>   arch/arm64/mm/numa.c            | 522 ++++++++++++++++++++++++++++++++++++++++
>   10 files changed, 971 insertions(+), 6 deletions(-)
>   create mode 100644 arch/arm64/include/asm/mmzone.h
>   create mode 100644 arch/arm64/include/asm/numa.h
>   create mode 100644 arch/arm64/kernel/dt_numa.c
>   create mode 100644 arch/arm64/mm/numa.c
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 242419d..6d262b1 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -59,6 +59,7 @@ config ARM64
>   	select HAVE_PERF_USER_STACK_DUMP
>   	select HAVE_RCU_TABLE_FREE
>   	select HAVE_SYSCALL_TRACEPOINTS
> +	select HAVE_MEMBLOCK_NODE_MAP if NUMA
>   	select IRQ_DOMAIN
>   	select MODULES_USE_ELF_RELA
>   	select NO_BOOTMEM
> @@ -315,6 +316,37 @@ config HOTPLUG_CPU
>   	  Say Y here to experiment with turning CPUs off and on.  CPUs
>   	  can be controlled through /sys/devices/system/cpu.
>
> +# Common NUMA Features
> +config NUMA
> +	bool "Numa Memory Allocation and Scheduler Support"
> +	depends on SMP
> +	---help---
> +	  Enable NUMA (Non Uniform Memory Access) support.
> +
> +	  The kernel will try to allocate memory used by a CPU on the
> +	  local memory controller of the CPU and add some more
> +	  NUMA awareness to the kernel.
> +
> +config ARM64_DT_NUMA
> +	def_bool n
> +	prompt "DT NUMA detection"
> +	---help---
> +	  Enable DT based numa.
> +
> +config NODES_SHIFT
> +	int "Maximum NUMA Nodes (as a power of 2)"
> +	range 1 10
> +	default "2"
> +	depends on NEED_MULTIPLE_NODES
> +	---help---
> +	  Specify the maximum number of NUMA Nodes available on the target
> +	  system.  Increases memory reserved to accommodate various tables.
> +
> +config USE_PERCPU_NUMA_NODE_ID
> +	def_bool y
> +	depends on NUMA
> +
> +
>   source kernel/Kconfig.preempt
>
>   config HZ
> diff --git a/arch/arm64/include/asm/mmzone.h b/arch/arm64/include/asm/mmzone.h
> new file mode 100644
> index 0000000..d27ee66
> --- /dev/null
> +++ b/arch/arm64/include/asm/mmzone.h
> @@ -0,0 +1,32 @@
> +#ifndef __ASM_ARM64_MMZONE_H_
> +#define __ASM_ARM64_MMZONE_H_
> +
> +#ifdef CONFIG_NUMA
> +
> +#include <linux/mmdebug.h>
> +#include <asm/smp.h>
> +#include <linux/types.h>
> +#include <asm/numa.h>
> +
> +extern struct pglist_data *node_data[];
> +
> +#define NODE_DATA(nid)		(node_data[nid])
> +
> +
> +struct numa_memblk {
> +	u64			start;
> +	u64			end;
> +	int			nid;
> +};
> +
> +struct numa_meminfo {
> +	int			nr_blks;
> +	struct numa_memblk	blk[NR_NODE_MEMBLKS];
> +};
> +
> +void __init numa_remove_memblk_from(int idx, struct numa_meminfo *mi);
> +int __init numa_cleanup_meminfo(struct numa_meminfo *mi);
> +void __init numa_reset_distance(void);
> +
> +#endif /* CONFIG_NUMA */
> +#endif /* __ASM_ARM64_MMZONE_H_ */
> diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h
> new file mode 100644
> index 0000000..8be5cb1
> --- /dev/null
> +++ b/arch/arm64/include/asm/numa.h
> @@ -0,0 +1,43 @@
> +#ifndef _ASM_ARM64_NUMA_H
> +#define _ASM_ARM64_NUMA_H

Use _ASM_NUMA_H please.

> +
> +#include <linux/nodemask.h>
> +#include <asm/topology.h>
> +
> +#ifdef CONFIG_NUMA
> +
> +#define NR_NODE_MEMBLKS		(MAX_NUMNODES * 2)
> +#define ZONE_ALIGN (1UL << (MAX_ORDER + PAGE_SHIFT))
> +
> +/* currently, arm64 implements flat NUMA topology */
> +#define parent_node(node)	(node)
> +
> +/* dummy definitions for pci functions */
> +#define pcibus_to_node(node)	0
> +#define cpumask_of_pcibus(bus)	0
> +
> +struct __node_cpu_hwid {
> +	u32 node_id;    /* logical node containing this CPU */
> +	u64 cpu_hwid;   /* MPIDR for this CPU */
> +};
> +
> +const struct cpumask *cpumask_of_node(int node);
> +/* Mappings between node number and cpus on that node. */
> +extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
> +
> +void __init arm64_numa_init(void);
> +int __init numa_add_memblk(u32 nodeid, u64 start, u64 end);
> +void numa_store_cpu_info(int cpu);
> +void numa_set_node(int cpu, int node);
> +void numa_clear_node(int cpu);
> +void numa_add_cpu(int cpu);
> +void numa_remove_cpu(int cpu);
> +void __init numa_set_distance(int from, int to, int distance);
> +int dt_get_cpu_node_id(int cpu);
> +int __init arm64_dt_numa_init(void);

Do we really need all those function declared here?

> +#else	/* CONFIG_NUMA */
> +static inline void arm64_numa_init(void);

Compile error when !CONFIG_NUMA, should be

static inline void arm64_numa_init(void) { }

> +static inline void numa_store_cpu_info(int cpu)		{ }
> +static inline void arm64_numa_init(void)		{ }

duplicate one.

> +#endif	/* CONFIG_NUMA */
> +#endif	/* _ASM_ARM64_NUMA_H */
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index 5bd029b..39451df 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -31,6 +31,7 @@ arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
>   arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
>   arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
>   arm64-obj-$(CONFIG_PCI)			+= pci.o
> +arm64-obj-$(CONFIG_ARM64_DT_NUMA)	+= dt_numa.o
>
>   obj-y					+= $(arm64-obj-y) vdso/
>   obj-m					+= $(arm64-obj-m)
> diff --git a/arch/arm64/kernel/dt_numa.c b/arch/arm64/kernel/dt_numa.c
> new file mode 100644
> index 0000000..7c418e2
> --- /dev/null
> +++ b/arch/arm64/kernel/dt_numa.c
> @@ -0,0 +1,302 @@
> +/*
> + * DT NUMA Parsing support, based on the powerpc 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/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/string.h>
> +#include <linux/init.h>
> +#include <linux/bootmem.h>
> +#include <linux/memblock.h>
> +#include <linux/ctype.h>
> +#include <linux/module.h>
> +#include <linux/nodemask.h>
> +#include <linux/sched.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <asm/smp_plat.h>
> +
> +#define MAX_DISTANCE_REF_POINTS 8
> +static int min_common_depth;
> +static int distance_ref_points_depth;
> +static const __be32 *distance_ref_points;
> +static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS];
> +static int default_nid;
> +static int of_node_to_nid_single(struct device_node *device);
> +static struct device_node *of_cpu_to_node(int cpu);
> +extern nodemask_t numa_nodes_parsed __initdata;
> +
> +static void initialize_distance_lookup_table(int nid,
> +		const __be32 *associativity)
> +{
> +	int i;
> +
> +	for (i = 0; i < distance_ref_points_depth; i++) {
> +		const __be32 *entry;
> +
> +		entry = &associativity[be32_to_cpu(distance_ref_points[i])];
> +		distance_lookup_table[nid][i] = of_read_number(entry, 1);
> +	}
> +}
> +
> +/* must hold reference to node during call */
> +static const __be32 *of_get_associativity(struct device_node *dev)
> +{
> +	return of_get_property(dev, "arm,associativity", NULL);
> +}
> +
> +/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
> + * info is found.
> + */
> +static int associativity_to_nid(const __be32 *associativity)
> +{
> +	int nid = NUMA_NO_NODE;
> +
> +	if (min_common_depth == -1)
> +		goto out;
> +
> +	if (of_read_number(associativity, 1) >= min_common_depth)
> +		nid = of_read_number(&associativity[min_common_depth], 1);
> +
> +	/* set 0xffff as invalid node */
> +	if (nid == 0xffff || nid >= MAX_NUMNODES)
> +		nid = NUMA_NO_NODE;
> +
> +	if (nid != NUMA_NO_NODE)
> +		initialize_distance_lookup_table(nid, associativity);
> +out:
> +	return nid;
> +}
> +
> +/* Returns the nid associated with the given device tree node,
> + * or -1 if not found.
> + */
> +static int of_node_to_nid_single(struct device_node *device)
> +{
> +	int nid = default_nid;
> +	const __be32 *tmp;
> +
> +	tmp = of_get_associativity(device);
> +	if (tmp)
> +		nid = associativity_to_nid(tmp);
> +	return nid;
> +}
> +
> +/* Walk the device tree upwards, looking for an associativity id */
> +int of_node_to_nid(struct device_node *device)
> +{
> +	struct device_node *tmp;
> +	int nid = NUMA_NO_NODE;
> +
> +	of_node_get(device);
> +	while (device) {
> +		nid = of_node_to_nid_single(device);
> +		if (nid != NUMA_NO_NODE)
> +			break;
> +
> +		tmp = device;
> +		device = of_get_parent(tmp);
> +		of_node_put(tmp);
> +	}
> +	of_node_put(device);
> +
> +	return nid;
> +}
> +
> +static int __init find_min_common_depth(unsigned long node)
> +{
> +	int depth;
> +	const __be32 *numa_prop;
> +	int nr_address_cells;
> +
> +	/*
> +	 * This property is a set of 32-bit integers, each representing
> +	 * an index into the arm,associativity nodes.
> +	 *
> +	 * With form 1 affinity the first integer is the most significant
> +	 * NUMA boundary and the following are progressively less significant
> +	 * boundaries. There can be more than one level of NUMA.
> +	 */
> +
> +	distance_ref_points = of_get_flat_dt_prop(node,
> +			"arm,associativity-reference-points",
> +			&distance_ref_points_depth);
> +	numa_prop = distance_ref_points;
> +
> +	if (numa_prop) {
> +		nr_address_cells = dt_mem_next_cell(
> +				OF_ROOT_NODE_ADDR_CELLS_DEFAULT, &numa_prop);
> +		nr_address_cells = dt_mem_next_cell(
> +				OF_ROOT_NODE_ADDR_CELLS_DEFAULT, &numa_prop);
> +	}
> +	if (!distance_ref_points) {
> +		pr_debug("NUMA: arm,associativity-reference-points not found.\n");
> +		goto err;
> +	}
> +
> +	distance_ref_points_depth /= sizeof(__be32);
> +
> +	if (!distance_ref_points_depth) {
> +		pr_err("NUMA: missing arm,associativity-reference-points\n");
> +		goto err;
> +	}
> +	depth = of_read_number(distance_ref_points, 1);
> +
> +	/*
> +	 * Warn and cap if the hardware supports more than
> +	 * MAX_DISTANCE_REF_POINTS domains.
> +	 */
> +	if (distance_ref_points_depth > MAX_DISTANCE_REF_POINTS) {
> +		pr_debug("NUMA: distance array capped at %d entries\n", MAX_DISTANCE_REF_POINTS);
> +		distance_ref_points_depth = MAX_DISTANCE_REF_POINTS;
> +	}
> +
> +	return depth;
> +err:
> +	return -1;
> +}
> +
> +int dt_get_cpu_node_id(int cpu)
> +{
> +	struct device_node *dn = NULL;
> +	int nid = default_nid;
> +
> +	dn =  of_cpu_to_node(cpu);
> +	if (dn)
> +		nid = of_node_to_nid_single(dn);
> +	return nid;
> +}
> +
> +static struct device_node *of_cpu_to_node(int cpu)
> +{
> +	struct device_node *dn = NULL;
> +
> +	while ((dn = of_find_node_by_type(dn, "cpu"))) {
> +		const u32 *cell;
> +		u64 hwid;
> +
> +		/*
> +		 * A cpu node with missing "reg" property is
> +		 * considered invalid to build a cpu_logical_map
> +		 * entry.
> +		 */
> +		cell = of_get_property(dn, "reg", NULL);
> +		if (!cell) {
> +			pr_err("%s: missing reg property\n", dn->full_name);
> +			return NULL;
> +		}
> +		hwid = of_read_number(cell, of_n_addr_cells(dn));
> +
> +		if (cpu_logical_map(cpu) == hwid)
> +			return dn;
> +	}
> +	return NULL;
> +}
> +
> +static int __init parse_memory_node(unsigned long node)
> +{
> +	const __be32 *reg, *endp, *associativity;
> +	int length;
> +	int nid = default_nid;
> +
> +	associativity = of_get_flat_dt_prop(node, "arm,associativity", &length);
> +
> +	if (associativity)
> +		nid = associativity_to_nid(associativity);
> +
> +	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;
> +		struct memblock_region *mblk;
> +
> +		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
> +		size = dt_mem_next_cell(dt_root_size_cells, &reg);
> +		pr_debug("NUMA-DT:  base = %llx , node = %u\n",
> +				base, nid);
> +		for_each_memblock(memory, mblk) {
> +			if (mblk->base == base) {
> +				node_set(nid, numa_nodes_parsed);
> +				numa_add_memblk(nid, mblk->base, mblk->size);
> +				break;
> +			}
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * early_init_dt_scan_numa_map - parse memory node and map nid to memory range.
> + */
> +int __init early_init_dt_scan_numa_map(unsigned long node, const char *uname,
> +				     int depth, void *data)
> +{
> +	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
> +
> +	if (depth == 0) {
> +		min_common_depth = find_min_common_depth(node);
> +		if (min_common_depth < 0)
> +			return min_common_depth;
> +		pr_debug("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
> +		return 0;
> +	}
> +
> +	if (type) {
> +		if (strcmp(type, "memory") == 0)
> +			parse_memory_node(node);
> +	}
> +	return 0;
> +}
> +
> +int dt_get_node_distance(int a, int b)
> +{
> +	int i;
> +	int distance = LOCAL_DISTANCE;
> +
> +	for (i = 0; i < distance_ref_points_depth; i++) {
> +		if (distance_lookup_table[a][i] == distance_lookup_table[b][i])
> +			break;
> +
> +		/* Double the distance for each NUMA level */
> +		distance *= 2;
> +	}
> +	return distance;
> +}
> +
> +/* DT node mapping is done already early_init_dt_scan_memory */
> +int __init arm64_dt_numa_init(void)
> +{
> +	int i;
> +	u32 nodea, nodeb, distance, node_count = 0;
> +
> +	of_scan_flat_dt(early_init_dt_scan_numa_map, NULL);
> +
> +	for_each_node_mask(i, numa_nodes_parsed)
> +		node_count = i;
> +	node_count++;
> +
> +	for (nodea =  0; nodea < node_count; nodea++) {
> +		for (nodeb = 0; nodeb < node_count; nodeb++) {
> +			distance = dt_get_node_distance(nodea, nodeb);
> +			numa_set_distance(nodea, nodeb, distance);
> +		}
> +	}
> +	return 0;
> +}
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 2437196..80b4a9e 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -425,6 +425,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;
> @@ -461,7 +464,12 @@ static int c_show(struct seq_file *m, void *v)
>   		 * "processor".  Give glibc what it expects.
>   		 */
>   #ifdef CONFIG_SMP
> +	if (IS_ENABLED(CONFIG_NUMA)) {
> +		seq_printf(m, "processor\t: %d", i);
> +		seq_printf(m, " [nid: %d]\n", cpu_to_node(i));
> +	} else {
>   		seq_printf(m, "processor\t: %d\n", i);
> +	}
>   #endif
>   	}
>
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index b06d1d9..1d1e86f 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -50,6 +50,7 @@
>   #include <asm/sections.h>
>   #include <asm/tlbflush.h>
>   #include <asm/ptrace.h>
> +#include <asm/numa.h>
>
>   #define CREATE_TRACE_POINTS
>   #include <trace/events/ipi.h>
> @@ -123,6 +124,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
>   static void smp_store_cpu_info(unsigned int cpuid)
>   {
>   	store_cpu_topology(cpuid);
> +	numa_store_cpu_info(cpuid);
>   }
>
>   /*
> diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
> index c56179e..c86e6de 100644
> --- a/arch/arm64/mm/Makefile
> +++ b/arch/arm64/mm/Makefile
> @@ -3,3 +3,4 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
>   				   ioremap.o mmap.o pgd.o mmu.o \
>   				   context.o proc.o pageattr.o
>   obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
> +obj-$(CONFIG_NUMA)		+= numa.o
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 494297c..6fd6802 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -39,6 +39,7 @@
>   #include <asm/setup.h>
>   #include <asm/sizes.h>
>   #include <asm/tlb.h>
> +#include <asm/numa.h>
>
>   #include "mm.h"
>
> @@ -73,6 +74,20 @@ static phys_addr_t max_zone_dma_phys(void)
>   	return min(offset + (1ULL << 32), memblock_end_of_DRAM());
>   }
>
> +#ifdef CONFIG_NUMA
> +static void __init zone_sizes_init(unsigned long min, unsigned long max)
> +{
> +	unsigned long max_zone_pfns[MAX_NR_ZONES];
> +
> +	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
> +	if (IS_ENABLED(CONFIG_ZONE_DMA))
> +		max_zone_pfns[ZONE_DMA] = PFN_DOWN(max_zone_dma_phys());
> +	max_zone_pfns[ZONE_NORMAL] = max;
> +
> +	free_area_init_nodes(max_zone_pfns);
> +}
> +
> +#else
>   static void __init zone_sizes_init(unsigned long min, unsigned long max)
>   {
>   	struct memblock_region *reg;
> @@ -111,6 +126,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
>
>   	free_area_init_node(0, zone_size, min, zhole_size);
>   }
> +#endif /* CONFIG_NUMA */
>
>   #ifdef CONFIG_HAVE_ARCH_PFN_VALID
>   int pfn_valid(unsigned long pfn)
> @@ -128,10 +144,15 @@ static void arm64_memory_present(void)
>   static void arm64_memory_present(void)
>   {
>   	struct memblock_region *reg;
> +	int nid = 0;
>
> -	for_each_memblock(memory, reg)
> -		memory_present(0, memblock_region_memory_base_pfn(reg),
> -			       memblock_region_memory_end_pfn(reg));
> +	for_each_memblock(memory, reg) {
> +#ifdef CONFIG_NUMA
> +		nid = reg->nid;
> +#endif
> +		memory_present(nid, memblock_region_memory_base_pfn(reg),
> +				memblock_region_memory_end_pfn(reg));
> +	}
>   }
>   #endif
>
> @@ -167,6 +188,10 @@ void __init bootmem_init(void)
>   	min = PFN_UP(memblock_start_of_DRAM());
>   	max = PFN_DOWN(memblock_end_of_DRAM());
>
> +	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
> +	max_pfn = max_low_pfn = max;
> +
> +	arm64_numa_init();
>   	/*
>   	 * Sparsemem tries to allocate bootmem in memory_present(), so must be
>   	 * done after the fixed reservations.
> @@ -175,9 +200,6 @@ void __init bootmem_init(void)
>
>   	sparse_init();
>   	zone_sizes_init(min, max);
> -
> -	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
> -	max_pfn = max_low_pfn = max;
>   }
>
>   #ifndef CONFIG_SPARSEMEM_VMEMMAP
> diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
> new file mode 100644
> index 0000000..da1d301
> --- /dev/null
> +++ b/arch/arm64/mm/numa.c
> @@ -0,0 +1,522 @@
> +/*
> + * 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/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/string.h>
> +#include <linux/init.h>
> +#include <linux/bootmem.h>
> +#include <linux/memblock.h>
> +#include <linux/mmzone.h>
> +#include <linux/ctype.h>
> +#include <linux/module.h>
> +#include <linux/nodemask.h>
> +#include <linux/sched.h>
> +#include <linux/topology.h>
> +#include <linux/of.h>
> +#include <asm/smp_plat.h>
> +
> +int __initdata numa_off;
> +nodemask_t numa_nodes_parsed __initdata;
> +static int numa_distance_cnt;
> +static u8 *numa_distance;
> +
> +struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
> +EXPORT_SYMBOL(node_data);
> +
> +static struct __node_cpu_hwid node_cpu_hwid[NR_CPUS];
> +static struct numa_meminfo numa_meminfo;
> +
> +static __init int numa_setup(char *opt)
> +{
> +	if (!opt)
> +		return -EINVAL;
> +	if (!strncmp(opt, "off", 3)) {
> +		pr_info("%s\n", "NUMA turned off");
> +		numa_off = 1;
> +	}
> +	return 0;
> +}
> +early_param("numa", numa_setup);
> +
> +cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
> +EXPORT_SYMBOL(node_to_cpumask_map);
> +
> +/*
> + * Returns a pointer to the bitmask of CPUs on Node 'node'.
> + */
> +const struct cpumask *cpumask_of_node(int node)
> +{
> +	if (node >= nr_node_ids) {
> +		pr_warn("cpumask_of_node(%d): node > nr_node_ids(%d)\n",
> +			node, nr_node_ids);
> +		dump_stack();
> +		return cpu_none_mask;
> +	}
> +	if (node_to_cpumask_map[node] == NULL) {
> +		pr_warn("cpumask_of_node(%d): no node_to_cpumask_map!\n",
> +			node);
> +		dump_stack();
> +		return cpu_online_mask;
> +	}
> +	return node_to_cpumask_map[node];
> +}
> +EXPORT_SYMBOL(cpumask_of_node);
> +
> +void numa_clear_node(int cpu)
> +{
> +	node_cpu_hwid[cpu].node_id = NUMA_NO_NODE;
> +}
> +
> +/*
> + * Allocate node_to_cpumask_map based on number of available nodes
> + * Requires node_possible_map to be valid.
> + *
> + * Note: cpumask_of_node() is not valid until after this is done.
> + * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
> + */
> +void __init setup_node_to_cpumask_map(void)
> +{
> +	unsigned int node;
> +
> +	/* setup nr_node_ids if not done yet */
> +	if (nr_node_ids == MAX_NUMNODES)
> +		setup_nr_node_ids();
> +
> +	/* allocate the map */
> +	for (node = 0; node < nr_node_ids; node++)
> +		alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
> +
> +	/* cpumask_of_node() will now work */
> +	pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
> +}
> +
> +/*
> + *  Set the cpu to node and mem mapping
> + */
> +void numa_store_cpu_info(int cpu)
> +{
> +	if (IS_ENABLED(CONFIG_ARM64_DT_NUMA))
> +		node_cpu_hwid[cpu].node_id  =  dt_get_cpu_node_id(cpu);
> +	else
> +		node_cpu_hwid[cpu].node_id  =  0;
> +
> +	/* mapping of MPIDR/hwid, node and logical cpu id */
> +	node_cpu_hwid[cpu].cpu_hwid = cpu_logical_map(cpu);
> +	cpumask_set_cpu(cpu, node_to_cpumask_map[node_cpu_hwid[cpu].node_id]);
> +	set_numa_node(node_cpu_hwid[cpu].node_id);
> +	set_numa_mem(local_memory_node(node_cpu_hwid[cpu].node_id));
> +}
> +
> +/**
> + * numa_add_memblk_to - Add one numa_memblk to a numa_meminfo
> + */
> +
> +static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
> +				     struct numa_meminfo *mi)
> +{
> +	/* ignore zero length blks */
> +	if (start == end)
> +		return 0;
> +
> +	/* whine about and ignore invalid blks */
> +	if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
> +		pr_warn("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
> +				nid, start, end - 1);
> +		return 0;
> +	}
> +
> +	if (mi->nr_blks >= NR_NODE_MEMBLKS) {
> +		pr_err("NUMA: too many memblk ranges\n");
> +		return -EINVAL;
> +	}
> +
> +	pr_info("NUMA: Adding memblock %d [0x%llx - 0x%llx] on node %d\n",
> +			mi->nr_blks, start, end, nid);
> +	mi->blk[mi->nr_blks].start = start;
> +	mi->blk[mi->nr_blks].end = end;
> +	mi->blk[mi->nr_blks].nid = nid;
> +	mi->nr_blks++;
> +	return 0;
> +}
> +
> +/**
> + * numa_add_memblk - Add one numa_memblk to numa_meminfo
> + * @nid: NUMA node ID of the new memblk
> + * @start: Start address of the new memblk
> + * @end: End address of the new memblk
> + *
> + * Add a new memblk to the default numa_meminfo.
> + *
> + * RETURNS:
> + * 0 on success, -errno on failure.
> + */
> +#define MAX_PHYS_ADDR	((phys_addr_t)~0)
> +
> +int __init numa_add_memblk(u32 nid, u64 base, u64 size)

In the comments, it says "@end: End address of the new memblk",
I think it's better to be consistent with other archs, just
use "end" instead of "size" here.

Thanks
Hanjun

> +{
> +	const u64 phys_offset = __pa(PAGE_OFFSET);
> +
> +	base &= PAGE_MASK;
> +	size &= PAGE_MASK;
> +
> +	if (base > MAX_PHYS_ADDR) {
> +		pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
> +				base, base + size);
> +		return -ENOMEM;
> +	}
> +
> +	if (base + size > MAX_PHYS_ADDR) {
> +		pr_info("NUMA: Ignoring memory range 0x%lx - 0x%llx\n",
> +				ULONG_MAX, base + size);
> +		size = MAX_PHYS_ADDR - base;
> +	}
> +
> +	if (base + size < phys_offset) {
> +		pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
> +			   base, base + size);
> +		return -ENOMEM;
> +	}
> +	if (base < phys_offset) {
> +		pr_info("NUMA: Ignoring memory range 0x%llx - 0x%llx\n",
> +			   base, phys_offset);
> +		size -= phys_offset - base;
> +		base = phys_offset;
> +	}
> +
> +	return numa_add_memblk_to(nid, base, base+size, &numa_meminfo);
> +}
> +EXPORT_SYMBOL(numa_add_memblk);
> +
> +/* Initialize NODE_DATA for a node on the local memory */
> +static void __init setup_node_data(int nid, u64 start, u64 end)
> +{
> +	const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
> +	u64 nd_pa;
> +	void *nd;
> +	int tnid;
> +
> +	start = roundup(start, ZONE_ALIGN);
> +
> +	pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
> +	       nid, start, end - 1);
> +
> +	/*
> +	 * Allocate node data.  Try node-local memory and then any node.
> +	 */
> +	nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid);
> +	if (!nd_pa) {
> +		nd_pa = __memblock_alloc_base(nd_size, SMP_CACHE_BYTES,
> +					      MEMBLOCK_ALLOC_ACCESSIBLE);
> +		if (!nd_pa) {
> +			pr_err("Cannot find %zu bytes in node %d\n",
> +			       nd_size, nid);
> +			return;
> +		}
> +	}
> +	nd = __va(nd_pa);
> +
> +	/* report and initialize */
> +	pr_info("  NODE_DATA [mem %#010Lx-%#010Lx]\n",
> +	       nd_pa, nd_pa + nd_size - 1);
> +	tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
> +	if (tnid != nid)
> +		pr_info("    NODE_DATA(%d) on node %d\n", nid, tnid);
> +
> +	node_data[nid] = nd;
> +	memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
> +	NODE_DATA(nid)->node_id = nid;
> +	NODE_DATA(nid)->node_start_pfn = start >> PAGE_SHIFT;
> +	NODE_DATA(nid)->node_spanned_pages = (end - start) >> PAGE_SHIFT;
> +
> +	node_set_online(nid);
> +}
> +
> +/*
> + * Set nodes, which have memory in @mi, in *@nodemask.
> + */
> +static void __init numa_nodemask_from_meminfo(nodemask_t *nodemask,
> +					      const struct numa_meminfo *mi)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(mi->blk); i++)
> +		if (mi->blk[i].start != mi->blk[i].end &&
> +		    mi->blk[i].nid != NUMA_NO_NODE)
> +			node_set(mi->blk[i].nid, *nodemask);
> +}
> +
> +/*
> + * Sanity check to catch more bad NUMA configurations (they are amazingly
> + * common).  Make sure the nodes cover all memory.
> + */
> +static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
> +{
> +	u64 numaram, totalram;
> +	int i;
> +
> +	numaram = 0;
> +	for (i = 0; i < mi->nr_blks; i++) {
> +		u64 s = mi->blk[i].start >> PAGE_SHIFT;
> +		u64 e = mi->blk[i].end >> PAGE_SHIFT;
> +
> +		numaram += e - s;
> +		numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e);
> +		if ((s64)numaram < 0)
> +			numaram = 0;
> +	}
> +
> +	totalram = max_pfn - absent_pages_in_range(0, max_pfn);
> +
> +	/* We seem to lose 3 pages somewhere. Allow 1M of slack. */
> +	if ((s64)(totalram - numaram) >= (1 << (20 - PAGE_SHIFT))) {
> +		pr_err("NUMA: nodes only cover %lluMB of your %lluMB Total RAM. Not used.\n",
> +		       (numaram << PAGE_SHIFT) >> 20,
> +		       (totalram << PAGE_SHIFT) >> 20);
> +		return false;
> +	}
> +	return true;
> +}
> +
> +/**
> + * numa_reset_distance - Reset NUMA distance table
> + *
> + * The current table is freed.  The next numa_set_distance() call will
> + * create a new one.
> + */
> +void __init numa_reset_distance(void)
> +{
> +	size_t size = numa_distance_cnt * numa_distance_cnt *
> +		sizeof(numa_distance[0]);
> +
> +	/* numa_distance could be 1LU marking allocation failure, test cnt */
> +	if (numa_distance_cnt)
> +		memblock_free(__pa(numa_distance), size);
> +	numa_distance_cnt = 0;
> +	numa_distance = NULL;	/* enable table creation */
> +}
> +
> +static int __init numa_alloc_distance(void)
> +{
> +	nodemask_t nodes_parsed;
> +	size_t size;
> +	int i, j, cnt = 0;
> +	u64 phys;
> +
> +	/* size the new table and allocate it */
> +	nodes_parsed = numa_nodes_parsed;
> +	numa_nodemask_from_meminfo(&nodes_parsed, &numa_meminfo);
> +
> +	for_each_node_mask(i, nodes_parsed)
> +		cnt = i;
> +	cnt++;
> +	size = cnt * cnt * sizeof(numa_distance[0]);
> +
> +	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
> +				      size, PAGE_SIZE);
> +	if (!phys) {
> +		pr_warning("NUMA: Warning: can't allocate distance table!\n");
> +		/* don't retry until explicitly reset */
> +		numa_distance = (void *)1LU;
> +		return -ENOMEM;
> +	}
> +	memblock_reserve(phys, size);
> +
> +	numa_distance = __va(phys);
> +	numa_distance_cnt = cnt;
> +
> +	/* fill with the default distances */
> +	for (i = 0; i < cnt; i++)
> +		for (j = 0; j < cnt; j++)
> +			numa_distance[i * cnt + j] = i == j ?
> +				LOCAL_DISTANCE : REMOTE_DISTANCE;
> +	pr_debug("NUMA: Initialized distance table, cnt=%d\n", cnt);
> +
> +	return 0;
> +}
> +
> +/**
> + * numa_set_distance - Set NUMA distance from one NUMA to another
> + * @from: the 'from' node to set distance
> + * @to: the 'to'  node to set distance
> + * @distance: NUMA distance
> + *
> + * Set the distance from node @from to @to to @distance.  If distance table
> + * doesn't exist, one which is large enough to accommodate all the currently
> + * known nodes will be created.
> + *
> + * If such table cannot be allocated, a warning is printed and further
> + * calls are ignored until the distance table is reset with
> + * numa_reset_distance().
> + *
> + * If @from or @to is higher than the highest known node or lower than zero
> + * at the time of table creation or @distance doesn't make sense, the call
> + * is ignored.
> + * This is to allow simplification of specific NUMA config implementations.
> + */
> +void __init numa_set_distance(int from, int to, int distance)
> +{
> +	if (!numa_distance && numa_alloc_distance() < 0)
> +		return;
> +
> +	if (from >= numa_distance_cnt || to >= numa_distance_cnt ||
> +			from < 0 || to < 0) {
> +		pr_warn_once("NUMA: Warning: node ids are out of bound, from=%d to=%d distance=%d\n",
> +			    from, to, distance);
> +		return;
> +	}
> +
> +	if ((u8)distance != distance ||
> +	    (from == to && distance != LOCAL_DISTANCE)) {
> +		pr_warn_once("NUMA: Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
> +			     from, to, distance);
> +		return;
> +	}
> +
> +	numa_distance[from * numa_distance_cnt + to] = distance;
> +}
> +EXPORT_SYMBOL(numa_set_distance);
> +
> +int __node_distance(int from, int to)
> +{
> +	if (from >= numa_distance_cnt || to >= numa_distance_cnt)
> +		return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
> +	return numa_distance[from * numa_distance_cnt + to];
> +}
> +EXPORT_SYMBOL(__node_distance);
> +
> +static int __init numa_register_memblks(struct numa_meminfo *mi)
> +{
> +	unsigned long uninitialized_var(pfn_align);
> +	int i, nid;
> +
> +	/* Account for nodes with cpus and no memory */
> +	node_possible_map = numa_nodes_parsed;
> +	numa_nodemask_from_meminfo(&node_possible_map, mi);
> +	if (WARN_ON(nodes_empty(node_possible_map)))
> +		return -EINVAL;
> +
> +	for (i = 0; i < mi->nr_blks; i++) {
> +		struct numa_memblk *mb = &mi->blk[i];
> +
> +		memblock_set_node(mb->start, mb->end - mb->start,
> +				  &memblock.memory, mb->nid);
> +	}
> +
> +	/*
> +	 * If sections array is gonna be used for pfn -> nid mapping, check
> +	 * whether its granularity is fine enough.
> +	 */
> +#ifdef NODE_NOT_IN_PAGE_FLAGS
> +	pfn_align = node_map_pfn_alignment();
> +	if (pfn_align && pfn_align < PAGES_PER_SECTION) {
> +		pr_warn("Node alignment %lluMB < min %lluMB, rejecting NUMA config\n",
> +		       PFN_PHYS(pfn_align) >> 20,
> +		       PFN_PHYS(PAGES_PER_SECTION) >> 20);
> +		return -EINVAL;
> +	}
> +#endif
> +	if (!numa_meminfo_cover_memory(mi))
> +		return -EINVAL;
> +
> +	/* Finally register nodes. */
> +	for_each_node_mask(nid, node_possible_map) {
> +		u64 start = PFN_PHYS(max_pfn);
> +		u64 end = 0;
> +
> +		for (i = 0; i < mi->nr_blks; i++) {
> +			if (nid != mi->blk[i].nid)
> +				continue;
> +			start = min(mi->blk[i].start, start);
> +			end = max(mi->blk[i].end, end);
> +		}
> +
> +		if (start < end)
> +			setup_node_data(nid, start, end);
> +	}
> +
> +	/* Dump memblock with node info and return. */
> +	memblock_dump_all();
> +	return 0;
> +}
> +
> +static int __init numa_init(int (*init_func)(void))
> +{
> +	int ret, i;
> +
> +	nodes_clear(numa_nodes_parsed);
> +	nodes_clear(node_possible_map);
> +	nodes_clear(node_online_map);
> +
> +	ret = init_func();
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = numa_register_memblks(&numa_meminfo);
> +	if (ret < 0)
> +		return ret;
> +
> +	for (i = 0; i < nr_cpu_ids; i++)
> +		numa_clear_node(i);
> +
> +	setup_node_to_cpumask_map();
> +	return 0;
> +}
> +
> +/**
> + * dummy_numa_init - Fallback dummy NUMA init
> + *
> + * Used if there's no underlying NUMA architecture, NUMA initialization
> + * fails, or NUMA is disabled on the command line.
> + *
> + * Must online at least one node and add memory blocks that cover all
> + * allowed memory.  This function must not fail.
> + */
> +static int __init dummy_numa_init(void)
> +{
> +	pr_info("%s\n", "No NUMA configuration found");
> +	pr_info("Faking a node at [mem %#018Lx-%#018Lx]\n",
> +	       0LLU, PFN_PHYS(max_pfn) - 1);
> +	node_set(0, numa_nodes_parsed);
> +	numa_add_memblk(0, 0, PFN_PHYS(max_pfn));
> +
> +	return 0;
> +}
> +
> +/**
> + * arm64_numa_init - Initialize NUMA
> + *
> + * Try each configured NUMA initialization method until one succeeds.  The
> + * last fallback is dummy single node config encomapssing whole memory and
> + * never fails.
> + */
> +void __init arm64_numa_init(void)
> +{
> +	int (*init_func)(void) = NULL;
> +
> +	if (IS_ENABLED(CONFIG_ARM64_DT_NUMA))
> +		init_func = arm64_dt_numa_init;
> +
> +	if (!numa_off && init_func) {
> +		if (!numa_init(init_func))
> +			return;
> +	}
> +
> +	numa_init(dummy_numa_init);
> +}
>

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

* Re: [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
  2015-02-24  8:52                 ` Ganapatrao Kulkarni
@ 2015-03-10  8:42                     ` Ganapatrao Kulkarni
  -1 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-03-10  8:42 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Ganapatrao Kulkarni,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Will Deacon,
	Catalin Marinas, Grant Likely, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Leif Lindholm, Roy Franz, Ard Biesheuvel,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, Rob Herring, Steve Capper,
	Hanjun Guo, jchandra-dY08KVG/lbpWk0Htik3J/w, Al Stone,
	jcm-H+wXaHxf7aLQT0dZR+AlfA, ddutile-H+wXaHxf7aLQT0dZR+AlfA

Ping?

On Tue, Feb 24, 2015 at 2:22 PM, Ganapatrao Kulkarni
<gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Hi Arnd,
>
> On Fri, Jan 23, 2015 at 6:07 PM, Ganapatrao Kulkarni
> <gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> Hi Arnd,
>>
>> On Thu, Jan 22, 2015 at 11:56 PM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
>>> On Thursday 22 January 2015 17:47:13 Arnd Bergmann wrote:
>>>>
>>>> This seems wrong still: The clusters and cores do not have unique
>>>> numbers. I believe the code will not work correctly, and it won't
>>>> be compliant with the binding from patch 2.
>>>>
>>>> I think the right way here would be to use
>>>>
>>>>         arm,associativity = <0 2 47>;
>>>>
>>>> for cpu@20f, and
>>>>
>>>>         arm,associativity = <1 3 48>;
>>>>
>>>> for cpu@10000. Your previous version used the numbers from
>>>> the reg property, which should be fine as well if that helps:
>>>>
>>>>
>>>>         arm,associativity = <0x0 0x200 0x20f>;
>>>>
>>>>         arm,associativity = <0x10000 0x10000 0x10000>;
>>>>
>>>> which should have the same effect as above, as long as the code
>>>> can handle the numbers not being consecutive.
>>>>
>>>>
>>>
>>> Upon further consideration, I think your patch is correct after
>>> all, but let me check again on PowerPC machines.
>> i have removed, board id which was in previous patch, to keep the
>> associativity aligned to mpidr, ie. socket,cluster id and core id.
>> both previous and current mappings holds good for our design.
>> our topology is 2 sockets(aff2=0and 1) , each having 3
>> clusters(aff1=0to2)and each cluster having 16 cores(aff0:0to15)
>> in associativity property, for our case, only first id(socket id) is
>> mapped to numa, others are mentioned only to describe the topology.
>>>
>>>         Arnd
> any further comments, how we go about these patches?
> please suggest.
>
>> thanks
>> Ganapat
>
> thanks
> Ganapat
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
@ 2015-03-10  8:42                     ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-03-10  8:42 UTC (permalink / raw)
  To: linux-arm-kernel

Ping?

On Tue, Feb 24, 2015 at 2:22 PM, Ganapatrao Kulkarni
<gpkulkarni@gmail.com> wrote:
> Hi Arnd,
>
> On Fri, Jan 23, 2015 at 6:07 PM, Ganapatrao Kulkarni
> <gpkulkarni@gmail.com> wrote:
>> Hi Arnd,
>>
>> On Thu, Jan 22, 2015 at 11:56 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>>> On Thursday 22 January 2015 17:47:13 Arnd Bergmann wrote:
>>>>
>>>> This seems wrong still: The clusters and cores do not have unique
>>>> numbers. I believe the code will not work correctly, and it won't
>>>> be compliant with the binding from patch 2.
>>>>
>>>> I think the right way here would be to use
>>>>
>>>>         arm,associativity = <0 2 47>;
>>>>
>>>> for cpu at 20f, and
>>>>
>>>>         arm,associativity = <1 3 48>;
>>>>
>>>> for cpu at 10000. Your previous version used the numbers from
>>>> the reg property, which should be fine as well if that helps:
>>>>
>>>>
>>>>         arm,associativity = <0x0 0x200 0x20f>;
>>>>
>>>>         arm,associativity = <0x10000 0x10000 0x10000>;
>>>>
>>>> which should have the same effect as above, as long as the code
>>>> can handle the numbers not being consecutive.
>>>>
>>>>
>>>
>>> Upon further consideration, I think your patch is correct after
>>> all, but let me check again on PowerPC machines.
>> i have removed, board id which was in previous patch, to keep the
>> associativity aligned to mpidr, ie. socket,cluster id and core id.
>> both previous and current mappings holds good for our design.
>> our topology is 2 sockets(aff2=0and 1) , each having 3
>> clusters(aff1=0to2)and each cluster having 16 cores(aff0:0to15)
>> in associativity property, for our case, only first id(socket id) is
>> mapped to numa, others are mentioned only to describe the topology.
>>>
>>>         Arnd
> any further comments, how we go about these patches?
> please suggest.
>
>> thanks
>> Ganapat
>
> thanks
> Ganapat

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

* Re: [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
  2015-03-10  8:42                     ` Ganapatrao Kulkarni
@ 2015-03-18  4:02                         ` Ganapatrao Kulkarni
  -1 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-03-18  4:02 UTC (permalink / raw)
  To: Arnd Bergmann, Will Deacon, Catalin Marinas, Mark Rutland
  Cc: Ganapatrao Kulkarni,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Grant Likely,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Leif Lindholm, Roy Franz,
	Ard Biesheuvel, msalter-H+wXaHxf7aLQT0dZR+AlfA, Rob Herring,
	Steve Capper, Hanjun Guo, jchandra-dY08KVG/lbpWk0Htik3J/w,
	Al Stone, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	ddutile-H+wXaHxf7aLQT0dZR+AlfA

Hi Catalin, Will, Mark, Arnd

On Tue, Mar 10, 2015 at 2:12 PM, Ganapatrao Kulkarni
<gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Ping?
>
> On Tue, Feb 24, 2015 at 2:22 PM, Ganapatrao Kulkarni
> <gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> Hi Arnd,
>>
>> On Fri, Jan 23, 2015 at 6:07 PM, Ganapatrao Kulkarni
>> <gpkulkarni-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>>> Hi Arnd,
>>>
>>> On Thu, Jan 22, 2015 at 11:56 PM, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
>>>> On Thursday 22 January 2015 17:47:13 Arnd Bergmann wrote:
>>>>>
>>>>> This seems wrong still: The clusters and cores do not have unique
>>>>> numbers. I believe the code will not work correctly, and it won't
>>>>> be compliant with the binding from patch 2.
>>>>>
>>>>> I think the right way here would be to use
>>>>>
>>>>>         arm,associativity = <0 2 47>;
>>>>>
>>>>> for cpu@20f, and
>>>>>
>>>>>         arm,associativity = <1 3 48>;
>>>>>
>>>>> for cpu@10000. Your previous version used the numbers from
>>>>> the reg property, which should be fine as well if that helps:
>>>>>
>>>>>
>>>>>         arm,associativity = <0x0 0x200 0x20f>;
>>>>>
>>>>>         arm,associativity = <0x10000 0x10000 0x10000>;
>>>>>
>>>>> which should have the same effect as above, as long as the code
>>>>> can handle the numbers not being consecutive.
>>>>>
>>>>>
>>>>
>>>> Upon further consideration, I think your patch is correct after
>>>> all, but let me check again on PowerPC machines.
>>> i have removed, board id which was in previous patch, to keep the
>>> associativity aligned to mpidr, ie. socket,cluster id and core id.
>>> both previous and current mappings holds good for our design.
>>> our topology is 2 sockets(aff2=0and 1) , each having 3
>>> clusters(aff1=0to2)and each cluster having 16 cores(aff0:0to15)
>>> in associativity property, for our case, only first id(socket id) is
>>> mapped to numa, others are mentioned only to describe the topology.
>>>>
>>>>         Arnd
>> any further comments, how we go about these patches?
>> please suggest.
>>
>>> thanks
>>> Ganapat
>>
>> thanks
>> Ganapat

Please suggest how we go about these patches.
please share your review comments, if any changes needs to be done.


thanks
Ganapat
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
@ 2015-03-18  4:02                         ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-03-18  4:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Catalin, Will, Mark, Arnd

On Tue, Mar 10, 2015 at 2:12 PM, Ganapatrao Kulkarni
<gpkulkarni@gmail.com> wrote:
> Ping?
>
> On Tue, Feb 24, 2015 at 2:22 PM, Ganapatrao Kulkarni
> <gpkulkarni@gmail.com> wrote:
>> Hi Arnd,
>>
>> On Fri, Jan 23, 2015 at 6:07 PM, Ganapatrao Kulkarni
>> <gpkulkarni@gmail.com> wrote:
>>> Hi Arnd,
>>>
>>> On Thu, Jan 22, 2015 at 11:56 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>>>> On Thursday 22 January 2015 17:47:13 Arnd Bergmann wrote:
>>>>>
>>>>> This seems wrong still: The clusters and cores do not have unique
>>>>> numbers. I believe the code will not work correctly, and it won't
>>>>> be compliant with the binding from patch 2.
>>>>>
>>>>> I think the right way here would be to use
>>>>>
>>>>>         arm,associativity = <0 2 47>;
>>>>>
>>>>> for cpu at 20f, and
>>>>>
>>>>>         arm,associativity = <1 3 48>;
>>>>>
>>>>> for cpu at 10000. Your previous version used the numbers from
>>>>> the reg property, which should be fine as well if that helps:
>>>>>
>>>>>
>>>>>         arm,associativity = <0x0 0x200 0x20f>;
>>>>>
>>>>>         arm,associativity = <0x10000 0x10000 0x10000>;
>>>>>
>>>>> which should have the same effect as above, as long as the code
>>>>> can handle the numbers not being consecutive.
>>>>>
>>>>>
>>>>
>>>> Upon further consideration, I think your patch is correct after
>>>> all, but let me check again on PowerPC machines.
>>> i have removed, board id which was in previous patch, to keep the
>>> associativity aligned to mpidr, ie. socket,cluster id and core id.
>>> both previous and current mappings holds good for our design.
>>> our topology is 2 sockets(aff2=0and 1) , each having 3
>>> clusters(aff1=0to2)and each cluster having 16 cores(aff0:0to15)
>>> in associativity property, for our case, only first id(socket id) is
>>> mapped to numa, others are mentioned only to describe the topology.
>>>>
>>>>         Arnd
>> any further comments, how we go about these patches?
>> please suggest.
>>
>>> thanks
>>> Ganapat
>>
>> thanks
>> Ganapat

Please suggest how we go about these patches.
please share your review comments, if any changes needs to be done.


thanks
Ganapat

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

* Re: [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
  2015-03-18  4:02                         ` Ganapatrao Kulkarni
@ 2015-03-18 10:00                             ` Will Deacon
  -1 siblings, 0 replies; 36+ messages in thread
From: Will Deacon @ 2015-03-18 10:00 UTC (permalink / raw)
  To: Ganapatrao Kulkarni
  Cc: Arnd Bergmann, Catalin Marinas, Mark Rutland,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Steve Capper, Al Stone,
	Ard Biesheuvel, jcm-H+wXaHxf7aLQT0dZR+AlfA, Leif Lindholm,
	Roy Franz, Rob Herring, ddutile-H+wXaHxf7aLQT0dZR+AlfA,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
	msalter-H+wXaHxf7aLQT0dZR+AlfA,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Ganapatrao Kulkarni,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Wed, Mar 18, 2015 at 04:02:53AM +0000, Ganapatrao Kulkarni wrote:
> Hi Catalin, Will, Mark, Arnd

[...]

> Please suggest how we go about these patches.
> please share your review comments, if any changes needs to be done.

I can take the Kconfig patch if you send a version that applies cleanly.
As for the rest, you need an ack from a DT maintainer on the bindings
before anything else can get merged.

Will
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
@ 2015-03-18 10:00                             ` Will Deacon
  0 siblings, 0 replies; 36+ messages in thread
From: Will Deacon @ 2015-03-18 10:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 18, 2015 at 04:02:53AM +0000, Ganapatrao Kulkarni wrote:
> Hi Catalin, Will, Mark, Arnd

[...]

> Please suggest how we go about these patches.
> please share your review comments, if any changes needs to be done.

I can take the Kconfig patch if you send a version that applies cleanly.
As for the rest, you need an ack from a DT maintainer on the bindings
before anything else can get merged.

Will

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

* Re: [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
  2015-03-18 10:00                             ` Will Deacon
@ 2015-03-18 10:39                                 ` Ganapatrao Kulkarni
  -1 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-03-18 10:39 UTC (permalink / raw)
  To: Will Deacon
  Cc: Arnd Bergmann, Catalin Marinas, Mark Rutland,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Steve Capper, Al Stone,
	Ard Biesheuvel, jcm-H+wXaHxf7aLQT0dZR+AlfA, Leif Lindholm,
	Roy Franz, Rob Herring, ddutile-H+wXaHxf7aLQT0dZR+AlfA,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
	msalter-H+wXaHxf7aLQT0dZR+AlfA,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Ganapatrao Kulkarni,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Thanks Will.

On Wed, Mar 18, 2015 at 3:30 PM, Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org> wrote:
> On Wed, Mar 18, 2015 at 04:02:53AM +0000, Ganapatrao Kulkarni wrote:
>> Hi Catalin, Will, Mark, Arnd
>
> [...]
>
>> Please suggest how we go about these patches.
>> please share your review comments, if any changes needs to be done.
>
> I can take the Kconfig patch if you send a version that applies cleanly.
> As for the rest, you need an ack from a DT maintainer on the bindings
> before anything else can get merged.
i will send you Kconfig patch (i.e increase NR_CPUS range to 2-4096)
separately after rebasing to
linux-next, is that ok?
>
> Will
thanks
Ganapat
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
@ 2015-03-18 10:39                                 ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-03-18 10:39 UTC (permalink / raw)
  To: linux-arm-kernel

Thanks Will.

On Wed, Mar 18, 2015 at 3:30 PM, Will Deacon <will.deacon@arm.com> wrote:
> On Wed, Mar 18, 2015 at 04:02:53AM +0000, Ganapatrao Kulkarni wrote:
>> Hi Catalin, Will, Mark, Arnd
>
> [...]
>
>> Please suggest how we go about these patches.
>> please share your review comments, if any changes needs to be done.
>
> I can take the Kconfig patch if you send a version that applies cleanly.
> As for the rest, you need an ack from a DT maintainer on the bindings
> before anything else can get merged.
i will send you Kconfig patch (i.e increase NR_CPUS range to 2-4096)
separately after rebasing to
linux-next, is that ok?
>
> Will
thanks
Ganapat

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

* Re: [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
  2015-03-18 10:39                                 ` Ganapatrao Kulkarni
@ 2015-03-18 10:47                                     ` Will Deacon
  -1 siblings, 0 replies; 36+ messages in thread
From: Will Deacon @ 2015-03-18 10:47 UTC (permalink / raw)
  To: Ganapatrao Kulkarni
  Cc: Arnd Bergmann, Catalin Marinas, Mark Rutland,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Steve Capper, Al Stone,
	Ard Biesheuvel, jcm-H+wXaHxf7aLQT0dZR+AlfA, Leif Lindholm,
	Roy Franz, Rob Herring, ddutile-H+wXaHxf7aLQT0dZR+AlfA,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
	msalter-H+wXaHxf7aLQT0dZR+AlfA,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Ganapatrao Kulkarni,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Wed, Mar 18, 2015 at 10:39:43AM +0000, Ganapatrao Kulkarni wrote:
> On Wed, Mar 18, 2015 at 3:30 PM, Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org> wrote:
> > On Wed, Mar 18, 2015 at 04:02:53AM +0000, Ganapatrao Kulkarni wrote:
> >> Please suggest how we go about these patches.
> >> please share your review comments, if any changes needs to be done.
> >
> > I can take the Kconfig patch if you send a version that applies cleanly.
> > As for the rest, you need an ack from a DT maintainer on the bindings
> > before anything else can get merged.
> i will send you Kconfig patch (i.e increase NR_CPUS range to 2-4096)
> separately after rebasing to
> linux-next, is that ok?

Just base against -rc4 and I'll fix any conflicts that arise.

Will
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology.
@ 2015-03-18 10:47                                     ` Will Deacon
  0 siblings, 0 replies; 36+ messages in thread
From: Will Deacon @ 2015-03-18 10:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 18, 2015 at 10:39:43AM +0000, Ganapatrao Kulkarni wrote:
> On Wed, Mar 18, 2015 at 3:30 PM, Will Deacon <will.deacon@arm.com> wrote:
> > On Wed, Mar 18, 2015 at 04:02:53AM +0000, Ganapatrao Kulkarni wrote:
> >> Please suggest how we go about these patches.
> >> please share your review comments, if any changes needs to be done.
> >
> > I can take the Kconfig patch if you send a version that applies cleanly.
> > As for the rest, you need an ack from a DT maintainer on the bindings
> > before anything else can get merged.
> i will send you Kconfig patch (i.e increase NR_CPUS range to 2-4096)
> separately after rebasing to
> linux-next, is that ok?

Just base against -rc4 and I'll fix any conflicts that arise.

Will

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

* Re: [RFC PATCH v4 0/4] arm64:numa: Add numa support for arm64 platforms.
  2015-01-22 11:05 ` Ganapatrao Kulkarni
@ 2015-06-29 10:57     ` Ganapatrao Kulkarni
  -1 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-06-29 10:57 UTC (permalink / raw)
  To: Ganapatrao Kulkarni, Mark Rutland
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Will Deacon,
	Catalin Marinas, Grant Likely, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Leif Lindholm, Roy Franz, Ard Biesheuvel,
	msalter-H+wXaHxf7aLQT0dZR+AlfA, Rob Herring, Steve Capper,
	Hanjun Guo, jchandra-dY08KVG/lbpWk0Htik3J/w, Al Stone,
	Arnd Bergmann, jcm-H+wXaHxf7aLQT0dZR+AlfA,
	ddutile-H+wXaHxf7aLQT0dZR+AlfA, Prasun Kapoor,
	ddaney-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8

Hi Catalin, Will, Mark,

can you please have a look of numa patches and share your review comments.


thanks
Ganapat

On Thu, Jan 22, 2015 at 4:35 PM, Ganapatrao Kulkarni
<gkulkarni-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org> wrote:
> 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 to each other.
>
> v1:
> Initial patchset to support numa on arm64 platforms.
>
> Hi Arnd,
>    there are not many common functions to pull to of driver from
>    powerpc and arm.
>
> thanks
> Ganapat
>
> Ganapatrao Kulkarni (4):
>   arm64: defconfig: increase NR_CPUS range to 2-4096.
>   Documentation: arm64/arm: dt bindings for numa.
>   arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2     Node
>     topology.
>   arm64:numa: adding numa support for arm64 platforms.
>
>  Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++
>  arch/arm64/Kconfig                             |  36 +-
>  arch/arm64/boot/dts/thunder-88xx-2n.dts        |  78 +++
>  arch/arm64/boot/dts/thunder-88xx-2n.dtsi       | 790 +++++++++++++++++++++++++
>  arch/arm64/include/asm/mmzone.h                |  32 +
>  arch/arm64/include/asm/numa.h                  |  43 ++
>  arch/arm64/kernel/Makefile                     |   1 +
>  arch/arm64/kernel/dt_numa.c                    | 302 ++++++++++
>  arch/arm64/kernel/setup.c                      |   8 +
>  arch/arm64/kernel/smp.c                        |   2 +
>  arch/arm64/mm/Makefile                         |   1 +
>  arch/arm64/mm/init.c                           |  34 +-
>  arch/arm64/mm/numa.c                           | 522 ++++++++++++++++
>  13 files changed, 2053 insertions(+), 8 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
>  create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dts
>  create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dtsi
>  create mode 100644 arch/arm64/include/asm/mmzone.h
>  create mode 100644 arch/arm64/include/asm/numa.h
>  create mode 100644 arch/arm64/kernel/dt_numa.c
>  create mode 100644 arch/arm64/mm/numa.c
>
> --
> 1.8.1.4
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 0/4] arm64:numa: Add numa support for arm64 platforms.
@ 2015-06-29 10:57     ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-06-29 10:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Catalin, Will, Mark,

can you please have a look of numa patches and share your review comments.


thanks
Ganapat

On Thu, Jan 22, 2015 at 4:35 PM, Ganapatrao Kulkarni
<gkulkarni@caviumnetworks.com> wrote:
> 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 to each other.
>
> v1:
> Initial patchset to support numa on arm64 platforms.
>
> Hi Arnd,
>    there are not many common functions to pull to of driver from
>    powerpc and arm.
>
> thanks
> Ganapat
>
> Ganapatrao Kulkarni (4):
>   arm64: defconfig: increase NR_CPUS range to 2-4096.
>   Documentation: arm64/arm: dt bindings for numa.
>   arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2     Node
>     topology.
>   arm64:numa: adding numa support for arm64 platforms.
>
>  Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++
>  arch/arm64/Kconfig                             |  36 +-
>  arch/arm64/boot/dts/thunder-88xx-2n.dts        |  78 +++
>  arch/arm64/boot/dts/thunder-88xx-2n.dtsi       | 790 +++++++++++++++++++++++++
>  arch/arm64/include/asm/mmzone.h                |  32 +
>  arch/arm64/include/asm/numa.h                  |  43 ++
>  arch/arm64/kernel/Makefile                     |   1 +
>  arch/arm64/kernel/dt_numa.c                    | 302 ++++++++++
>  arch/arm64/kernel/setup.c                      |   8 +
>  arch/arm64/kernel/smp.c                        |   2 +
>  arch/arm64/mm/Makefile                         |   1 +
>  arch/arm64/mm/init.c                           |  34 +-
>  arch/arm64/mm/numa.c                           | 522 ++++++++++++++++
>  13 files changed, 2053 insertions(+), 8 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
>  create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dts
>  create mode 100644 arch/arm64/boot/dts/thunder-88xx-2n.dtsi
>  create mode 100644 arch/arm64/include/asm/mmzone.h
>  create mode 100644 arch/arm64/include/asm/numa.h
>  create mode 100644 arch/arm64/kernel/dt_numa.c
>  create mode 100644 arch/arm64/mm/numa.c
>
> --
> 1.8.1.4
>

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

* Re: [RFC PATCH v4 0/4] arm64:numa: Add numa support for arm64 platforms.
  2015-06-29 10:57     ` Ganapatrao Kulkarni
@ 2015-06-30 14:01         ` Will Deacon
  -1 siblings, 0 replies; 36+ messages in thread
From: Will Deacon @ 2015-06-30 14:01 UTC (permalink / raw)
  To: Ganapatrao Kulkarni
  Cc: Ganapatrao Kulkarni, Mark Rutland,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Catalin Marinas, grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Leif Lindholm, Roy Franz,
	Ard Biesheuvel, msalter-H+wXaHxf7aLQT0dZR+AlfA, Rob Herring,
	Steve Capper, hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Al Stone, Arnd Bergmann,
	jcm-H+wXaHxf7aLQT0dZR+AlfA, ddutile-H+wXaHxf7aLQT0dZR+AlfA,
	Prasun.Kapoor-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8, ddane

On Mon, Jun 29, 2015 at 11:57:49AM +0100, Ganapatrao Kulkarni wrote:
> Hi Catalin, Will, Mark,
> 
> can you please have a look of numa patches and share your review comments.

Nothing has changed since the last time you poked me about this series:

  - There are open comments from Hanjun
  - The device-tree part hasn't been reviewed by a DT maintainer

so I can't merge anything other than the Kconfig change atm.

Will
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 0/4] arm64:numa: Add numa support for arm64 platforms.
@ 2015-06-30 14:01         ` Will Deacon
  0 siblings, 0 replies; 36+ messages in thread
From: Will Deacon @ 2015-06-30 14:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 29, 2015 at 11:57:49AM +0100, Ganapatrao Kulkarni wrote:
> Hi Catalin, Will, Mark,
> 
> can you please have a look of numa patches and share your review comments.

Nothing has changed since the last time you poked me about this series:

  - There are open comments from Hanjun
  - The device-tree part hasn't been reviewed by a DT maintainer

so I can't merge anything other than the Kconfig change atm.

Will

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

* Re: [RFC PATCH v4 0/4] arm64:numa: Add numa support for arm64 platforms.
  2015-06-30 14:01         ` Will Deacon
@ 2015-06-30 14:22             ` Ganapatrao Kulkarni
  -1 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-06-30 14:22 UTC (permalink / raw)
  To: Will Deacon
  Cc: Ganapatrao Kulkarni, Mark Rutland,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Catalin Marinas, grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Leif Lindholm, Roy Franz,
	Ard Biesheuvel, msalter-H+wXaHxf7aLQT0dZR+AlfA, Rob Herring,
	Steve Capper, hanjun.guo-QSEj5FYQhm4dnm+yROfE0A,
	jchandra-dY08KVG/lbpWk0Htik3J/w, Al Stone, Arnd Bergmann,
	jcm-H+wXaHxf7aLQT0dZR+AlfA, ddutile-H+wXaHxf7aLQT0dZR+AlfA,
	Prasun.Kapoor-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8, ddane

Hi DT maintainers,

On Tue, Jun 30, 2015 at 7:31 PM, Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org> wrote:
> On Mon, Jun 29, 2015 at 11:57:49AM +0100, Ganapatrao Kulkarni wrote:
>> Hi Catalin, Will, Mark,
>>
>> can you please have a look of numa patches and share your review comments.
>
> Nothing has changed since the last time you poked me about this series:
>
>   - There are open comments from Hanjun
IIRC, already taken care, if any open points still, it will be taker
in next version.
>   - The device-tree part hasn't been reviewed by a DT maintainer
please review!
>
> so I can't merge anything other than the Kconfig change atm.
>
> Will

thanks
Ganapat
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [RFC PATCH v4 0/4] arm64:numa: Add numa support for arm64 platforms.
@ 2015-06-30 14:22             ` Ganapatrao Kulkarni
  0 siblings, 0 replies; 36+ messages in thread
From: Ganapatrao Kulkarni @ 2015-06-30 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi DT maintainers,

On Tue, Jun 30, 2015 at 7:31 PM, Will Deacon <will.deacon@arm.com> wrote:
> On Mon, Jun 29, 2015 at 11:57:49AM +0100, Ganapatrao Kulkarni wrote:
>> Hi Catalin, Will, Mark,
>>
>> can you please have a look of numa patches and share your review comments.
>
> Nothing has changed since the last time you poked me about this series:
>
>   - There are open comments from Hanjun
IIRC, already taken care, if any open points still, it will be taker
in next version.
>   - The device-tree part hasn't been reviewed by a DT maintainer
please review!
>
> so I can't merge anything other than the Kconfig change atm.
>
> Will

thanks
Ganapat

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

end of thread, other threads:[~2015-06-30 14:22 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-22 11:05 [RFC PATCH v4 0/4] arm64:numa: Add numa support for arm64 platforms Ganapatrao Kulkarni
2015-01-22 11:05 ` Ganapatrao Kulkarni
     [not found] ` <1421924755-26029-1-git-send-email-gkulkarni-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>
2015-01-22 11:05   ` [RFC PATCH v4 1/4] arm64: defconfig: increase NR_CPUS range to 2-4096 Ganapatrao Kulkarni
2015-01-22 11:05     ` Ganapatrao Kulkarni
2015-01-22 11:05   ` [RFC PATCH v4 2/4] Documentation: arm64/arm: dt bindings for numa Ganapatrao Kulkarni
2015-01-22 11:05     ` Ganapatrao Kulkarni
2015-01-22 11:05   ` [RFC PATCH v4 3/4] arm64:thunder: Add initial dts for Cavium's Thunder SoC in 2 Node topology Ganapatrao Kulkarni
2015-01-22 11:05     ` Ganapatrao Kulkarni
     [not found]     ` <1421924755-26029-4-git-send-email-gkulkarni-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>
2015-01-22 16:47       ` Arnd Bergmann
2015-01-22 16:47         ` Arnd Bergmann
2015-01-22 18:26         ` Arnd Bergmann
2015-01-22 18:26           ` Arnd Bergmann
2015-01-23 12:37           ` Ganapatrao Kulkarni
2015-01-23 12:37             ` Ganapatrao Kulkarni
     [not found]             ` <CAFpQJXUvux+b9hYx_ZY-1hor0HRFFgh=e4vCYyJiDHrDC9Y=tQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-02-24  8:52               ` Ganapatrao Kulkarni
2015-02-24  8:52                 ` Ganapatrao Kulkarni
     [not found]                 ` <CAFpQJXXkXatxRcfpA1DjuuiUf3vup3DV+dACyGxT=TDkrO8rNQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-10  8:42                   ` Ganapatrao Kulkarni
2015-03-10  8:42                     ` Ganapatrao Kulkarni
     [not found]                     ` <CAFpQJXVc5c=YRLw3uS5RiSR13veo_SUiM-aV6hf+diQuWxdfYQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-18  4:02                       ` Ganapatrao Kulkarni
2015-03-18  4:02                         ` Ganapatrao Kulkarni
     [not found]                         ` <CAFpQJXWL-NM+WndfB5pLj6TmdVngACR9YCr_ahaUTqAO3DaX1g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-18 10:00                           ` Will Deacon
2015-03-18 10:00                             ` Will Deacon
     [not found]                             ` <20150318100004.GC18951-5wv7dgnIgG8@public.gmane.org>
2015-03-18 10:39                               ` Ganapatrao Kulkarni
2015-03-18 10:39                                 ` Ganapatrao Kulkarni
     [not found]                                 ` <CAFpQJXWzhn=sFKOdbPGXGfQNr5outJodTH72RoC1VVYqt8jmdQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-18 10:47                                   ` Will Deacon
2015-03-18 10:47                                     ` Will Deacon
2015-06-29 10:57   ` [RFC PATCH v4 0/4] arm64:numa: Add numa support for arm64 platforms Ganapatrao Kulkarni
2015-06-29 10:57     ` Ganapatrao Kulkarni
     [not found]     ` <CAFpQJXXZc0sop601wrmTe5Ng0SiSGfT9AA2Dpf=X9bgGN9srrA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-06-30 14:01       ` Will Deacon
2015-06-30 14:01         ` Will Deacon
     [not found]         ` <20150630140123.GL27725-5wv7dgnIgG8@public.gmane.org>
2015-06-30 14:22           ` Ganapatrao Kulkarni
2015-06-30 14:22             ` Ganapatrao Kulkarni
2015-01-22 11:05 ` [RFC PATCH v4 4/4] arm64:numa: adding " Ganapatrao Kulkarni
2015-01-22 11:05   ` Ganapatrao Kulkarni
     [not found]   ` <1421924755-26029-5-git-send-email-gkulkarni-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org>
2015-02-27  9:08     ` Hanjun Guo
2015-02-27  9:08       ` Hanjun Guo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.