[RFC PATCH v6 08/25] sched/rt: Remove unnecessary runqueue pointer in struct rt_rq

From: Yuri Andriaccio

Date: Mon Jun 08 2026 - 08:22:24 EST


Remove the rq field in struct rt_rq.
The rq field now is just caching the pointer to the global runqueue of the
given rt_rq, so it is unnecessary as the global runqueue can be retrieved
in other ways.

Introduce global_rq_of_rt_rq to retrieve the global runqueue which serves a
rt_rq's dl_server.
Rework rq_of_rt_rq to retrieve the runqueue a rt_rq is serving.

Signed-off-by: Yuri Andriaccio <yurand2000@xxxxxxxxx>
---
kernel/sched/rt.c | 21 +++++++++------------
kernel/sched/sched.h | 16 ++++++++++++----
2 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 7b526a86083c..4575c234ae46 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -101,10 +101,7 @@ void init_tg_rt_entry(struct task_group *tg, struct rt_rq *rt_rq,
struct sched_rt_entity *rt_se, int cpu,
struct sched_rt_entity *parent)
{
- struct rq *rq = cpu_rq(cpu);
-
rt_rq->highest_prio.curr = MAX_RT_PRIO-1;
- rt_rq->rq = rq;
rt_rq->tg = tg;

tg->rt_rq[cpu] = rt_rq;
@@ -184,7 +181,7 @@ static void pull_rt_task(struct rq *);

static inline void rt_queue_push_tasks(struct rt_rq *rt_rq)
{
- struct rq *rq = container_of_const(rt_rq, struct rq, rt);
+ struct rq *rq = global_rq_of_rt_rq(rt_rq);

if (!has_pushable_tasks(rt_rq))
return;
@@ -194,7 +191,7 @@ static inline void rt_queue_push_tasks(struct rt_rq *rt_rq)

static inline void rt_queue_pull_task(struct rt_rq *rt_rq)
{
- struct rq *rq = container_of_const(rt_rq, struct rq, rt);
+ struct rq *rq = global_rq_of_rt_rq(rt_rq);

queue_balance_callback(rq, &per_cpu(rt_pull_head, rq->cpu), pull_rt_task);
}
@@ -222,7 +219,7 @@ static void enqueue_pushable_task(struct rt_rq *rt_rq, struct task_struct *p)
rt_rq->highest_prio.next = p->prio;

if (!rt_rq->overloaded) {
- rt_set_overload(rq_of_rt_rq(rt_rq));
+ rt_set_overload(global_rq_of_rt_rq(rt_rq));
rt_rq->overloaded = 1;
}
}
@@ -240,7 +237,7 @@ static void dequeue_pushable_task(struct rt_rq *rt_rq, struct task_struct *p)
rt_rq->highest_prio.next = MAX_RT_PRIO-1;

if (rt_rq->overloaded) {
- rt_clear_overload(rq_of_rt_rq(rt_rq));
+ rt_clear_overload(global_rq_of_rt_rq(rt_rq));
rt_rq->overloaded = 0;
}
}
@@ -495,7 +492,7 @@ update_stats_wait_start_rt(struct rt_rq *rt_rq, struct sched_rt_entity *rt_se)
if (!stats)
return;

- __update_stats_wait_start(rq_of_rt_rq(rt_rq), p, stats);
+ __update_stats_wait_start(global_rq_of_rt_rq(rt_rq), p, stats);
}

static inline void
@@ -512,7 +509,7 @@ update_stats_enqueue_sleeper_rt(struct rt_rq *rt_rq, struct sched_rt_entity *rt_
if (!stats)
return;

- __update_stats_enqueue_sleeper(rq_of_rt_rq(rt_rq), p, stats);
+ __update_stats_enqueue_sleeper(global_rq_of_rt_rq(rt_rq), p, stats);
}

static inline void
@@ -540,7 +537,7 @@ update_stats_wait_end_rt(struct rt_rq *rt_rq, struct sched_rt_entity *rt_se)
if (!stats)
return;

- __update_stats_wait_end(rq_of_rt_rq(rt_rq), p, stats);
+ __update_stats_wait_end(global_rq_of_rt_rq(rt_rq), p, stats);
}

static inline void
@@ -564,11 +561,11 @@ update_stats_dequeue_rt(struct rt_rq *rt_rq, struct sched_rt_entity *rt_se,
state = READ_ONCE(p->__state);
if (state & TASK_INTERRUPTIBLE)
__schedstat_set(p->stats.sleep_start,
- rq_clock(rq_of_rt_rq(rt_rq)));
+ rq_clock(global_rq_of_rt_rq(rt_rq)));

if (state & TASK_UNINTERRUPTIBLE)
__schedstat_set(p->stats.block_start,
- rq_clock(rq_of_rt_rq(rt_rq)));
+ rq_clock(global_rq_of_rt_rq(rt_rq)));
}
}

diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index a217c4ab6660..3aa29fe932fc 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -857,8 +857,6 @@ struct rt_rq {
raw_spinlock_t rt_runtime_lock;

unsigned int rt_nr_boosted;
-
- struct rq *rq; /* this is always top-level rq, cache? */
#endif
#ifdef CONFIG_CGROUP_SCHED
struct task_group *tg; /* this tg has "this" rt_rq on given CPU for runnable entities */
@@ -3337,9 +3335,14 @@ static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se)

static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
{
- /* Cannot fold with non-CONFIG_RT_GROUP_SCHED version, layout */
WARN_ON(!rt_group_sched_enabled() && rt_rq->tg != &root_task_group);
- return rt_rq->rq;
+ return container_of_const(rt_rq, struct rq, rt);
+}
+
+static inline struct rq *global_rq_of_rt_rq(struct rt_rq *rt_rq)
+{
+ /* Cannot fold with non-CONFIG_RT_GROUP_SCHED version, layout */
+ return cpu_rq(rq_of_rt_rq(rt_rq)->cpu);
}

static inline struct rt_rq *rt_rq_of_se(struct sched_rt_entity *rt_se)
@@ -3358,6 +3361,11 @@ static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
return container_of_const(rt_rq, struct rq, rt);
}

+static inline struct rq *global_rq_of_rt_rq(struct rt_rq *rt_rq)
+{
+ return container_of_const(rt_rq, struct rq, rt);
+}
+
static inline struct rt_rq *rt_rq_of_se(struct sched_rt_entity *rt_se)
{
struct rq *rq = task_rq(rt_task_of(rt_se));
--
2.54.0