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 ++++++ drivers/base/arch_numa.c | 85 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 2712d3c73719..924371de001f 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1582,6 +1582,19 @@ config NUMA_AWARE_SPINLOCKS
Say N if you want absolute first come first serve fairness.
+config ARCH_CUSTOM_NUMA_DISTANCE + bool "Support custom node relaim distance" + depends on 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. + source "kernel/Kconfig.hz"
config ARCH_SPARSEMEM_ENABLE diff --git a/drivers/base/arch_numa.c b/drivers/base/arch_numa.c index 5b59d133b6af..96281de7010d 100644 --- a/drivers/base/arch_numa.c +++ b/drivers/base/arch_numa.c @@ -189,6 +189,89 @@ void __init setup_per_cpu_areas(void) } #endif
+#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 -EINVAL; + + if (val < LOCAL_DISTANCE || val >= DISTANCE_MAX) + return -EINVAL; + + 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_LINXICORE9100: + get_numa_distance_info(&numa_levels, &max_distance); + + /* + * When numa_level more than three, sched domain may be + * asymmetrical, the number of CPUs of sched group is different + * from the brother in sched domain. + */ + 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 + /** * numa_add_memblk() - Set node id to memblk * @nid: NUMA node ID of the new memblk @@ -401,6 +484,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();