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