diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 851d24a35e4e1b45bef309557c960e1ebda48985..f87b6fd26e0f48891a1f7043f12b6b8337f34e3f 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -2115,6 +2115,11 @@ config STACKPROTECTOR_PER_TASK def_bool y depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_SYSREG +config ARCH_CUSTOM_NUMA_DISTANCE + bool "Support custom far numa distance" + depends on ARCH_HISI + default n + menuconfig ASCEND_FEATURES bool "Support Ascend Features" depends on ARM64 diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h index 43bfff72a32f1527c4d9ca45c3b07974051b6e3b..3af06fa3e969f0508f224469743cfb90c760e8c6 100644 --- a/arch/arm64/include/asm/numa.h +++ b/arch/arm64/include/asm/numa.h @@ -43,6 +43,7 @@ void __init early_map_cpu_to_node(unsigned int cpu, int nid); void numa_store_cpu_info(unsigned int cpu); void numa_add_cpu(unsigned int cpu); void numa_remove_cpu(unsigned int cpu); +bool arch_numa_distance_is_far(int distance, int numa_levels); #else /* CONFIG_NUMA */ diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c index 480fcfb1b917ac8d3159b78173cca93fcc8ef503..871394038ae0839fe2cc81b8f6ac875419acd705 100644 --- a/arch/arm64/mm/numa.c +++ b/arch/arm64/mm/numa.c @@ -619,6 +619,46 @@ static int __init dummy_numa_init(void) return 0; } +#ifdef CONFIG_ARCH_CUSTOM_NUMA_DISTANCE +static int arch_custom_numa_distance_flag = 1; +static int __init arch_custom_numa_distance_flag_setup(char *str) +{ + int val; + + if (kstrtoint(str, 0, &val)) + pr_warn("Unable to set arch_custom_numa_distance\n"); + + if (val != 0 || val != 1) + return 1; + + arch_custom_numa_distance_flag = val; + return 1; +} +early_param("arch_custom_numa_distance_flag=", arch_custom_numa_distance_flag_setup); + +bool arch_numa_distance_is_far(int distance, int numa_levels) +{ + unsigned int model = read_cpuid_id() & MIDR_CPU_MODEL_MASK; + int far_numa_distance = node_reclaim_distance; + + if (arch_custom_numa_distance_flag == 0) + return distance > node_reclaim_distance; + + switch (model) { + case MIDR_HISI_TSV200: + if (nr_node_ids != 4 || numa_levels <= 3) + break; + + far_numa_distance = 40; + break; + default: + break; + } + + return distance > far_numa_distance; +} +#endif + /** * arm64_numa_init() - Initialize NUMA * diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index e7413d6dd75b88ee50d0ef655ed15598b582fd86..fb6f20956ee774ae0b9ae74770439d04cb976c3d 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c @@ -1529,6 +1529,12 @@ int sched_max_numa_distance; static int *sched_domains_numa_distance; static struct cpumask ***sched_domains_numa_masks; int __read_mostly node_reclaim_distance = RECLAIM_DISTANCE; + +#ifdef CONFIG_ARCH_CUSTOM_NUMA_DISTANCE +static inline bool arch_numa_distance_is_far(int distance, int numa_levels) { + return distance > node_reclaim_distance; +} +#endif #endif /* @@ -1640,7 +1646,8 @@ sd_init(struct sched_domain_topology_level *tl, sd->flags &= ~SD_PREFER_SIBLING; sd->flags |= SD_SERIALIZE; - if (sched_domains_numa_distance[tl->numa_level] > node_reclaim_distance) { + if (arch_numa_distance_is_far(tl->numa_level, + sched_domains_numa_levels)) { sd->flags &= ~(SD_BALANCE_EXEC | SD_BALANCE_FORK | SD_WAKE_AFFINE);