[RFC PATCH v4 18/28] sched: Do not migrate task if it is moving out of its preferred LLC
From: Chen Yu
Date: Sat Aug 09 2025 - 01:13:30 EST
From: Tim Chen <tim.c.chen@xxxxxxxxxxxxxxx>
In the final step of task migration during load balancing,
can_migrate_task() is used to determine whether a task can
be moved to the destination. If the task has an LLC preference,
consider this preference when moving it out of its preferred LLC.
With this check in place, there is no need to retain the task's
cache-hot CPU check in task_hot(); remove it accordingly.
Besides, add more checks in detach_tasks() to avoid choosing
tasks that prefer their current LLC.
Co-developed-by: Chen Yu <yu.c.chen@xxxxxxxxx>
Signed-off-by: Chen Yu <yu.c.chen@xxxxxxxxx>
Signed-off-by: Tim Chen <tim.c.chen@xxxxxxxxxxxxxxx>
---
kernel/sched/fair.c | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 8d5792b9e658..22b7a7fe538e 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -9822,17 +9822,6 @@ static int task_hot(struct task_struct *p, struct lb_env *env)
if (sysctl_sched_migration_cost == 0)
return 0;
-#ifdef CONFIG_SCHED_CACHE
- if (sched_feat(SCHED_CACHE) && p->mm && p->mm->pcpu_sched) {
- /*
- * XXX things like Skylake have non-inclusive L3 and might not
- * like this L3 centric view. What to do about L2 stickyness ?
- */
- return per_cpu_ptr(p->mm->pcpu_sched, env->src_cpu)->occ >
- per_cpu_ptr(p->mm->pcpu_sched, env->dst_cpu)->occ;
- }
-#endif
-
delta = rq_clock_task(env->src_rq) - p->se.exec_start;
return delta < (s64)sysctl_sched_migration_cost;
@@ -10029,6 +10018,12 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)
if (env->flags & LBF_ACTIVE_LB)
return 1;
+#ifdef CONFIG_SCHED_CACHE
+ if (sched_feat(SCHED_CACHE) &&
+ get_migrate_hint(env->src_cpu, env->dst_cpu, p) == mig_forbid)
+ return 0;
+#endif
+
degrades = migrate_degrades_locality(p, env);
if (!degrades)
hot = task_hot(p, env);
@@ -10289,6 +10284,17 @@ static int detach_tasks(struct lb_env *env)
if (env->imbalance <= 0)
break;
+#ifdef CONFIG_SCHED_CACHE
+ /*
+ * Don't detach more tasks if remaining tasks want to stay:
+ * The tasks have already been sorted by order_tasks_by_llc(),
+ * they are tasks that prefer the current LLC.
+ */
+ if (sched_feat(SCHED_CACHE) && p->preferred_llc != -1 &&
+ llc_id(env->src_cpu) == p->preferred_llc)
+ break;
+#endif
+
continue;
next:
if (p->sched_task_hot)
--
2.25.1