[RFC PATCH v7 22/29] sched/rt: Try pull task on empty server pick.
From: Yuri Andriaccio
Date: Mon Nov 09 2026 - 11:42:32 EST
Try to pull task on a server with an empty runqueue before returning NULL (and
thus shutting down).
---
When all the servers of a cgroup are throttled, work is pending, and any one of
the servers is replenished, it may happen that the runqueue is empty and thus
the replenished server is immediately shut down.
The server may try to pull a task so that the cgroup could consume its
allocated runtime as soon as it is replenished.
Signed-off-by: Yuri Andriaccio <yurand2000@xxxxxxxxx>
---
kernel/sched/deadline.c | 8 ++++++++
kernel/sched/rt.c | 13 +++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 64df71ab370d..219493427e0b 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -2910,6 +2910,14 @@ static struct task_struct *__pick_task_dl(struct rq *rq, struct rq_flags *rf)
if (dl_server(dl_se)) {
p = dl_se->server_pick_task(dl_se, rf);
+
+ /*
+ * server_pick_task may drop the runqueue lock, so check if
+ * something has shifted.
+ */
+ if (pick_next_dl_entity(dl_rq) != dl_se)
+ goto again;
+
if (!p) {
dl_server_stop(dl_se);
goto again;
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 9d95cf5fd520..839977b05d53 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -286,14 +286,23 @@ int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent)
}
static struct sched_rt_entity *pick_next_rt_entity(struct rt_rq *rt_rq);
+static void pull_rt_task(struct rq *);
static struct task_struct *rt_server_pick(struct sched_dl_entity *dl_se, struct rq_flags *rf)
{
struct rt_rq *rt_rq = &dl_se->my_q->rt;
+ struct rq *global_rq = global_rq_of_rt_rq(rt_rq);
struct task_struct *p;
- if (!sched_rt_runnable(dl_se->my_q))
- return NULL;
+ if (!sched_rt_runnable(dl_se->my_q)) {
+ rq_unpin_lock(global_rq, rf);
+ pull_rt_task(rq_of_rt_rq(rt_rq));
+ update_rq_clock(global_rq);
+ rq_repin_lock(global_rq, rf);
+
+ if (!sched_rt_runnable(dl_se->my_q))
+ return NULL;
+ }
p = rt_task_of(pick_next_rt_entity(rt_rq));
--
2.56.0