]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
sched/ext: Implement cgroup_set_idle() callback
authorzhidao su <suzhidao@xiaomi.com>
Sat, 11 Oct 2025 07:16:51 +0000 (15:16 +0800)
committerTejun Heo <tj@kernel.org>
Tue, 14 Oct 2025 20:17:33 +0000 (10:17 -1000)
Implement the missing cgroup_set_idle() callback that was marked as a
TODO. This allows BPF schedulers to be notified when a cgroup's idle
state changes, enabling them to adjust their scheduling behavior
accordingly.

The implementation follows the same pattern as other cgroup callbacks
like cgroup_set_weight() and cgroup_set_bandwidth(). It checks if the
BPF scheduler has implemented the callback and invokes it with the
appropriate parameters.

Fixes a spelling error in the cgroup_set_bandwidth() documentation.

tj: s/scx_cgroup_rwsem/scx_cgroup_ops_rwsem/ to fix build breakage.

Signed-off-by: zhidao su <soolaugust@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
include/linux/sched/ext.h
kernel/sched/ext.c
kernel/sched/ext_internal.h

index d82b7a9b0658be75faf5aec0984ec2cc45ec38f0..9848aeab278649277c56d614403eb39ab73adca9 100644 (file)
@@ -228,6 +228,7 @@ struct scx_task_group {
        u64                     bw_period_us;
        u64                     bw_quota_us;
        u64                     bw_burst_us;
+       bool                    idle;
 #endif
 };
 
index 4b1467d3541a4eb03e0b9383a33ef17417c4d2da..430749ce46ab37320caca408aef5822394a244f3 100644 (file)
@@ -3066,6 +3066,7 @@ void scx_tg_init(struct task_group *tg)
        tg->scx.weight = CGROUP_WEIGHT_DFL;
        tg->scx.bw_period_us = default_bw_period_us();
        tg->scx.bw_quota_us = RUNTIME_INF;
+       tg->scx.idle = false;
 }
 
 int scx_tg_online(struct task_group *tg)
@@ -3214,7 +3215,18 @@ void scx_group_set_weight(struct task_group *tg, unsigned long weight)
 
 void scx_group_set_idle(struct task_group *tg, bool idle)
 {
-       /* TODO: Implement ops->cgroup_set_idle() */
+       struct scx_sched *sch = scx_root;
+
+       percpu_down_read(&scx_cgroup_ops_rwsem);
+
+       if (scx_cgroup_enabled && SCX_HAS_OP(sch, cgroup_set_idle))
+               SCX_CALL_OP(sch, SCX_KF_UNLOCKED, cgroup_set_idle, NULL,
+                           tg_cgrp(tg), idle);
+
+       /* Update the task group's idle state */
+       tg->scx.idle = idle;
+
+       percpu_up_read(&scx_cgroup_ops_rwsem);
 }
 
 void scx_group_set_bandwidth(struct task_group *tg,
@@ -5017,6 +5029,7 @@ static void sched_ext_ops__cgroup_move(struct task_struct *p, struct cgroup *fro
 static void sched_ext_ops__cgroup_cancel_move(struct task_struct *p, struct cgroup *from, struct cgroup *to) {}
 static void sched_ext_ops__cgroup_set_weight(struct cgroup *cgrp, u32 weight) {}
 static void sched_ext_ops__cgroup_set_bandwidth(struct cgroup *cgrp, u64 period_us, u64 quota_us, u64 burst_us) {}
+static void sched_ext_ops__cgroup_set_idle(struct cgroup *cgrp, bool idle) {}
 #endif
 static void sched_ext_ops__cpu_online(s32 cpu) {}
 static void sched_ext_ops__cpu_offline(s32 cpu) {}
@@ -5055,6 +5068,7 @@ static struct sched_ext_ops __bpf_ops_sched_ext_ops = {
        .cgroup_cancel_move     = sched_ext_ops__cgroup_cancel_move,
        .cgroup_set_weight      = sched_ext_ops__cgroup_set_weight,
        .cgroup_set_bandwidth   = sched_ext_ops__cgroup_set_bandwidth,
+       .cgroup_set_idle        = sched_ext_ops__cgroup_set_idle,
 #endif
        .cpu_online             = sched_ext_ops__cpu_online,
        .cpu_offline            = sched_ext_ops__cpu_offline,
index b3617abed5108141a93ed53661b2e91f4b4a2a10..7d00a0a2456e27bbc51cdeeb696d246a7e09c07e 100644 (file)
@@ -697,12 +697,23 @@ struct sched_ext_ops {
         * 2_500_000. @cgrp is entitled to 2.5 CPUs. @burst_us can be
         * interpreted in the same fashion and specifies how much @cgrp can
         * burst temporarily. The specific control mechanism and thus the
-        * interpretation of @period_us and burstiness is upto to the BPF
+        * interpretation of @period_us and burstiness is up to the BPF
         * scheduler.
         */
        void (*cgroup_set_bandwidth)(struct cgroup *cgrp,
                                     u64 period_us, u64 quota_us, u64 burst_us);
 
+       /**
+        * @cgroup_set_idle: A cgroup's idle state is being changed
+        * @cgrp: cgroup whose idle state is being updated
+        * @idle: whether the cgroup is entering or exiting idle state
+        *
+        * Update @cgrp's idle state to @idle. This callback is invoked when
+        * a cgroup transitions between idle and non-idle states, allowing the
+        * BPF scheduler to adjust its behavior accordingly.
+        */
+       void (*cgroup_set_idle)(struct cgroup *cgrp, bool idle);
+
 #endif /* CONFIG_EXT_GROUP_SCHED */
 
        /*