[RFC PATCH v7 28/29] sched/rt: Prevent CPU offline operation on active rt-cgroups.
From: Yuri Andriaccio
Date: Mon Nov 09 2026 - 11:44:51 EST
Introduce tg_can_offline_cpu and prevent CPU offlining if any rt-cgroup has
requested bandwidth on the offlining core.
Signed-off-by: Yuri Andriaccio <yurand2000@xxxxxxxxx>
---
kernel/sched/core.c | 3 +++
kernel/sched/rt.c | 27 +++++++++++++++++++++++++++
kernel/sched/sched.h | 1 +
3 files changed, 31 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 59bd9599c509..4321be11c6c7 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -8717,6 +8717,9 @@ int sched_cpu_deactivate(unsigned int cpu)
struct rq *rq = cpu_rq(cpu);
int ret;
+ if (!tg_can_offline_cpu(cpu))
+ return -EBUSY;
+
ret = dl_bw_deactivate(cpu);
if (ret)
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 37e4b24183ab..e5f05aeabd5c 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -2853,6 +2853,33 @@ int cpuset_can_change(struct cgroup *cgroup) {
return 1;
}
+static int __tg_can_offline_cpu(struct task_group *tg, void *data) {
+ const struct dl_bandwidth *dl_b;
+ int *d = data;
+ int cpu = *d;
+
+ if (tg == &root_task_group)
+ return 0;
+
+ guard(raw_spinlock_irq)(dl_bw_lock_of_tg(tg));
+ dl_b = dl_bandwidth_read(tg);
+ if (dl_b->dl_runtime == RUNTIME_INF)
+ return 0;
+
+ return cpumask_test_cpu(cpu, dl_b->active_mask);
+}
+
+int tg_can_offline_cpu(int cpu) {
+ if (!rt_group_sched_enabled())
+ return 1;
+
+ guard(rcu)();
+ if (walk_tg_tree(__tg_can_offline_cpu, tg_nop, &cpu))
+ return 0;
+
+ return 1;
+}
+
int sched_rt_can_attach(struct task_group *tg)
{
struct task_group *ctx;
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 9410d1909729..a6aae4375a31 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -590,6 +590,7 @@ extern int tg_rt_internal_bandwidth(struct task_group *tg, int cpu,
u64 *rt_period_us, u64 *rt_runtime_us);
extern int tg_set_rt_bandwidth(struct task_group *tg,
u64 rt_period_us, u64 rt_runtime_us);
+extern int tg_can_offline_cpu(int cpu);
extern int sched_rt_can_attach(struct task_group *tg);
extern struct task_group *sched_create_group(struct task_group *parent);
--
2.56.0