[RFC PATCH v5 07/29] sched/rt: Remove unnecessary runqueue pointer in struct rt_rq

From: Yuri Andriaccio

Date: Thu Apr 30 2026 - 17:43:42 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 served_rq_of_rt_rq to retrieve the runqueue the given rt_rq is
serving.

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

diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 392212ac90d8..dd4aee5570aa 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 = served_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 = served_rq_of_rt_rq(rt_rq);

queue_balance_callback(rq, &per_cpu(rt_pull_head, rq->cpu), pull_rt_task);
}
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 5833905d8eaa..770de5afd3a9 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -850,8 +850,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 */
@@ -3308,11 +3306,16 @@ static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se)
return container_of_const(rt_se, struct task_struct, rt);
}

+static inline struct rq *served_rq_of_rt_rq(struct rt_rq *rt_rq)
+{
+ WARN_ON(!rt_group_sched_enabled() && rt_rq->tg != &root_task_group);
+ return container_of_const(rt_rq, struct rq, rt);
+}
+
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 cpu_rq(served_rq_of_rt_rq(rt_rq)->cpu);
}

static inline struct rt_rq *rt_rq_of_se(struct sched_rt_entity *rt_se)
@@ -3323,10 +3326,7 @@ static inline struct rt_rq *rt_rq_of_se(struct sched_rt_entity *rt_se)

static inline struct rq *rq_of_rt_se(struct sched_rt_entity *rt_se)
{
- struct rt_rq *rt_rq = rt_se->rt_rq;
-
- WARN_ON(!rt_group_sched_enabled() && rt_rq->tg != &root_task_group);
- return rt_rq->rq;
+ return rq_of_rt_rq(rt_se->rt_rq);
}
#else
static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se)
@@ -3334,6 +3334,11 @@ static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se)
return container_of_const(rt_se, struct task_struct, rt);
}

+static inline struct rq *served_rq_of_rt_rq(struct rt_rq *rt_rq)
+{
+ return container_of_const(rt_rq, struct rq, rt);
+}
+
static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
{
return container_of_const(rt_rq, struct rq, rt);
--
2.53.0