Re: [PATCH v2 1/2] cgroup: add BPF kfuncs to read a cpu cgroup's stats
Ziyang Men <[email protected]>
| Newsgroups | org.kernel.vger.cgroups,org.kernel.vger.bpf,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest |
|---|---|
| Message-ID | <[email protected]> |
Hi Tejun,
On Tue, Aug 18, 2026 at 07:16:24AM -1000, Tejun Heo wrote:
>On Mon, Aug 17, 2026 at 05:24:49PM -0700, Ziyang Men wrote:
>> +++ b/kernel/cgroup/bpf_cpu.c
>
>Probably not the best file name. bpf_cgroup.c or maybe just put it in
>cgroup.c?
>
bpf_cgroup.c sounds good, I will rename to it.
>> +/**
>> + * bpf_css_to_task_group - Cast a CPU controller css to its task group
>> + * @css: CPU controller css
>> + *
>> + * Must be called under RCU.
>> + * A C cast does not give the verifier a task_group pointer. This kfunc
>> + * preserves the task_group and per-CPU types needed to read cfs_rq.
>
>The fact that this is used for per-CPU types now probably won't age well if
>this grows more usages in the future.
>
Yes the major usage of this function is to enable the bpf side to compute the
throttled_time meanwhile not touch the codes in scheduler.
>> + *
>> + * Return: The task group, or NULL if @css belongs to another controller.
>> + */
>> +__bpf_kfunc struct task_group *
>> +bpf_css_to_task_group(struct cgroup_subsys_state *css)
>> +{
>> + if (css->ss != &cpu_cgrp_subsys)
>
>unlikely()?
>
Ok. Added.
>> + return NULL;
>> +
>> + /* task_group embeds css at offset zero. */
>> + return (struct task_group *)css;
>
>container_of()?
>
Ok. Added.
>> +/**
>> + * bpf_css_flush_rstat - Flush a cgroup subsystem's rstat data
>> + * @css: cgroup subsystem state to flush
>> + */
>> +__bpf_kfunc void bpf_css_flush_rstat(struct cgroup_subsys_state *css)
>> +{
>> + css_rstat_flush(css);
>> +}
>
>Why is this necessary? Isn't css_rstat_flush() already exposed as a kfunc?
>
Ok. Will remove it.
>> +/**
>> + * bpf_cgroup_base_stat - Read a cgroup's base statistics
>> + * @cgrp: cgroup to read from
>> + * @out: zero-initialized output in nanoseconds
>> + *
>> + * CPU time is adjusted as for cpu.stat.
>> + */
>> +__bpf_kfunc void bpf_cgroup_base_stat(struct cgroup *cgrp,
>> + struct cgroup_base_stat *out)
>> +{
>> + if (cgroup_parent(cgrp)) {
>> + __css_rstat_lock(&cgrp->self, -1);
>> + *out = cgrp->bstat;
>> + cputime_adjust(&cgrp->bstat.cputime, &cgrp->prev_cputime,
>> + &out->cputime.utime, &out->cputime.stime);
>> + __css_rstat_unlock(&cgrp->self, -1);
>> + } else {
>> + root_cgroup_cputime(out);
>> + }
>> +}
>> +
>> +__bpf_kfunc_end_defs();
>> +
>> +BTF_KFUNCS_START(bpf_rstat_common_kfunc_ids)
>> +BTF_ID_FLAGS(func, bpf_css_flush_rstat, KF_SLEEPABLE)
>> +BTF_ID_FLAGS(func, bpf_cgroup_base_stat, KF_SLEEPABLE)
>
>Why are these SLEEPABLE?
>
The css_rstat_flush() calls might_sleep() and cond_resched().
The bpf_cgroup_base_stat() takes an rstat spinlock_t, which can sleep on
PREEMPT_RT.
So both marked as SLEEPABLE.
>Thanks.
>
>--
>tejun
Please let me know your concerns. Thanks!
Best,
Ziyang