@@ -203,6 +203,11 @@ struct scx_exit_task_args {
203
203
struct scx_cgroup_init_args {
204
204
/* the weight of the cgroup [1..10000] */
205
205
u32 weight ;
206
+
207
+ /* bandwidth control parameters from cpu.max and cpu.max.burst */
208
+ u64 bw_period_us ;
209
+ u64 bw_quota_us ;
210
+ u64 bw_burst_us ;
206
211
};
207
212
208
213
enum scx_cpu_preempt_reason {
@@ -664,9 +669,31 @@ struct sched_ext_ops {
664
669
* @cgrp: cgroup whose weight is being updated
665
670
* @weight: new weight [1..10000]
666
671
*
667
- * Update @tg 's weight to @weight.
672
+ * Update @cgrp 's weight to @weight.
668
673
*/
669
674
void (* cgroup_set_weight )(struct cgroup * cgrp , u32 weight );
675
+
676
+ /**
677
+ * @cgroup_set_bandwidth: A cgroup's bandwidth is being changed
678
+ * @cgrp: cgroup whose bandwidth is being updated
679
+ * @period_us: bandwidth control period
680
+ * @quota_us: bandwidth control quota
681
+ * @burst_us: bandwidth control burst
682
+ *
683
+ * Update @cgrp's bandwidth control parameters. This is from the cpu.max
684
+ * cgroup interface.
685
+ *
686
+ * @quota_us / @period_us determines the CPU bandwidth @cgrp is entitled
687
+ * to. For example, if @period_us is 1_000_000 and @quota_us is
688
+ * 2_500_000. @cgrp is entitled to 2.5 CPUs. @burst_us can be
689
+ * interpreted in the same fashion and specifies how much @cgrp can
690
+ * burst temporarily. The specific control mechanism and thus the
691
+ * interpretation of @period_us and burstiness is upto to the BPF
692
+ * scheduler.
693
+ */
694
+ void (* cgroup_set_bandwidth )(struct cgroup * cgrp ,
695
+ u64 period_us , u64 quota_us , u64 burst_us );
696
+
670
697
#endif /* CONFIG_EXT_GROUP_SCHED */
671
698
672
699
/*
@@ -4059,6 +4086,8 @@ static bool scx_cgroup_enabled;
4059
4086
void scx_tg_init (struct task_group * tg )
4060
4087
{
4061
4088
tg -> scx .weight = CGROUP_WEIGHT_DFL ;
4089
+ tg -> scx .bw_period_us = default_bw_period_us ();
4090
+ tg -> scx .bw_quota_us = RUNTIME_INF ;
4062
4091
}
4063
4092
4064
4093
int scx_tg_online (struct task_group * tg )
@@ -4073,7 +4102,10 @@ int scx_tg_online(struct task_group *tg)
4073
4102
if (scx_cgroup_enabled ) {
4074
4103
if (SCX_HAS_OP (sch , cgroup_init )) {
4075
4104
struct scx_cgroup_init_args args =
4076
- { .weight = tg -> scx .weight };
4105
+ { .weight = tg -> scx .weight ,
4106
+ .bw_period_us = tg -> scx .bw_period_us ,
4107
+ .bw_quota_us = tg -> scx .bw_quota_us ,
4108
+ .bw_burst_us = tg -> scx .bw_burst_us };
4077
4109
4078
4110
ret = SCX_CALL_OP_RET (sch , SCX_KF_UNLOCKED , cgroup_init ,
4079
4111
NULL , tg -> css .cgroup , & args );
@@ -4225,6 +4257,27 @@ void scx_group_set_idle(struct task_group *tg, bool idle)
4225
4257
/* TODO: Implement ops->cgroup_set_idle() */
4226
4258
}
4227
4259
4260
+ void scx_group_set_bandwidth (struct task_group * tg ,
4261
+ u64 period_us , u64 quota_us , u64 burst_us )
4262
+ {
4263
+ struct scx_sched * sch = scx_root ;
4264
+
4265
+ percpu_down_read (& scx_cgroup_rwsem );
4266
+
4267
+ if (scx_cgroup_enabled && SCX_HAS_OP (sch , cgroup_set_bandwidth ) &&
4268
+ (tg -> scx .bw_period_us != period_us ||
4269
+ tg -> scx .bw_quota_us != quota_us ||
4270
+ tg -> scx .bw_burst_us != burst_us ))
4271
+ SCX_CALL_OP (sch , SCX_KF_UNLOCKED , cgroup_set_bandwidth , NULL ,
4272
+ tg_cgrp (tg ), period_us , quota_us , burst_us );
4273
+
4274
+ tg -> scx .bw_period_us = period_us ;
4275
+ tg -> scx .bw_quota_us = quota_us ;
4276
+ tg -> scx .bw_burst_us = burst_us ;
4277
+
4278
+ percpu_up_read (& scx_cgroup_rwsem );
4279
+ }
4280
+
4228
4281
static void scx_cgroup_lock (void )
4229
4282
{
4230
4283
percpu_down_write (& scx_cgroup_rwsem );
@@ -4400,7 +4453,12 @@ static int scx_cgroup_init(struct scx_sched *sch)
4400
4453
rcu_read_lock ();
4401
4454
css_for_each_descendant_pre (css , & root_task_group .css ) {
4402
4455
struct task_group * tg = css_tg (css );
4403
- struct scx_cgroup_init_args args = { .weight = tg -> scx .weight };
4456
+ struct scx_cgroup_init_args args = {
4457
+ .weight = tg -> scx .weight ,
4458
+ .bw_period_us = tg -> scx .bw_period_us ,
4459
+ .bw_quota_us = tg -> scx .bw_quota_us ,
4460
+ .bw_burst_us = tg -> scx .bw_burst_us ,
4461
+ };
4404
4462
4405
4463
if ((tg -> scx .flags &
4406
4464
(SCX_TG_ONLINE | SCX_TG_INITED )) != SCX_TG_ONLINE )
@@ -5902,6 +5960,7 @@ static s32 sched_ext_ops__cgroup_prep_move(struct task_struct *p, struct cgroup
5902
5960
static void sched_ext_ops__cgroup_move (struct task_struct * p , struct cgroup * from , struct cgroup * to ) {}
5903
5961
static void sched_ext_ops__cgroup_cancel_move (struct task_struct * p , struct cgroup * from , struct cgroup * to ) {}
5904
5962
static void sched_ext_ops__cgroup_set_weight (struct cgroup * cgrp , u32 weight ) {}
5963
+ static void sched_ext_ops__cgroup_set_bandwidth (struct cgroup * cgrp , u64 period_us , u64 quota_us , u64 burst_us ) {}
5905
5964
#endif
5906
5965
static void sched_ext_ops__cpu_online (s32 cpu ) {}
5907
5966
static void sched_ext_ops__cpu_offline (s32 cpu ) {}
@@ -5939,6 +5998,7 @@ static struct sched_ext_ops __bpf_ops_sched_ext_ops = {
5939
5998
.cgroup_move = sched_ext_ops__cgroup_move ,
5940
5999
.cgroup_cancel_move = sched_ext_ops__cgroup_cancel_move ,
5941
6000
.cgroup_set_weight = sched_ext_ops__cgroup_set_weight ,
6001
+ .cgroup_set_bandwidth = sched_ext_ops__cgroup_set_bandwidth ,
5942
6002
#endif
5943
6003
.cpu_online = sched_ext_ops__cpu_online ,
5944
6004
.cpu_offline = sched_ext_ops__cpu_offline ,
0 commit comments