[RFC PATCH 5/7] sched/cache: Allow a process to enable cache aware scheduling via prctl
From: Tim Chen <hidden>
Date: 2026-08-28 22:23:56
Also in:
lkml
Subsystem:
scheduler, the rest · Maintainers:
Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot, Linus Torvalds
Add the PR_SCHED_CACHE_ENABLE and PR_SCHED_CACHE_DISABLE subops to the
PR_SCHED_CACHE prctl interface, allowing a process to turn cache aware
scheduling on or off.
int prctl(PR_SCHED_CACHE, unsigned long subop, pid_t pid,
unsigned long cookie, unsigned long type);
/* disable cache aware scheduling for this task */
prctl(PR_SCHED_CACHE, PR_SCHED_CACHE_DISABLE, 0, 0, PIDTYPE_PID);
/* enable cache aware scheduling for this task */
prctl(PR_SCHED_CACHE, PR_SCHED_CACHE_ENABLE, 0, 0, PIDTYPE_PID);
pid 0 targets the calling task; otherwise the group of the given pid is
used. Both return -ENOENT when the task has no cache scheduling group.
Co-developed-by: Chen Yu <yu.c.chen@intel.com>
Signed-off-by: Chen Yu <yu.c.chen@intel.com>
Signed-off-by: Tim Chen <redacted>
---
include/linux/sched.h | 1 +
include/uapi/linux/prctl.h | 4 +++-
kernel/sched/cache_sched.c | 15 +++++++++++++++
kernel/sched/fair.c | 6 ++++++
4 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 79f0079c3aa1..1529730c91a5 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h@@ -2399,6 +2399,7 @@ struct sched_cache_group { unsigned long next_scan; unsigned long footprint; int cpu; + int enabled; refcount_t refcnt; struct rcu_head rcu; } ____cacheline_aligned_in_smp;
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index fed7bb028f9a..3fb31c4ab7b5 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h@@ -421,6 +421,8 @@ struct prctl_mm_map { # define PR_SCHED_CACHE_GET 0 # define PR_SCHED_CACHE_CREATE 1 # define PR_SCHED_CACHE_SHARE_FROM 2 -# define PR_SCHED_CACHE_MAX 3 +# define PR_SCHED_CACHE_DISABLE 3 +# define PR_SCHED_CACHE_ENABLE 4 +# define PR_SCHED_CACHE_MAX 5 #endif /* _LINUX_PRCTL_H */
diff --git a/kernel/sched/cache_sched.c b/kernel/sched/cache_sched.c
index d1932f0c5ee8..c4ec6c553cca 100644
--- a/kernel/sched/cache_sched.c
+++ b/kernel/sched/cache_sched.c@@ -60,6 +60,7 @@ static void sched_cache_group_init(struct sched_cache_group *grp, grp->next_scan = jiffies; grp->nr_running_avg = 0; grp->footprint = 0; + grp->enabled = 1; refcount_set(&grp->refcnt, 1); /* * The update to grp->pcpu_sched should not be reordered
@@ -261,6 +262,20 @@ int sched_cache_prctl(int option, unsigned long arg2, unsigned long arg3, } switch (arg2) { + case PR_SCHED_CACHE_DISABLE: + case PR_SCHED_CACHE_ENABLE: + /* + * Setting a single task is OK, because the sched_cache_group is + * shared by multiple tasks, setting one equals to setting all. + */ + grp = task_cache_group_get(dst); + if (!grp) { + err = -ENOENT; + goto out_task; + } + WRITE_ONCE(grp->enabled, arg2 == PR_SCHED_CACHE_ENABLE); + + goto out_group; case PR_SCHED_CACHE_GET: { unsigned long id = 0;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index d422b62ba987..e7c8b031946c 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c@@ -1652,6 +1652,9 @@ static int get_pref_llc(struct task_struct *p, struct sched_cache_group *grp) if (!grp) return -1; + if (!READ_ONCE(grp->enabled)) + return -1; + mm_sched_cpu = READ_ONCE(grp->cpu); if (mm_sched_cpu != -1) { mm_sched_llc = llc_id(mm_sched_cpu);
@@ -1743,6 +1746,9 @@ static void task_tick_cache(struct rq *rq, struct task_struct *p) !grp->pcpu_sched) return; + if (!READ_ONCE(grp->enabled)) + return; + epoch = rq->cpu_epoch; /* avoid moving backwards */ if (time_after_eq(grp->epoch, epoch))
--
2.32.0