[PATCH 3/6] sched/numa: Notify the scheduling class of preferred node changes

From: Andrea Righi

Date: Tue Oct 27 2026 - 00:16:56 EST


sched_setnuma() updates p->numa_preferred_nid under the task's rq lock
and within a sched_change section, but the task's scheduling class has
no way to learn about the new preference other than polling the field.

Add an optional sched_class->numa_node_changed() method, called from
sched_setnuma() when the preferred node actually changes, after the new
value is stored and before the task is re-enqueued. This lets a class
that keeps its own placement state (e.g., sched_ext) react to the change
without sched core having to know about any specific class.

No functional change: no class implements the method yet.

Suggested-by: Tejun Heo <tj@xxxxxxxxxx>
Signed-off-by: Andrea Righi <arighi@xxxxxxxxxx>
---
kernel/sched/core.c | 7 ++++++-
kernel/sched/sched.h | 7 +++++++
2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 2f46922982f32..542f28fd95603 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -8331,8 +8331,13 @@ int migrate_task_to(struct task_struct *p, int target_cpu)
void sched_setnuma(struct task_struct *p, int nid)
{
guard(task_rq_lock)(p);
- scoped_guard (sched_change, p, DEQUEUE_SAVE)
+ scoped_guard (sched_change, p, DEQUEUE_SAVE) {
+ bool changed = p->numa_preferred_nid != nid;
+
p->numa_preferred_nid = nid;
+ if (changed && p->sched_class->numa_node_changed)
+ p->sched_class->numa_node_changed(task_rq(p), p, nid);
+ }
}
#endif /* CONFIG_NUMA_BALANCING */

diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 2b05c41e66e29..974f5df919aec 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -2814,6 +2814,13 @@ struct sched_class {
void (*task_change_group)(struct task_struct *p);
#endif

+#ifdef CONFIG_NUMA_BALANCING
+ /*
+ * sched_setnuma: task_rq_lock + sched_change
+ */
+ void (*numa_node_changed)(struct rq *rq, struct task_struct *p, int nid);
+#endif
+
#ifdef CONFIG_SCHED_CORE
/*
* pick_next_task: rq->lock
--
2.56.0