diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 553dfbac6e4dc1b0ef30d39ea3d50541a351aaa7..da5ba498c9d675de38af59170a92b479cef9ff7b 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -189,6 +189,7 @@ CONFIG_USER_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y CONFIG_SCHED_STEAL=y +CONFIG_SCHED_KEEP_ON_CORE=y CONFIG_CHECKPOINT_RESTORE=y CONFIG_SCHED_AUTOGROUP=y # CONFIG_SYSFS_DEPRECATED is not set diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 5cd5b3c579d3735bfb8109f57bfb590dc59b3359..09214349bddfcc98609be2e2ad64cb21a0030865 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -35,6 +35,10 @@ extern unsigned int sysctl_sched_child_runs_first; extern int sysctl_sched_util_low_pct; #endif +#ifdef CONFIG_SCHED_KEEP_ON_CORE +extern int sysctl_sched_util_ratio; +#endif + #ifdef CONFIG_QOS_SCHED_SMART_GRID extern unsigned int sysctl_smart_grid_strategy_ctrl; extern int sysctl_affinity_adjust_delay_ms; diff --git a/init/Kconfig b/init/Kconfig index e552194efbeacebaec67a3fb6644ac7f7152dc97..9dcc127047296cf828d2df37286ad8fa7e8f8d2a 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1370,6 +1370,18 @@ config SCHED_STEAL If unsure, say N here. +config SCHED_KEEP_ON_CORE + bool "Prefer physical cores when migrating tasks" + depends on SCHED_SMT + default n + help + When cpu hyperthreading is enabled, one physical core can virtualize + multiple logical cpus. Assume that physical core0 virtualizes two + logical cpus, cpu0 and cpu1. Only when the load of cpu0 exceeds the + ratio to the capacity of cpu0, the task will be migrated to the cpu1, + otherwise the task will not be migrated and the cpu0 will still be + used. + config CHECKPOINT_RESTORE bool "Checkpoint/restore support" select PROC_CHILDREN diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 95d1841f8a208579cfc80042dded8739a5d3e9e3..8dc1d2afe1b7a3853886d0fc8b152e84bf789d84 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7242,6 +7242,20 @@ static int select_idle_core(struct task_struct *p, int core, struct cpumask *cpu return -1; } +#ifdef CONFIG_SCHED_KEEP_ON_CORE +int sysctl_sched_util_ratio = 100; + +static int core_has_spare(int cpu) +{ + int core_id = cpumask_first(cpu_smt_mask(cpu)); + struct rq *rq = cpu_rq(core_id); + unsigned long util = rq->cfs.avg.util_avg; + unsigned long capacity = rq->cpu_capacity; + + return util * 100 < capacity * sysctl_sched_util_ratio; +} +#endif + #else /* CONFIG_SCHED_SMT */ static inline void set_idle_cores(int cpu, int val) @@ -8210,6 +8224,14 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f } #endif +#ifdef CONFIG_SCHED_KEEP_ON_CORE + if (sched_feat(KEEP_ON_CORE) && + static_branch_likely(&sched_smt_present)) { + if (core_has_spare(new_cpu)) + new_cpu = cpumask_first(cpu_smt_mask((new_cpu))); + } +#endif + rcu_read_unlock(); #ifdef CONFIG_QOS_SCHED_DYNAMIC_AFFINITY @@ -9701,6 +9723,15 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) } #endif +#ifdef CONFIG_SCHED_KEEP_ON_CORE + if (sched_feat(KEEP_ON_CORE) && + static_branch_likely(&sched_smt_present)) { + if (core_has_spare(env->dst_cpu) && + cpumask_first(cpu_smt_mask((env->dst_cpu))) != env->dst_cpu) + return 0; + } +#endif + /* * We do not migrate tasks that are: * 1) throttled_lb_pair, or diff --git a/kernel/sched/features.h b/kernel/sched/features.h index 76fade025c4bdfb1b9b816b3e74fa0bbe23fb244..fb885b20ba34ec753ac76b44a9774eaa89e267bf 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h @@ -70,6 +70,10 @@ SCHED_FEAT(SIS_UTIL, false) SCHED_FEAT(STEAL, false) #endif +#ifdef CONFIG_SCHED_KEEP_ON_CORE +SCHED_FEAT(KEEP_ON_CORE, false) +#endif + /* * Issue a WARN when we do multiple update_rq_clock() calls * in a single rq->lock section. Default disabled because the diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 3941856c19d1d7ff3366bbdad43c058d90f0f11b..bd7b17be9ba44449b80d319651b32d3ad63932b8 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -2817,6 +2817,16 @@ static struct ctl_table kern_table[] = { .extra2 = &one_hundred, }, #endif +#ifdef CONFIG_SCHED_KEEP_ON_CORE + { + .procname = "sched_util_ratio", + .data = &sysctl_sched_util_ratio, + .maxlen = sizeof(sysctl_sched_util_ratio), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + }, +#endif #ifdef CONFIG_QOS_SCHED_SMART_GRID { .procname = "smart_grid_strategy_ctrl",