[PATCH OLK-6.6] Add NI_RANDOM
Signed-off-by: Luo Gengkun <luogengkun2@huawei.com> --- ...ed-fair-Proportional-newidle-balance.patch | 208 ++++++++++++++++++ ...complex-proportional-newidle-balance.patch | 133 +++++++++++ 2 files changed, 341 insertions(+) create mode 100644 NI/0001-sched-fair-Proportional-newidle-balance.patch create mode 100644 NI/0002-sched-fair-More-complex-proportional-newidle-balance.patch diff --git a/NI/0001-sched-fair-Proportional-newidle-balance.patch b/NI/0001-sched-fair-Proportional-newidle-balance.patch new file mode 100644 index 000000000000..09ab81d809ff --- /dev/null +++ b/NI/0001-sched-fair-Proportional-newidle-balance.patch @@ -0,0 +1,208 @@ +From ccfc9b017997ffc44398363c85721a67c56533df Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra <peterz@infradead.org> +Date: Fri, 7 Nov 2025 17:01:31 +0100 +Subject: [PATCH OLK-6.6 1/2] sched/fair: Proportional newidle balance + +Add a randomized algorithm that runs newidle balancing proportional to +its success rate. + +This improves schbench significantly: + + 6.18-rc4: 2.22 Mrps/s + 6.18-rc4+revert: 2.04 Mrps/s + 6.18-rc4+revert+random: 2.18 Mrps/S + +Conversely, per Adam Li this affects SpecJBB slightly, reducing it by 1%: + + 6.17: -6% + 6.17+revert: 0% + 6.17+revert+random: -1% + +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com> +Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com> +Tested-by: Chris Mason <clm@meta.com> +Link: https://lkml.kernel.org/r/6825c50d-7fa7-45d8-9b81-c6e7e25738e2@meta.com +Link: https://patch.msgid.link/20251107161739.770122091@infradead.org +Signed-off-by: Luo Gengkun <luogengkun2@huawei.com> +--- + include/linux/sched/topology.h | 3 +++ + kernel/sched/core.c | 3 +++ + kernel/sched/fair.c | 43 ++++++++++++++++++++++++++++++---- + kernel/sched/features.h | 5 ++++ + kernel/sched/sched.h | 7 ++++++ + kernel/sched/topology.c | 6 +++++ + 6 files changed, 63 insertions(+), 4 deletions(-) + +diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h +index f0caa9e1a3c2..ab45a04061fb 100644 +--- a/include/linux/sched/topology.h ++++ b/include/linux/sched/topology.h +@@ -131,6 +131,9 @@ struct sched_domain { + unsigned int nr_balance_failed; /* initialise to 0 */ + + /* idle_balance() stats */ ++ unsigned int newidle_call; ++ unsigned int newidle_success; ++ unsigned int newidle_ratio; + u64 max_newidle_lb_cost; + unsigned long last_decay_max_lb_cost; + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index 981652b0d14c..5b486736bd5d 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -46,6 +46,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(sched_util_est_se_tp); + EXPORT_TRACEPOINT_SYMBOL_GPL(sched_update_nr_running_tp); + + DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); ++DEFINE_PER_CPU(struct rnd_state, sched_rnd_state); + + #ifdef CONFIG_SCHED_DEBUG + /* +@@ -9335,6 +9336,8 @@ void __init sched_init_smp(void) + { + sched_init_numa(); + ++ prandom_init_once(&sched_rnd_state); ++ + /* + * There's no userspace yet to cause hotplug operations; hence all the + * CPU masks are stable and all blatant races in the below code cannot +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index fb01890861eb..31a1f7734332 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -11840,8 +11840,23 @@ void update_max_interval(void) + max_load_balance_interval = HZ*num_online_cpus()/10; + } + +-static inline bool update_newidle_cost(struct sched_domain *sd, u64 cost) ++static inline void update_newidle_stats(struct sched_domain *sd, unsigned int success) + { ++ sd->newidle_call++; ++ sd->newidle_success += success; ++ ++ if (sd->newidle_call >= 1024) { ++ sd->newidle_ratio = sd->newidle_success; ++ sd->newidle_call /= 2; ++ sd->newidle_success /= 2; ++ } ++} ++ ++static inline bool update_newidle_cost(struct sched_domain *sd, u64 cost, unsigned int success) ++{ ++ if (cost) ++ update_newidle_stats(sd, success); ++ + if (cost > sd->max_newidle_lb_cost) { + /* + * Track max cost of a domain to make sure to not delay the +@@ -11889,7 +11904,7 @@ static void rebalance_domains(struct rq *rq, enum cpu_idle_type idle) + * Decay the newidle max times here because this is a regular + * visit to all the domains. + */ +- need_decay = update_newidle_cost(sd, 0); ++ need_decay = update_newidle_cost(sd, 0, 0); + max_cost += sd->max_newidle_lb_cost; + + /* +@@ -12527,6 +12542,22 @@ static int newidle_balance(struct rq *this_rq, struct rq_flags *rf) + break; + + if (sd->flags & SD_BALANCE_NEWIDLE) { ++ unsigned int weight = 1; ++ ++ if (sched_feat(NI_RANDOM)) { ++ /* ++ * Throw a 1k sided dice; and only run ++ * newidle_balance according to the success ++ * rate. ++ */ ++ u32 d1k = sched_rng() % 1024; ++ weight = 1 + sd->newidle_ratio; ++ if (d1k > weight) { ++ update_newidle_stats(sd, 0); ++ continue; ++ } ++ weight = (1024 + weight/2) / weight; ++ } + + pulled_task = load_balance(this_cpu, this_rq, + sd, CPU_NEWLY_IDLE, +@@ -12534,10 +12565,14 @@ static int newidle_balance(struct rq *this_rq, struct rq_flags *rf) + + t1 = sched_clock_cpu(this_cpu); + domain_cost = t1 - t0; +- update_newidle_cost(sd, domain_cost); +- + curr_cost += domain_cost; + t0 = t1; ++ ++ /* ++ * Track max cost of a domain to make sure to not delay the ++ * next wakeup on the CPU. ++ */ ++ update_newidle_cost(sd, domain_cost, weight * !!pulled_task); + } + + /* +diff --git a/kernel/sched/features.h b/kernel/sched/features.h +index 578cd5ed2b93..0198f4e97d24 100644 +--- a/kernel/sched/features.h ++++ b/kernel/sched/features.h +@@ -117,3 +117,8 @@ SCHED_FEAT(STEAL, false) + SCHED_FEAT(SIS_NODE, false) + SCHED_FEAT(TEST_STEAL_PLUS, false) + SCHED_FEAT(TEST_STEAL_PLUS_IDLE, false) ++ ++/* ++ * Do newidle balancing proportional to its success rate using randomization. ++ */ ++SCHED_FEAT(NI_RANDOM, true) +\ No newline at end of file +diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h +index 8940656dac3d..1f5ea2538515 100644 +--- a/kernel/sched/sched.h ++++ b/kernel/sched/sched.h +@@ -4,6 +4,7 @@ + */ + #include <linux/sched.h> + ++#include <linux/prandom.h> + #include <linux/sched/autogroup.h> + #include <linux/sched/clock.h> + #include <linux/sched/coredump.h> +@@ -1196,6 +1197,12 @@ static inline bool is_migration_disabled(struct task_struct *p) + } + + DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); ++DECLARE_PER_CPU(struct rnd_state, sched_rnd_state); ++ ++static inline u32 sched_rng(void) ++{ ++ return prandom_u32_state(this_cpu_ptr(&sched_rnd_state)); ++} + + #define cpu_rq(cpu) (&per_cpu(runqueues, (cpu))) + #define this_rq() this_cpu_ptr(&runqueues) +diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c +index 6576bf380086..cb82bbc4fb41 100644 +--- a/kernel/sched/topology.c ++++ b/kernel/sched/topology.c +@@ -1822,6 +1822,12 @@ sd_init(struct sched_domain_topology_level *tl, + + .last_balance = jiffies, + .balance_interval = sd_weight, ++ ++ /* 50% success rate */ ++ .newidle_call = 512, ++ .newidle_success = 256, ++ .newidle_ratio = 512, ++ + .max_newidle_lb_cost = 0, + .last_decay_max_lb_cost = jiffies, + .child = child, +-- +2.34.1 + diff --git a/NI/0002-sched-fair-More-complex-proportional-newidle-balance.patch b/NI/0002-sched-fair-More-complex-proportional-newidle-balance.patch new file mode 100644 index 000000000000..4ab477726400 --- /dev/null +++ b/NI/0002-sched-fair-More-complex-proportional-newidle-balance.patch @@ -0,0 +1,133 @@ +From 069a09a4f06e2a05e933dc58bbeb8c66fcd75572 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra <peterz@infradead.org> +Date: Tue, 27 Jan 2026 16:17:48 +0100 +Subject: [PATCH OLK-6.6 2/2] sched/fair: More complex proportional newidle + balance + +It turns out that a few workloads (easyWave, fio) have a fairly low +success rate on newidle balance, but still benefit greatly from having +it anyway. + +Luckliky these workloads have a faily low newidle rate, so the cost if +doing the newidle is relatively low, even if unsuccessfull. + +Add a simple rate based part to the newidle ratio compute, such that +low rate newidle will still have a high newidle ratio. + +This cures the easyWave and fio workloads while not affecting the +schbench numbers either (which have a very high newidle rate). + +Reported-by: Mario Roy <marioeroy@gmail.com> +Reported-by: "Mohamed Abuelfotoh, Hazem" <abuehaze@amazon.com> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Tested-by: Mario Roy <marioeroy@gmail.com> +Tested-by: "Mohamed Abuelfotoh, Hazem" <abuehaze@amazon.com> +Link: https://patch.msgid.link/20260127151748.GA1079264@noisy.programming.kicks-as... +Signed-off-by: Luo Gengkun <luogengkun2@huawei.com> +--- + include/linux/sched/topology.h | 1 + + kernel/sched/fair.c | 27 +++++++++++++++++++++++++-- + kernel/sched/features.h | 3 ++- + kernel/sched/topology.c | 3 +++ + 4 files changed, 31 insertions(+), 3 deletions(-) + +diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h +index ab45a04061fb..d66e6c6c2cdf 100644 +--- a/include/linux/sched/topology.h ++++ b/include/linux/sched/topology.h +@@ -134,6 +134,7 @@ struct sched_domain { + unsigned int newidle_call; + unsigned int newidle_success; + unsigned int newidle_ratio; ++ u64 newidle_stamp; + u64 max_newidle_lb_cost; + unsigned long last_decay_max_lb_cost; + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 31a1f7734332..ec40e79802bd 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -11846,7 +11846,30 @@ static inline void update_newidle_stats(struct sched_domain *sd, unsigned int su + sd->newidle_success += success; + + if (sd->newidle_call >= 1024) { +- sd->newidle_ratio = sd->newidle_success; ++ u64 now = sched_clock(); ++ s64 delta = now - sd->newidle_stamp; ++ sd->newidle_stamp = now; ++ int ratio = 0; ++ ++ if (delta < 0) ++ delta = 0; ++ ++ if (sched_feat(NI_RATE)) { ++ /* ++ * ratio delta freq ++ * ++ * 1024 - 4 s - 128 Hz ++ * 512 - 2 s - 256 Hz ++ * 256 - 1 s - 512 Hz ++ * 128 - .5 s - 1024 Hz ++ * 64 - .25 s - 2048 Hz ++ */ ++ ratio = delta >> 22; ++ } ++ ++ ratio += sd->newidle_success; ++ ++ sd->newidle_ratio = min(1024, ratio); + sd->newidle_call /= 2; + sd->newidle_success /= 2; + } +@@ -12544,7 +12567,7 @@ static int newidle_balance(struct rq *this_rq, struct rq_flags *rf) + if (sd->flags & SD_BALANCE_NEWIDLE) { + unsigned int weight = 1; + +- if (sched_feat(NI_RANDOM)) { ++ if (sched_feat(NI_RANDOM) && sd->newidle_ratio < 1024) { + /* + * Throw a 1k sided dice; and only run + * newidle_balance according to the success +diff --git a/kernel/sched/features.h b/kernel/sched/features.h +index 0198f4e97d24..9a8b6f41f4cb 100644 +--- a/kernel/sched/features.h ++++ b/kernel/sched/features.h +@@ -121,4 +121,5 @@ SCHED_FEAT(TEST_STEAL_PLUS_IDLE, false) + /* + * Do newidle balancing proportional to its success rate using randomization. + */ +-SCHED_FEAT(NI_RANDOM, true) +\ No newline at end of file ++SCHED_FEAT(NI_RANDOM, true) ++SCHED_FEAT(NI_RATE, true) +diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c +index cb82bbc4fb41..ac198e940978 100644 +--- a/kernel/sched/topology.c ++++ b/kernel/sched/topology.c +@@ -4,6 +4,7 @@ + */ + #include "sched.h" + #include "sparsemask.h" ++#include <linux/sched/clock.h> + + DEFINE_MUTEX(sched_domains_mutex); + +@@ -1783,6 +1784,7 @@ sd_init(struct sched_domain_topology_level *tl, + struct sched_domain *sd = *per_cpu_ptr(sdd->sd, cpu); + int sd_id, sd_weight, sd_flags = 0; + struct cpumask *sd_span; ++ u64 now = sched_clock(); + + #ifdef CONFIG_NUMA + /* +@@ -1827,6 +1829,7 @@ sd_init(struct sched_domain_topology_level *tl, + .newidle_call = 512, + .newidle_success = 256, + .newidle_ratio = 512, ++ .newidle_stamp = now, + + .max_newidle_lb_cost = 0, + .last_decay_max_lb_cost = jiffies, +-- +2.34.1 + -- 2.34.1
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/29708 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/DGC... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/29708 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/DGC...
participants (2)
-
Luo Gengkun -
patchwork bot