.../admin-guide/kernel-parameters.txt | 3 + Documentation/scheduler/index.rst | 1 + Documentation/scheduler/sched-cache.rst | 175 ++++++++ fs/exec.c | 24 ++ include/linux/mm_types.h | 15 +- include/linux/sched.h | 18 +- include/uapi/linux/prctl.h | 9 + kernel/exit.c | 35 +- kernel/fork.c | 38 ++ kernel/sched/build_utility.c | 4 + kernel/sched/cache_sched.c | 374 ++++++++++++++++++ kernel/sched/debug.c | 63 ++- kernel/sched/fair.c | 188 +++++---- kernel/sched/sched.h | 24 +- kernel/sched/topology.c | 32 +- kernel/sys.c | 5 + 16 files changed, 895 insertions(+), 113 deletions(-) create mode 100644 Documentation/scheduler/sched-cache.rst create mode 100644 kernel/sched/cache_sched.c
Hi all,
Cache aware scheduling today groups tasks by their mm: the LLC aggregation
target lives in mm_struct, so the address space is the unit of grouping.
That works, but in some scenarios that is too coarse and too eager, and the
only knob we have over it is a single system-wide debugfs switch.
It's too coarse because plenty of workloads share data across cooperating
*processes* rather than threads - a database with a process per connection,
a browser with a renderer per site, a server and its worker helpers. They
pass data through shm or pipes and would love to be pulled onto the same
LLC, but they never share an mm, so today they can't be. And it's too eager
in the other direction: a process whose threads don't actually share
anything gets aggregated anyway, just because they happen to sit in one
address space.
So the core idea of this series is simple: allow other groupings than
the mm, make the grouping an object in its own right, and let user space
say "put these tasks together" explicitly.
What the series does
====================
Patches 1-3 are pure preparation, no behavior change. They turn the
per-mm statistics into a standalone, refcounted sched_cache_group, reach
it from task_struct instead of from p->mm, and pull the allocation out into
a helper. Once the group stands on its own, membership no longer has to
follow the mm address space.
Patch 4 adds the actual interface:
int prctl(PR_SCHED_CACHE, subop, pid, arg4, pid_type);
PR_SCHED_CACHE_GET read back a task's (obfuscated) cookie id
PR_SCHED_CACHE_CREATE create a fresh group and install it
PR_SCHED_CACHE_SHARE_FROM copy the group of arg4 onto pid
PR_SCHED_CACHE_DISABLE opt this group out of LLC aggregation
PR_SCHED_CACHE_ENABLE opt it back in
'pid' is the task the operation applies to, with 0 meaning the caller, and
'pid_type' picks whether we touch just the thread, the whole thread group,
or the process group. Permissions follow core scheduling: every task we
touch has to pass ptrace_may_access(PTRACE_MODE_READ_REALCREDS), and for
the group scopes we check *all* of them before changing *any* of them, so
the operation is all-or-nothing.
Two subops need a word on their fourth argument:
- GET writes the cookie id to arg4, which is a u64 __user * and must be
8-byte aligned (misaligned pointers are rejected with -EINVAL). As in
core scheduling the value handed out is an obfuscated hash of the
kernel object, not a real pointer or a user-supplied number.
- SHARE_FROM reads arg4 as the *source* pid and copies its group onto
'pid'. CREATE is deliberately not idempotent - it always allocates a
new group - so a caller that wants many tasks in one group does CREATE
once and SHARE_FROM for the rest.
Patches 5-6 build on that. Patch 5 wires up DISABLE/ENABLE, and patch 6
turns the old debugfs boolean into a THP-style always/advise/never mode so
that the system policy and the per-task hint compose the same way THP's do:
'always' aggregates regardless of the per-task hint, 'advise' honors it,
'never' turns the whole thing off. The write side still accepts the old
0/1 (and y/n, on/off) spelling so existing scripts don't break; only the
read format grows to "[always] advise never".
Patch 7 documents the prctl and debugfs interface for cache aware
scheduling in kerneldoc.
Relation to sched QoS
=====================
This patch set is also inspired by Qais' sched QoS tool for finer-grained
control:
https://lore.kernel.org/lkml/20260415000910.2h5misvwc45bdumu@airbuntu/
https://github.com/qais-yousef/schedqos
There are two deliberate differences from the sched QoS interface:
1. The cookie is owned by the kernel. User space never invents or passes a
cookie value - it only names tasks by pid and asks the kernel to create
a group or link one task's group to another. That mirrors core
scheduling, where PR_SCHED_CORE_GET only hands back an obfuscated id.
It also relieves userspace the burden of cookie lifecycle management and
avoiding duplicate cookies between separate entities doing the grouping.
We think that it will make schedqos easier to implement.
The cookie value is only meant to identify whether two tasks belong
in the same cache scheduling group.
2. It's prctl() rather than sched_setattr(). Group membership isn't really
an attribute value, and core scheduling already set a prctl-shaped
precedent for "put these tasks together", so we reuse its subop layout,
pid_type scoping and ptrace_may_access() permission model.
On the schedqos side the change would live in apply_thread_qos(): create
the group once per app instance and let the rest of the app join it -
roughly:
if (!appi->grouped) {
/* CREATE is not idempotent, do it once per instance */
err = prctl(PR_SCHED_CACHE, PR_SCHED_CACHE_CREATE,
tgid, 0, PIDTYPE_TGID);
appi->grouped = !err;
} else {
prctl(PR_SCHED_CACHE, PR_SCHED_CACHE_SHARE_FROM,
pid, tgid, PIDTYPE_PID);
}
Yangyu Chen also proposed exposing per-process parameters via prctl:
https://lore.kernel.org/all/tencent_93116D14C771DC8C988C10E3C634BE0CC107@qq.com/
That fits naturally on top of this if people agree the direction is right.
And in theory cgroup could offer per-cgroup cache aware scheduling with the
same mechanism - but we'd want input from the cgroup maintainers before
going anywhere near that.
Still to do
===========
- Documentation for the new prctl (a prctl(2) man-page
update).
- A selftest under tools/testing/selftests exercising the subops and the
permission checks - likewise TODO.
Feedbacks very welcome, especially on the interface shape (prctl vs. a QoS
attribute), the kernel-owned-cookie choice, and whether the always/advise/
never policy composition is the right model.
The series applies on v7.2-rc6.
Tim Chen and Chen Yu
Chen Yu (1):
sched/cache: Extend the enabled debugfs to more modes
Tim Chen (6):
sched/cache: Decouple sched_cache_group from mm
sched/cache: Introduce task_struct->sched_cache_grp
sched/cache: Extract sched_cache_alloc_group() helper
sched/cache: Add prctl to manage per process cache scheduling groups
sched/cache: Allow a process to enable cache aware scheduling via
prctl
sched/cache: Documentation: document the PR_SCHED_CACHE prctl
.../admin-guide/kernel-parameters.txt | 3 +
Documentation/scheduler/index.rst | 1 +
Documentation/scheduler/sched-cache.rst | 175 ++++++++
fs/exec.c | 24 ++
include/linux/mm_types.h | 15 +-
include/linux/sched.h | 18 +-
include/uapi/linux/prctl.h | 9 +
kernel/exit.c | 35 +-
kernel/fork.c | 38 ++
kernel/sched/build_utility.c | 4 +
kernel/sched/cache_sched.c | 374 ++++++++++++++++++
kernel/sched/debug.c | 63 ++-
kernel/sched/fair.c | 188 +++++----
kernel/sched/sched.h | 24 +-
kernel/sched/topology.c | 32 +-
kernel/sys.c | 5 +
16 files changed, 895 insertions(+), 113 deletions(-)
create mode 100644 Documentation/scheduler/sched-cache.rst
create mode 100644 kernel/sched/cache_sched.c
--
2.32.0
Hi Tim/Peter. I have been trying to catch up. I still have to read and might have missed some conversation details. So please bear with me for silly questions. On 8/29/26 3:59 AM, Tim Chen wrote: > Hi all, > > Cache aware scheduling today groups tasks by their mm: the LLC aggregation > target lives in mm_struct, so the address space is the unit of grouping. > That works, but in some scenarios that is too coarse and too eager, and the > only knob we have over it is a single system-wide debugfs switch. > > It's too coarse because plenty of workloads share data across cooperating > *processes* rather than threads - a database with a process per connection, > a browser with a renderer per site, a server and its worker helpers. They > pass data through shm or pipes and would love to be pulled onto the same > LLC, but they never share an mm, so today they can't be. And it's too eager > in the other direction: a process whose threads don't actually share > anything gets aggregated anyway, just because they happen to sit in one > address space. > > So the core idea of this series is simple: allow other groupings than > the mm, make the grouping an object in its own right, and let user space > say "put these tasks together" explicitly. So, As you said, this is effectively asking user to make the decision. But what tools do user space have today to make effective decisions? Application changes could turn out to be tricky to do and how an application developer will know whether to group them together or not? What's guidance there? Can the grouping be done post the application started running? Like any option that says these pid's are to be bundled into one group? I remember you guys discussed about cgroup and decided it is not a good option. That argument is still holds?
On Wed, 2026-09-09 at 18:27 +0530, Shrikanth Hegde wrote: > Hi Tim/Peter. > > I have been trying to catch up. I still have to read > and might have missed some conversation details. So please > bear with me for silly questions. Thanks for taking a look. You questions are helpful for providing the context of why this series was proposed. > > On 8/29/26 3:59 AM, Tim Chen wrote: > > Hi all, > > > > Cache aware scheduling today groups tasks by their mm: the LLC aggregation > > target lives in mm_struct, so the address space is the unit of grouping. > > That works, but in some scenarios that is too coarse and too eager, and the > > only knob we have over it is a single system-wide debugfs switch. > > > > It's too coarse because plenty of workloads share data across cooperating > > *processes* rather than threads - a database with a process per connection, > > a browser with a renderer per site, a server and its worker helpers. They > > pass data through shm or pipes and would love to be pulled onto the same > > LLC, but they never share an mm, so today they can't be. And it's too eager > > in the other direction: a process whose threads don't actually share > > anything gets aggregated anyway, just because they happen to sit in one > > address space. > > > > So the core idea of this series is simple: allow other groupings than > > the mm, make the grouping an object in its own right, and let user space > > say "put these tasks together" explicitly. > > So, As you said, this is effectively asking user to make the decision. By default, tasks are grouped by process and that make sense in many cases. But sometimes the users have information about task characteristics that they wish to group tasks in other ways. In our discussions with Vern Hao from Tencent, they have multiple processes in their workload, where some tasks in a process is responsible for database access, some for encryption, and some dealing with disk access. Those tasks across processes with similar function share more data than tasks in a process for their applications. Another scenario is grouping processes with shared memory together. > > But what tools do user space have today to make effective decisions? As in the example above, this is for users who know about their workload characteristics and wish to group their tasks in other way than the default process grouping. Also if people identify via perf c2c that tasks > Application changes could turn out to be tricky to do and how an > application developer will know whether to group them together or not? > What's guidance there? No changes is required on application. An admin or a separate daemon can use prctl to group tasks together by sepcifying the pids pair of tasks to be grouped. Please see the PR_SCHED_CACHE_SHARE_FROM operation in patch 7 of the documentation. > > Can the grouping be done post the application started running? > Like any option that says these pid's are to be bundled into one group? Yes. > > I remember you guys discussed about cgroup and decided it is not a good option. > That argument is still holds? I think there is no strong case to support that tasks sharing data necessarily belong in a cgroup. Using cgroup wouldn't cover all the use cases we want. With the proposed prctl based interface in this series, the administrator can easily group the processes in a cgroup together if that makes sense. We also would rather not disturb the cgroup interface unnecessarily. Tim
On Fri, Aug 28, 2026 at 03:29:07PM -0700, Tim Chen wrote: > Feedbacks very welcome, especially on the interface shape (prctl vs. a QoS > attribute), the kernel-owned-cookie choice, and whether the always/advise/ > never policy composition is the right model. Who would be using this -- what workload prompted you do do this etc.
Hi Peter, On Sat, Aug 29, 2026 at 11:27:21AM +0200, Peter Zijlstra wrote: > Subject: Re: [RFC PATCH 0/7] sched/cache: Per-task control of cache aware > scheduling via prctl > > On Fri, Aug 28, 2026 at 03:29:07PM -0700, Tim Chen wrote: > > > Feedbacks very welcome, especially on the interface shape (prctl vs. a QoS > > attribute), the kernel-owned-cookie choice, and whether the always/advise/ > > never policy composition is the right model. > > Who would be using this -- what workload prompted you do do this etc. > One motivation is that some cloud users would like finer-grained control over cache‑aware scheduling. Vern Hao from Tencent previously asked about this: https://lore.kernel.org/all/7d5bb7c4-abc5-470e-84fe-72a3b1d3a2f4@gmail.com/ and mentioned that, in their production environment, threads within the same process do not always share data. On the other hand, it is possible that within one process there are two thread groups, A and B. Threads in group A share data with each other, while threads in group B do not. Typically, in Vern's environment, group A and group B are cgroups. Group A usually runs memory‑intensive workloads, such as KV‑cache related ones, and such workloads have intensive data sharing among themselves, so they would like to enable cache‑aware scheduling separately. Furthermore, since group A is memory‑intensive, the default cache‑aware scheduling threshold might reject aggregation because group A's memory footprint is high. As a result, group A has a requirement to turn the threshold parameter separately. thanks, Chenyu
On Mon, 2026-08-31 at 22:39 +0800, Chen Yu wrote: > Hi Peter, > > On Sat, Aug 29, 2026 at 11:27:21AM +0200, Peter Zijlstra wrote: > > Subject: Re: [RFC PATCH 0/7] sched/cache: Per-task control of cache aware > > scheduling via prctl > > > > On Fri, Aug 28, 2026 at 03:29:07PM -0700, Tim Chen wrote: > > > > > Feedbacks very welcome, especially on the interface shape (prctl vs. a QoS > > > attribute), the kernel-owned-cookie choice, and whether the always/advise/ > > > never policy composition is the right model. > > > > Who would be using this -- what workload prompted you do do this etc. > > > > One motivation is that some cloud users would like finer-grained control over > cache‑aware scheduling. Vern Hao from Tencent previously asked about this: > > https://lore.kernel.org/all/7d5bb7c4-abc5-470e-84fe-72a3b1d3a2f4@gmail.com/ > > and mentioned that, in their production environment, threads within the same > process do not always share data. On the other hand, it is possible that within > one process there are two thread groups, A and B. Threads in group A share data > with each other, while threads in group B do not. Typically, in Vern's environment, > group A and group B are cgroups. Group A usually runs memory‑intensive workloads, such > as KV‑cache related ones, and such workloads have intensive data sharing among themselves, > so they would like to enable cache‑aware scheduling separately. Furthermore, since group A > is memory‑intensive, the default cache‑aware scheduling threshold might reject aggregation > because group A's memory footprint is high. As a result, group A has a requirement to turn the > threshold parameter separately. I also remembered in discussions with Vern, His usage scenario has processes each comprising of threads doing different functions, like one thread responsible for database lookup, one for encryption/decryption and one for file IO ...etc. So the threads in different processes performing similar function has more common data and perform better when grouped together. Also in separate discussions with Qais, he has also mentioned that for his environment, tasks in the same process may not share data. https://lore.kernel.org/lkml/20260219140828.a7pyzupun7lsdw34@airbuntu/ : >> This initial implementation treats threads within the same process as >> entities that are likely to share data. During load balancing, the >This is a very aggressive assumption. From what I've seen, only few tasks truly >share data. Lumping everything in a process together is an easy way to >classify, but I think we can do better. So this series is an attempt to address such cases where grouping tasks by other criteria than mm makes sense. Tim
© 2016 - 2026 Red Hat, Inc.