[RFC PATCH 2/6] sched/fair: Add is_smt_buddy_run() to skip SMT domain
From: Li kunyu
Date: Tue Oct 20 2026 - 04:44:22 EST
When a CFS task is successfully pushed to an SMT sibling CPU during
periodic load balancing or nohz_kick, scanning the SMT scheduling domain
afterwards is unnecessary. It also risks pulling the task back to the
original CPU, defeating the purpose of the push.
The is_smt_buddy_run() helper is introduced to detect whether a task is
already running on its SMT sibling. When this condition holds, the SMT
scheduling domain is skipped in the subsequent load balance path.
This improves efficiency by avoiding redundant SMT domain scans and
prevents reverse pulling of tasks that were just pushed to the sibling.
Tested-by: Li Wang (Hieco) <li.wang@xxxxxxxxx>
Signed-off-by: Li kunyu <likunyu@xxxxxxxxxxxxxx>
---
kernel/sched/fair.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index a43a168f23ba..12b3223c6403 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -14244,6 +14244,22 @@ update_newidle_cost(struct sched_domain *sd, u64 cost, unsigned int success)
return false;
}
+/*
+ * When the CFS task is successfully pushed to the SMT sibling CPU in
+ * the cyclic load balancing and nohz_kick process, skipping the SMT
+ * scheduling domain check can improve efficiency to a certain extent.
+ */
+static bool is_smt_buddy_run(struct sched_domain *sd, bool is_smt_move_task)
+{
+ if (!sched_feat(SMT_BUDDY_ASSIST))
+ return false;
+
+ if ((sd->flags & SD_SHARE_CPUCAPACITY) && is_smt_move_task)
+ return true;
+
+ return false;
+}
+
/*
* An exciting thing is that we have implemented an efficient push
* function process.
@@ -14350,8 +14366,7 @@ static void sched_balance_domains(struct rq *rq, enum cpu_idle_type idle)
int update_next_balance = 0;
int need_decay = 0;
u64 max_cost = 0;
-
- smt_buddy_move_task(rq);
+ bool is_smt_move_task = smt_buddy_move_task(rq);
rcu_read_lock();
for_each_domain(cpu, sd) {
@@ -14375,7 +14390,8 @@ static void sched_balance_domains(struct rq *rq, enum cpu_idle_type idle)
interval = get_sd_balance_interval(sd, busy);
if (time_after_eq(jiffies, sd->last_balance + interval)) {
- if (sched_balance_rq(cpu, rq, sd, idle, &continue_balancing)) {
+ if (!is_smt_buddy_run(sd, is_smt_move_task) &&
+ sched_balance_rq(cpu, rq, sd, idle, &continue_balancing)) {
/*
* The LBF_DST_PINNED logic could have changed
* env->dst_cpu, so we can't know our idle
--
2.47.3