* Re: [PATCH RFC] sched_ext: warn when cpu.max is set but the BPF scheduler doesn't implement bandwidth control
2026-08-18 13:53 [PATCH RFC] sched_ext: warn when cpu.max is set but the BPF scheduler doesn't implement bandwidth control Tao Cui
@ 2026-08-18 13:58 ` Tao Cui
2026-08-18 14:10 ` sashiko-bot
2026-08-18 15:34 ` Tejun Heo
2 siblings, 0 replies; 4+ messages in thread
From: Tao Cui @ 2026-08-18 13:58 UTC (permalink / raw)
To: tj, void
Cc: cui.tao, arighi, changwoo, suzhidao, sched-ext, linux-kernel, bpf,
Tao Cui
Hi, tejun
在 2026/8/18 21:53, Tao Cui 写道:
> From: Tao Cui <cuitao@kylinos.cn>
>
> The kernel stores cpu.max bandwidth parameters in the task_group and
> passes them to the BPF scheduler via ops.cgroup_set_bandwidth() and
> scx_cgroup_init_args, but does not enforce the quota itself. If the
> loaded BPF scheduler doesn't implement the callback, cpu.max is
> silently ignored -- the cgroup gets unlimited CPU regardless of the
> configured quota.
>
> Of the example schedulers, only scx_qmap implements the callback --
> and only to bpf_printk() the parameters, so no in-tree scheduler
> actually enforces the quota. Measured with scx_simple: a
> cgroup with cpu.max = "50000 100000" (50% of one CPU) and one
> busy task used 9946ms of CPU in 10 seconds with nr_throttled
> remaining 0.
>
> Print a one-time warning when a finite quota is configured on a
> cgroup while the active scheduler lacks the callback, so users and
> container orchestrators know the quota is not enforced.
>
Some background on how I found this: I was testing how sched_ext
interacts with cgroup CPU controls in a VM, and the cpu.max case stood
out:
cgroup with cpu.max = "50000 100000" (50% of one CPU),
one busy task, scx_simple loaded
sched_ext : 9946ms of CPU in 10s, nr_throttled = 0
CFS : ~5000ms in 10s, throttling as expected
The same happens with scx_flatcg and scx_central -- neither they nor
scx_simple implement ops.cgroup_set_bandwidth(), so the quota is
silently ignored. grep shows scx_qmap is the only in-tree user of the
callback -- and its implementation just bpf_printk()s the parameters, so
even there the quota is not enforced. Outside the
tree, lavd implements its own bandwidth accounting, but as far as I can
tell rusty and bpfland don't, which suggests users on those schedulers
are running containers with cpu.max that does nothing.
That's why I drafted the warning patch -- but I'm not sure a warning is
the right approach. Some alternatives I can think of:
1. pr_warn_once() as in this patch (minimal, but the quota is still
not enforced)
2. refuse to enable sched_ext (or the cgroup support) when a finite
quota exists and the callback is missing
3. kernel-side fallback enforcement, e.g. throttle in
scx_next_task_picked()/dispatch path based on tg->scx.bw_quota_us
Is the missing enforcement considered the BPF scheduler's responsibility
by design (and just under-documented), or would a kernel fallback be
welcome? If it's the former, maybe sched-ext.rst should mention that
cpu.max requires ops.cgroup_set_bandwidth() from the loaded scheduler.
Happy to work on whichever direction you prefer.
Thanks,
Tao
> Signed-off-by: Tao Cui <cuitao@kylinos.cn>
> ---
> kernel/sched/ext/ext.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
> index 10af28a9f2c0..de786d0b928a 100644
> --- a/kernel/sched/ext/ext.c
> +++ b/kernel/sched/ext/ext.c
> @@ -4953,6 +4953,12 @@ void scx_group_set_bandwidth(struct task_group *tg,
> tg->scx.bw_burst_us != burst_us))
> SCX_CALL_OP(sch, cgroup_set_bandwidth, NULL,
> tg_cgrp(tg), period_us, quota_us, burst_us);
> + else if (scx_cgroup_enabled && sch &&
> + !SCX_HAS_OP(sch, cgroup_set_bandwidth) &&
> + quota_us != RUNTIME_INF)
> + pr_warn_once("sched_ext: BPF scheduler \"%s\" does not implement "
> + "ops.cgroup_set_bandwidth(); cpu.max will not be enforced\n",
> + sch->ops.name);
>
> tg->scx.bw_period_us = period_us;
> tg->scx.bw_quota_us = quota_us;
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH RFC] sched_ext: warn when cpu.max is set but the BPF scheduler doesn't implement bandwidth control
2026-08-18 13:53 [PATCH RFC] sched_ext: warn when cpu.max is set but the BPF scheduler doesn't implement bandwidth control Tao Cui
2026-08-18 13:58 ` Tao Cui
@ 2026-08-18 14:10 ` sashiko-bot
2026-08-18 15:34 ` Tejun Heo
2 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-08-18 14:10 UTC (permalink / raw)
To: Tao Cui; +Cc: sched-ext, bpf
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The new warning for unenforced `cpu.max` is missing during BPF scheduler initialization, meaning preexisting cgroup quotas are silently ignored without notification.
--
--- Patch [1]: [PATCH RFC] sched_ext: warn when cpu.max is set but the BPF scheduler doesn't implement bandwidth control ---
commit 88bd45e8c02c048f00992a1d03614c8ef709c738
Author: Tao Cui <cuitao@kylinos.cn>
sched_ext: warn when cpu.max is set but the BPF scheduler doesn't implement bandwidth control
This commit adds a one-time warning when a finite cpu.max quota is
configured on a cgroup but the active BPF scheduler lacks the
cgroup_set_bandwidth callback. The intent is to notify users and
orchestrators that the quota is silently ignored and not enforced by the
scheduler.
> diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
> index 18183062f751c..1067d271f6b27 100644
> --- a/kernel/sched/ext/ext.c
> +++ b/kernel/sched/ext/ext.c
> @@ -4565,6 +4565,12 @@ void scx_group_set_bandwidth(struct task_group *tg,
> tg->scx.bw_burst_us != burst_us))
> SCX_CALL_OP(sch, cgroup_set_bandwidth, NULL,
> tg_cgrp(tg), period_us, quota_us, burst_us);
> + else if (scx_cgroup_enabled && sch &&
> + !SCX_HAS_OP(sch, cgroup_set_bandwidth) &&
> + quota_us != RUNTIME_INF)
> + pr_warn_once("sched_ext: BPF scheduler \"%s\" does not implement "
> + "ops.cgroup_set_bandwidth(); cpu.max will not be enforced\n",
> + sch->ops.name);
[Severity: Medium]
Will this warning also catch preexisting cgroup bandwidth configurations?
If a user configures a finite cpu.max limit on a cgroup before the BPF
scheduler is loaded, the initialization path in scx_cgroup_init() passes
the existing quota to the scheduler:
kernel/sched/ext/ext.c:scx_cgroup_init() {
...
struct scx_cgroup_init_args args = {
.weight = tg->scx.weight,
.bw_period_us = tg->scx.bw_period_us,
.bw_quota_us = tg->scx.bw_quota_us,
.bw_burst_us = tg->scx.bw_burst_us,
};
...
ret = SCX_CALL_OP_RET(sch, cgroup_init, NULL,
css->cgroup, &args);
...
}
Should scx_cgroup_init() also check for an unenforced quota and emit this
warning, to ensure users are notified when preexisting configurations are
silently ignored?
>
> tg->scx.bw_period_us = period_us;
> tg->scx.bw_quota_us = quota_us;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260818135328.174152-1-cui.tao@linux.dev?part=1
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH RFC] sched_ext: warn when cpu.max is set but the BPF scheduler doesn't implement bandwidth control
2026-08-18 13:53 [PATCH RFC] sched_ext: warn when cpu.max is set but the BPF scheduler doesn't implement bandwidth control Tao Cui
2026-08-18 13:58 ` Tao Cui
2026-08-18 14:10 ` sashiko-bot
@ 2026-08-18 15:34 ` Tejun Heo
2 siblings, 0 replies; 4+ messages in thread
From: Tejun Heo @ 2026-08-18 15:34 UTC (permalink / raw)
To: Tao Cui
Cc: void, arighi, changwoo, suzhidao, sched-ext, linux-kernel, bpf,
Tao Cui
Hello,
On Tue, Aug 18, 2026 at 09:53:28PM +0800, Tao Cui wrote:
> From: Tao Cui <cuitao@kylinos.cn>
>
> The kernel stores cpu.max bandwidth parameters in the task_group and
> passes them to the BPF scheduler via ops.cgroup_set_bandwidth() and
> scx_cgroup_init_args, but does not enforce the quota itself. If the
> loaded BPF scheduler doesn't implement the callback, cpu.max is
> silently ignored -- the cgroup gets unlimited CPU regardless of the
> configured quota.
>
> Of the example schedulers, only scx_qmap implements the callback --
> and only to bpf_printk() the parameters, so no in-tree scheduler
> actually enforces the quota. Measured with scx_simple: a
> cgroup with cpu.max = "50000 100000" (50% of one CPU) and one
> busy task used 9946ms of CPU in 10 seconds with nr_throttled
> remaining 0.
>
> Print a one-time warning when a finite quota is configured on a
> cgroup while the active scheduler lacks the callback, so users and
> container orchestrators know the quota is not enforced.
We had something similar with cpu.weight and it created more annoaynces than
helping anything. cgroup bw control isn't the only thing the BPF scheduler
may skip to implement. It can also choose to ignore e.g. nice levels
completely too and there's no way to detect things like that. Documentation
is probably the right way to handle this.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 4+ messages in thread