Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1382064 > unrolled thread
| Started by | David Daney <ddaney.cavm@gmail.com> |
|---|---|
| First post | 2016-04-18 23:20 +0200 |
| Last post | 2016-04-18 23:20 +0200 |
| Articles | 3 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH v4 00/14] ACPI NUMA support for ARM64 David Daney <ddaney.cavm@gmail.com> - 2016-04-18 23:20 +0200
[PATCH v4 05/14] acpi, numa: move acpi_numa_slit_init() to drivers/acpi/numa.c David Daney <ddaney.cavm@gmail.com> - 2016-04-18 23:20 +0200
[PATCH v4 12/14] arm64, acpi, numa: NUMA support based on SRAT and SLIT David Daney <ddaney.cavm@gmail.com> - 2016-04-18 23:20 +0200
| From | David Daney <ddaney.cavm@gmail.com> |
|---|---|
| Date | 2016-04-18 23:20 +0200 |
| Subject | [PATCH v4 00/14] ACPI NUMA support for ARM64 |
| Message-ID | <rpoKm-3Yo-27@gated-at.bofh.it> |
From: David Daney <david.daney@cavium.com>
Based on v16 of device-tree NUMA patch set for arm64 [1],this patch
set introduce the ACPI based configuration to provide NUMA
information.
ACPI 5.1 already introduced NUMA support for ARM64, which can get the
NUMA domain information from SRAT and SLIT table, so parse those two
tables to get mappings from cpu/mem to numa node configuration and
system locality.
v4 updates:
- Updated from Hanjun Guo's v3 patches.
- Rebased on top of v16 of device-tree NUMA patches.
- Reordered some of the changes so that we don't introduce code and
then change it several times in the patch set. New code is
introduced in its final form. Code reused from x86 is first moved
with no change, and then a separate patch to make any needed
changes.
- code that is used only by ia64, moved to architecture specific
files.
v3 updates:
- Deep investigation about the ACPI_DEBUG_PRINT() and remvoe
that for acpi/numa.c (patch 2/12)
- Remove the duplicate NULL check for table print (patch 3/12)
- Introduce CONFIG_ACPI_HAS_NUMA_ARCH_FIXUP to remove duplicate
dummy function for acpi_numa_arch_fixup()
- Solve the problem that the mapping from logical cpu to numa node
is wrong which spotted out by Lorenzo
- cleanups for x86 and move acpi_numa_slit_init() and some other
functions to common place, then reduce the duplicate of x86
and arm64 (patch 7-12/12).
- rebased on top of 4.4 and Ganapat's v9 patch set.
[1]: https://lkml.org/lkml/2016/4/8/571
David Daney (1):
acpi, numa, srat: Improve SRAT error detection and add messages.
Hanjun Guo (11):
acpi, numa: Use pr_fmt() instead of printk
acpi, numa: Replace ACPI_DEBUG_PRINT() with pr_debug()
acpi, numa: remove duplicate NULL check
acpi, numa: move acpi_numa_slit_init() to drivers/acpi/numa.c
arm64, numa: rework numa_add_memblk()
x86, acpi, numa: cleanup acpi_numa_processor_affinity_init()
acpi, numa: move bad_srat() and srat_disabled() to
drivers/acpi/numa.c
acpi, numa: remove unneeded acpi_numa=1
acpi, numa: Move acpi_numa_memory_affinity_init() to
drivers/acpi/numa.c
arm64, acpi, numa: NUMA support based on SRAT and SLIT
acpi, numa: Enable ACPI based NUMA on ARM64
Robert Richter (2):
acpi, numa: Move acpi_numa_arch_fixup() to ia64 only
arm64, acpi, numa: Default enable ACPI_NUMA with NUMA
arch/arm64/include/asm/acpi.h | 8 ++
arch/arm64/include/asm/numa.h | 2 +
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/acpi_numa.c | 149 +++++++++++++++++++++++++++++
arch/arm64/kernel/smp.c | 2 +
arch/arm64/mm/numa.c | 17 ++--
arch/ia64/include/asm/acpi.h | 3 +
arch/ia64/kernel/acpi.c | 2 +-
arch/ia64/kernel/setup.c | 1 +
arch/x86/include/asm/acpi.h | 1 -
arch/x86/mm/numa.c | 2 +-
arch/x86/mm/srat.c | 115 +----------------------
drivers/acpi/Kconfig | 4 +-
drivers/acpi/numa.c | 211 +++++++++++++++++++++++++++++++-----------
drivers/of/of_numa.c | 4 +-
include/acpi/acpi_numa.h | 12 +++
include/linux/acpi.h | 18 +++-
17 files changed, 370 insertions(+), 182 deletions(-)
create mode 100644 arch/arm64/kernel/acpi_numa.c
--
1.7.11.7
[toc] | [next] | [standalone]
| From | David Daney <ddaney.cavm@gmail.com> |
|---|---|
| Date | 2016-04-18 23:20 +0200 |
| Subject | [PATCH v4 05/14] acpi, numa: move acpi_numa_slit_init() to drivers/acpi/numa.c |
| Message-ID | <rpoKu-3Yo-177@gated-at.bofh.it> |
| In reply to | #1382064 |
From: Hanjun Guo <hanjun.guo@linaro.org>
Identical implementations of acpi_numa_slit_init() are used by both
x86 and follow-on arm64 support. Move it to drivers/acpi/numa.c, and
mark it as __weak because ia64 has its own architecture specific
implementation.
No code change.
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: David Daney <david.daney@cavium.com>
---
arch/x86/mm/srat.c | 27 ---------------------------
drivers/acpi/numa.c | 27 +++++++++++++++++++++++++++
2 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c
index 90b6ed9..f242a11 100644
--- a/arch/x86/mm/srat.c
+++ b/arch/x86/mm/srat.c
@@ -42,33 +42,6 @@ static __init inline int srat_disabled(void)
return acpi_numa < 0;
}
-/*
- * Callback for SLIT parsing. pxm_to_node() returns NUMA_NO_NODE for
- * I/O localities since SRAT does not list them. I/O localities are
- * not supported at this point.
- */
-void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
-{
- int i, j;
-
- for (i = 0; i < slit->locality_count; i++) {
- const int from_node = pxm_to_node(i);
-
- if (from_node == NUMA_NO_NODE)
- continue;
-
- for (j = 0; j < slit->locality_count; j++) {
- const int to_node = pxm_to_node(j);
-
- if (to_node == NUMA_NO_NODE)
- continue;
-
- numa_set_distance(from_node, to_node,
- slit->entry[slit->locality_count * i + j]);
- }
- }
-}
-
/* Callback for Proximity Domain -> x2APIC mapping */
void __init
acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index f41f06b..5403d62 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -197,6 +197,33 @@ static int __init slit_valid(struct acpi_table_slit *slit)
return 1;
}
+/*
+ * Callback for SLIT parsing. pxm_to_node() returns NUMA_NO_NODE for
+ * I/O localities since SRAT does not list them. I/O localities are
+ * not supported at this point.
+ */
+void __init __weak acpi_numa_slit_init(struct acpi_table_slit *slit)
+{
+ int i, j;
+
+ for (i = 0; i < slit->locality_count; i++) {
+ const int from_node = pxm_to_node(i);
+
+ if (from_node == NUMA_NO_NODE)
+ continue;
+
+ for (j = 0; j < slit->locality_count; j++) {
+ const int to_node = pxm_to_node(j);
+
+ if (to_node == NUMA_NO_NODE)
+ continue;
+
+ numa_set_distance(from_node, to_node,
+ slit->entry[slit->locality_count * i + j]);
+ }
+ }
+}
+
static int __init acpi_parse_slit(struct acpi_table_header *table)
{
struct acpi_table_slit *slit = (struct acpi_table_slit *)table;
--
1.7.11.7
[toc] | [prev] | [next] | [standalone]
| From | David Daney <ddaney.cavm@gmail.com> |
|---|---|
| Date | 2016-04-18 23:20 +0200 |
| Subject | [PATCH v4 12/14] arm64, acpi, numa: NUMA support based on SRAT and SLIT |
| Message-ID | <rpoKB-3Yo-279@gated-at.bofh.it> |
| In reply to | #1382064 |
From: Hanjun Guo <hanjun.guo@linaro.org>
Introduce a new file to hold ACPI based NUMA information parsing from
SRAT and SLIT.
SRAT includes the CPU ACPI ID to Proximity Domain mappings and memory
ranges to Proximity Domain mapping. SLIT has the information of inter
node distances(relative number for access latency).
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
Signed-off-by: Ganapatrao Kulkarni <gkulkarni@caviumnetworks.com>
[rrichter@cavium.com Reworked for numa v10 series ]
Signed-off-by: Robert Richter <rrichter@cavium.com>
[david.daney@cavium.com reorderd and combinded with other patches in Hanjun Guo's original set]
Signed-off-by: David Daney <david.daney@cavium.com>
---
arch/arm64/include/asm/acpi.h | 8 +++
arch/arm64/include/asm/numa.h | 2 +
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/acpi_numa.c | 149 ++++++++++++++++++++++++++++++++++++++++++
arch/arm64/kernel/smp.c | 2 +
arch/arm64/mm/numa.c | 5 +-
6 files changed, 166 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/kernel/acpi_numa.c
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index aee323b..4b13ecd 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -113,4 +113,12 @@ static inline const char *acpi_get_enable_method(int cpu)
pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr);
#endif
+#ifdef CONFIG_ACPI_NUMA
+int arm64_acpi_numa_init(void);
+int acpi_numa_get_nid(unsigned int cpu, u64 hwid);
+#else
+static inline int arm64_acpi_numa_init(void) { return -ENOSYS; }
+static inline int acpi_numa_get_nid(unsigned int cpu, u64 hwid) { return NUMA_NO_NODE; }
+#endif /* CONFIG_ACPI_NUMA */
+
#endif /*_ASM_ACPI_H*/
diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h
index e9b4f29..600887e 100644
--- a/arch/arm64/include/asm/numa.h
+++ b/arch/arm64/include/asm/numa.h
@@ -5,6 +5,8 @@
#ifdef CONFIG_NUMA
+#define NR_NODE_MEMBLKS (MAX_NUMNODES * 2)
+
/* currently, arm64 implements flat NUMA topology */
#define parent_node(node) (node)
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 3793003..69569c6 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -42,6 +42,7 @@ arm64-obj-$(CONFIG_EFI) += efi.o efi-entry.stub.o
arm64-obj-$(CONFIG_PCI) += pci.o
arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o
arm64-obj-$(CONFIG_ACPI) += acpi.o
+arm64-obj-$(CONFIG_ACPI_NUMA) += acpi_numa.o
arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o
arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o
arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c
new file mode 100644
index 0000000..fd72070
--- /dev/null
+++ b/arch/arm64/kernel/acpi_numa.c
@@ -0,0 +1,149 @@
+/*
+ * ACPI 5.1 based NUMA setup for ARM64
+ * Lots of code was borrowed from arch/x86/mm/srat.c
+ *
+ * Copyright 2004 Andi Kleen, SuSE Labs.
+ * Copyright (C) 2013-2016, Linaro Ltd.
+ * Author: Hanjun Guo <hanjun.guo@linaro.org>
+ *
+ * Reads the ACPI SRAT table to figure out what memory belongs to which CPUs.
+ *
+ * Called from acpi_numa_init while reading the SRAT and SLIT tables.
+ * Assumes all memory regions belonging to a single proximity domain
+ * are in one chunk. Holes between them will be included in the node.
+ */
+
+#define pr_fmt(fmt) "ACPI: NUMA: " fmt
+
+#include <linux/acpi.h>
+#include <linux/bitmap.h>
+#include <linux/bootmem.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/memblock.h>
+#include <linux/mmzone.h>
+#include <linux/module.h>
+#include <linux/topology.h>
+
+#include <acpi/processor.h>
+#include <asm/numa.h>
+
+static int cpus_in_srat;
+
+struct __node_cpu_hwid {
+ u32 node_id; /* logical node containing this CPU */
+ u64 cpu_hwid; /* MPIDR for this CPU */
+};
+
+static struct __node_cpu_hwid early_node_cpu_hwid[NR_CPUS] = {
+[0 ... NR_CPUS - 1] = {NUMA_NO_NODE, PHYS_CPUID_INVALID} };
+
+int acpi_numa_get_nid(unsigned int cpu, u64 hwid)
+{
+ int i;
+
+ for (i = 0; i < cpus_in_srat; i++) {
+ if (hwid == early_node_cpu_hwid[i].cpu_hwid)
+ return early_node_cpu_hwid[i].node_id;
+ }
+
+ return NUMA_NO_NODE;
+}
+
+static int __init get_mpidr_in_madt(int acpi_id, u64 *mpidr)
+{
+ unsigned long madt_end, entry;
+ struct acpi_table_madt *madt;
+ acpi_size tbl_size;
+
+ if (ACPI_FAILURE(acpi_get_table_with_size(ACPI_SIG_MADT, 0,
+ (struct acpi_table_header **)&madt, &tbl_size)))
+ return -ENODEV;
+
+ entry = (unsigned long)madt;
+ madt_end = entry + madt->header.length;
+
+ /* Parse all entries looking for a match. */
+ entry += sizeof(struct acpi_table_madt);
+ while (entry + sizeof(struct acpi_subtable_header) < madt_end) {
+ struct acpi_subtable_header *header =
+ (struct acpi_subtable_header *)entry;
+
+ if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
+ struct acpi_madt_generic_interrupt *gicc =
+ container_of(header,
+ struct acpi_madt_generic_interrupt, header);
+
+ if ((gicc->flags & ACPI_MADT_ENABLED) &&
+ (gicc->uid == acpi_id)) {
+ *mpidr = gicc->arm_mpidr;
+ early_acpi_os_unmap_memory(madt, tbl_size);
+ return 0;
+ }
+ }
+ entry += header->length;
+ }
+
+ early_acpi_os_unmap_memory(madt, tbl_size);
+ return -ENODEV;
+}
+
+/* Callback for Proximity Domain -> ACPI processor UID mapping */
+void __init acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa)
+{
+ int pxm, node;
+ u64 mpidr;
+
+ if (srat_disabled())
+ return;
+
+ if (pa->header.length < sizeof(struct acpi_srat_gicc_affinity)) {
+ pr_err("SRAT: Invalid SRAT header length: %d\n",
+ pa->header.length);
+ bad_srat();
+ return;
+ }
+
+ if (!(pa->flags & ACPI_SRAT_GICC_ENABLED))
+ return;
+
+ if (cpus_in_srat >= NR_CPUS) {
+ pr_warn_once("SRAT: cpu_to_node_map[%d] is too small, may not be able to use all cpus\n",
+ NR_CPUS);
+ return;
+ }
+
+ pxm = pa->proximity_domain;
+ node = acpi_map_pxm_to_node(pxm);
+
+ if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) {
+ pr_err("SRAT: Too many proximity domains %d\n", pxm);
+ bad_srat();
+ return;
+ }
+
+ if (get_mpidr_in_madt(pa->acpi_processor_uid, &mpidr)) {
+ pr_err("SRAT: PXM %d with ACPI ID %d has no valid MPIDR in MADT\n",
+ pxm, pa->acpi_processor_uid);
+ bad_srat();
+ return;
+ }
+
+ early_node_cpu_hwid[cpus_in_srat].node_id = node;
+ early_node_cpu_hwid[cpus_in_srat].cpu_hwid = mpidr;
+ node_set(node, numa_nodes_parsed);
+ cpus_in_srat++;
+ pr_info("SRAT: PXM %d -> MPIDR 0x%Lx -> Node %d cpu %d\n",
+ pxm, mpidr, node, cpus_in_srat);
+}
+
+int __init arm64_acpi_numa_init(void)
+{
+ int ret;
+
+ ret = acpi_numa_init();
+ if (ret)
+ return ret;
+
+ return srat_disabled() ? -EINVAL : 0;
+}
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index bebc4c6..6c7ef8f 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -524,6 +524,8 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
*/
acpi_set_mailbox_entry(cpu_count, processor);
+ early_map_cpu_to_node(cpu_count, acpi_numa_get_nid(cpu_count, hwid));
+
cpu_count++;
}
diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
index 6cb03f9..fc15186 100644
--- a/arch/arm64/mm/numa.c
+++ b/arch/arm64/mm/numa.c
@@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/acpi.h>
#include <linux/bootmem.h>
#include <linux/memblock.h>
#include <linux/module.h>
@@ -388,7 +389,9 @@ static int __init dummy_numa_init(void)
void __init arm64_numa_init(void)
{
if (!numa_off) {
- if (!numa_init(of_numa_init))
+ if (!acpi_disabled && !numa_init(arm64_acpi_numa_init))
+ return;
+ if (acpi_disabled && !numa_init(of_numa_init))
return;
}
--
1.7.11.7
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web