[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 |