|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2 03/17] xen/arm: implement node distance helpers for Arm
We will parse NUMA nodes distances from device tree. So we need
a matrix to record the distances between any two nodes we parsed.
Accordingly, we provide this node_set_distance API for device tree
NUMA to set the distance for any two nodes in this patch. When
NUMA initialization failed, __node_distance will return
NUMA_REMOTE_DISTANCE, this will help us avoid doing rollback
for distance maxtrix when NUMA initialization failed.
As both x86 and Arm have implemented __node_distance, so we move
its definition from asm/numa.h to xen/numa.h. At same time, the
outdated u8 return value of x86 has been changed to unsigned char.
Signed-off-by: Wei Chen <wei.chen@xxxxxxx>
---
v1 -> v2:
1. Use unsigned int/char instead of uint32_t/u8.
2. Re-org the commit message.
---
xen/arch/arm/Makefile | 1 +
xen/arch/arm/include/asm/numa.h | 14 +++++++++
xen/arch/arm/numa.c | 52 ++++++++++++++++++++++++++++++++-
xen/arch/x86/include/asm/numa.h | 1 -
xen/arch/x86/srat.c | 2 +-
xen/include/xen/numa.h | 1 +
6 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 4d076b278b..9073398d6e 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_LIVEPATCH) += livepatch.o
obj-y += mem_access.o
obj-y += mm.o
obj-y += monitor.o
+obj-$(CONFIG_NUMA) += numa.o
obj-y += p2m.o
obj-y += percpu.o
obj-y += platform.o
diff --git a/xen/arch/arm/include/asm/numa.h b/xen/arch/arm/include/asm/numa.h
index 52ca414e47..dbdb632711 100644
--- a/xen/arch/arm/include/asm/numa.h
+++ b/xen/arch/arm/include/asm/numa.h
@@ -28,6 +28,20 @@ enum dt_numa_status {
DT_NUMA_OFF,
};
+/*
+ * In ACPI spec, 0-9 are the reserved values for node distance,
+ * 10 indicates local node distance, 20 indicates remote node
+ * distance. Set node distance map in device tree will follow
+ * the ACPI's definition.
+ */
+#define NUMA_DISTANCE_UDF_MIN 0
+#define NUMA_DISTANCE_UDF_MAX 9
+#define NUMA_LOCAL_DISTANCE 10
+#define NUMA_REMOTE_DISTANCE 20
+
+extern void numa_set_distance(nodeid_t from, nodeid_t to,
+ unsigned int distance);
+
#else
/* Fake one node for now. See also node_online_map. */
diff --git a/xen/arch/arm/numa.c b/xen/arch/arm/numa.c
index 1c02b6a25d..34851ceacf 100644
--- a/xen/arch/arm/numa.c
+++ b/xen/arch/arm/numa.c
@@ -2,7 +2,7 @@
/*
* Arm Architecture support layer for NUMA.
*
- * Copyright (C) 2021 Arm Ltd
+ * Copyright (C) 2022 Arm Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -22,6 +22,11 @@
static enum dt_numa_status __read_mostly device_tree_numa;
+static unsigned char __read_mostly
+node_distance_map[MAX_NUMNODES][MAX_NUMNODES] = {
+ { 0 }
+};
+
void __init numa_fw_bad(void)
{
printk(KERN_ERR "NUMA: device tree numa info table not used.\n");
@@ -42,3 +47,48 @@ int __init arch_numa_setup(const char *opt)
{
return -EINVAL;
}
+
+void __init numa_set_distance(nodeid_t from, nodeid_t to,
+ unsigned int distance)
+{
+ if ( from >= MAX_NUMNODES || to >= MAX_NUMNODES )
+ {
+ printk(KERN_WARNING
+ "NUMA: invalid nodes: from=%"PRIu8" to=%"PRIu8" MAX=%"PRIu8"\n",
+ from, to, MAX_NUMNODES);
+ return;
+ }
+
+ /* NUMA defines 0xff as an unreachable node and 0-9 are undefined */
+ if ( distance >= NUMA_NO_DISTANCE ||
+ (distance >= NUMA_DISTANCE_UDF_MIN &&
+ distance <= NUMA_DISTANCE_UDF_MAX) ||
+ (from == to && distance != NUMA_LOCAL_DISTANCE) )
+ {
+ printk(KERN_WARNING
+ "NUMA: invalid distance: from=%"PRIu8" to=%"PRIu8"
distance=%"PRIu32"\n",
+ from, to, distance);
+ return;
+ }
+
+ node_distance_map[from][to] = distance;
+}
+
+unsigned char __node_distance(nodeid_t from, nodeid_t to)
+{
+ /* When NUMA is off, any distance will be treated as remote. */
+ if ( numa_disabled() )
+ return NUMA_REMOTE_DISTANCE;
+
+ /*
+ * Check whether the nodes are in the matrix range.
+ * When any node is out of range, except from and to nodes are the
+ * same, we treat them as unreachable (return 0xFF)
+ */
+ if ( from >= MAX_NUMNODES || to >= MAX_NUMNODES )
+ return from == to ? NUMA_LOCAL_DISTANCE : NUMA_NO_DISTANCE;
+
+ return node_distance_map[from][to];
+}
+
+EXPORT_SYMBOL(__node_distance);
diff --git a/xen/arch/x86/include/asm/numa.h b/xen/arch/x86/include/asm/numa.h
index 61efe60a95..18b71ddfef 100644
--- a/xen/arch/x86/include/asm/numa.h
+++ b/xen/arch/x86/include/asm/numa.h
@@ -21,7 +21,6 @@ extern void init_cpu_to_node(void);
#define arch_want_default_dmazone() (num_online_nodes() > 1)
void srat_parse_regions(paddr_t addr);
-extern u8 __node_distance(nodeid_t a, nodeid_t b);
unsigned int arch_get_dma_bitsize(void);
#endif
diff --git a/xen/arch/x86/srat.c b/xen/arch/x86/srat.c
index 56749ddca5..50faf5d352 100644
--- a/xen/arch/x86/srat.c
+++ b/xen/arch/x86/srat.c
@@ -328,7 +328,7 @@ unsigned int numa_node_to_arch_nid(nodeid_t n)
return 0;
}
-u8 __node_distance(nodeid_t a, nodeid_t b)
+unsigned char __node_distance(nodeid_t a, nodeid_t b)
{
unsigned index;
u8 slit_val;
diff --git a/xen/include/xen/numa.h b/xen/include/xen/numa.h
index 7d7aeb3a3c..cff4fb8ccc 100644
--- a/xen/include/xen/numa.h
+++ b/xen/include/xen/numa.h
@@ -115,6 +115,7 @@ extern bool numa_memblks_available(void);
extern bool numa_update_node_memblks(nodeid_t node, unsigned int arch_nid,
paddr_t start, paddr_t size, bool
hotplug);
extern void numa_set_processor_nodes_parsed(nodeid_t node);
+extern unsigned char __node_distance(nodeid_t a, nodeid_t b);
#else
--
2.25.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |