hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8PG0C CVE: NA
--------------------------------
'node_reclaim_distance' affects scheduling behavior and memory reclamation, but the value is currently the default value and can not be set.
Now introduce the way to adjust 'node_reclaim_distance' depending on the cpu model.
Signed-off-by: Hui Tang tanghui20@huawei.com --- arch/arm64/Kconfig | 13 ++++++++ arch/arm64/mm/numa.c | 79 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index c5eca65c27fc..99fa1b145f32 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -2102,6 +2102,19 @@ config STACKPROTECTOR_PER_TASK def_bool y depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_SYSREG
+config ARCH_CUSTOM_NUMA_DISTANCE + bool "Support custom node relaim distance" + depends on ARM64 && ARCH_HISI && NUMA + default n + help + Allow arch to adjust node_reclaim_distance. + + Some machines may have a specific node distance to achieve optimal + system performance. You can set a specific node_reclaim_distance based + on the system topology. + + If unsure, say N. + menuconfig ASCEND_FEATURES bool "Support Ascend Features" depends on ARM64 diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c index 480fcfb1b917..dd72f25452c1 100644 --- a/arch/arm64/mm/numa.c +++ b/arch/arm64/mm/numa.c @@ -554,6 +554,83 @@ static int __init numa_register_nodes(void) return 0; }
+#ifdef CONFIG_ARCH_CUSTOM_NUMA_DISTANCE +#define DISTANCE_MAX (1 << DISTANCE_BITS) +static void get_numa_distance_info(int *numa_levels, int *max_distance) +{ + DECLARE_BITMAP(distance_map, DISTANCE_MAX); + int max = 0; + int i, j; + + bitmap_zero(distance_map, DISTANCE_MAX); + for (i = 0; i < nr_node_ids; i++) { + for (j = 0; j < nr_node_ids; j++) { + int distance = node_distance(i, j); + + if (distance < LOCAL_DISTANCE || + distance >= DISTANCE_MAX) { + return; + } + + if (distance > max) + max = distance; + + bitmap_set(distance_map, distance, 1); + } + } + + if (numa_levels) + *numa_levels = bitmap_weight(distance_map, DISTANCE_MAX); + + if (max_distance) + *max_distance = max; +} + +static int __init node_reclaim_distance_setup(char *str) +{ + int val; + + if (kstrtoint(str, 0, &val)) + return 0; + + if (val < LOCAL_DISTANCE || val >= DISTANCE_MAX) + return 0; + + if (val != RECLAIM_DISTANCE) { + node_reclaim_distance = val; + pr_info("Force set node_reclaim_distance to %d\n", val); + } + + return 0; +} +early_param("node_reclaim_distance", node_reclaim_distance_setup); + +static void __init node_reclaim_distance_adjust(void) +{ + unsigned int model = read_cpuid_id() & MIDR_CPU_MODEL_MASK; + int max_distance = 0; + int numa_levels = 0; + + switch (model) { + case MIDR_HISI_TSV200: + get_numa_distance_info(&numa_levels, &max_distance); + if (nr_node_ids != 4 || numa_levels <= 3 || + node_reclaim_distance != RECLAIM_DISTANCE || + max_distance <= RECLAIM_DISTANCE) + break; + + node_reclaim_distance = max_distance; + pr_info("Force adjust node_reclaim_distance to %d\n", + node_reclaim_distance); + break; + default: + break; + } +} +#else +static inline void __init node_reclaim_distance_adjust(void) {} +#endif + static int __init numa_init(int (*init_func)(void)) { int ret; @@ -582,6 +659,8 @@ static int __init numa_init(int (*init_func)(void))
setup_node_to_cpumask_map();
+ node_reclaim_distance_adjust(); + return 0; out_free_distance: numa_free_distance();