[RFC PATCH v4 02/28] sched/deadline: Distinct between dl_rq and my_q

Yuri Andriaccio posted 28 patches 8 hours ago
[RFC PATCH v4 02/28] sched/deadline: Distinct between dl_rq and my_q
Posted by Yuri Andriaccio 8 hours ago
From: luca abeni <luca.abeni@santannapisa.it>

Split the single runqueue pointer in sched_dl_entity into two separate
pointers, following the existing pattern used by sched_rt_entity:

- dl_rq: Points to the deadline runqueue where this entity is queued
         (global runqueue).
- my_q:  Points to the runqueue that this entity serves (for servers).

This distinction is currently redundant for the fair_server (both point
to the same CPU's structures), but is essential for future RT cgroup
support where deadline servers will be queued on the global dl_rq while
serving tasks from cgroup-specific runqueues.

Update rq_of_dl_se() to use container_of() to recover the global rq from
dl_rq, and update fair.c to explicitly use my_q (local rq) when accessing
the served runqueue.

Update dl_server_init() to take a dl_rq pointer (use to retrieve the
global runqueue where the dl_server is scheduled) and a rq pointer (for
the local runqueue served by the server).

Signed-off-by: luca abeni <luca.abeni@santannapisa.it>
Signed-off-by: Yuri Andriaccio <yurand2000@gmail.com>
---
 include/linux/sched.h   |  6 ++++--
 kernel/sched/deadline.c | 11 +++++++----
 kernel/sched/fair.c     |  4 ++--
 kernel/sched/sched.h    |  3 ++-
 4 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index b469878de2..000aa3b2b1 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -729,12 +729,14 @@ struct sched_dl_entity {
 	 * Bits for DL-server functionality. Also see the comment near
 	 * dl_server_update().
 	 *
-	 * @rq the runqueue this server is for
+	 * @dl_rq the runqueue on which this entity is (to be) queued
+	 * @my_q  the runqueue "owned" by this entity
 	 *
 	 * @server_has_tasks() returns true if @server_pick return a
 	 * runnable task.
 	 */
-	struct rq			*rq;
+	struct dl_rq			*dl_rq;
+	struct rq			*my_q;
 	dl_server_pick_f		server_pick_task;
 
 #ifdef CONFIG_RT_MUTEXES
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index d7940c45f7..e36d98eb5f 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -75,11 +75,12 @@ static inline struct rq *rq_of_dl_rq(struct dl_rq *dl_rq)
 
 static inline struct rq *rq_of_dl_se(struct sched_dl_entity *dl_se)
 {
-	struct rq *rq = dl_se->rq;
+	struct rq *rq;
 
 	if (!dl_server(dl_se))
 		rq = task_rq(dl_task_of(dl_se));
-
+	else
+		rq = container_of(dl_se->dl_rq, struct rq, dl);
 	return rq;
 }
 
@@ -1604,10 +1605,12 @@ void dl_server_stop(struct sched_dl_entity *dl_se)
 	dl_se->dl_server_active = 0;
 }
 
-void dl_server_init(struct sched_dl_entity *dl_se, struct rq *rq,
+void dl_server_init(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq,
+		    struct rq *served_rq,
 		    dl_server_pick_f pick_task)
 {
-	dl_se->rq = rq;
+	dl_se->dl_rq = dl_rq;
+	dl_se->my_q  = served_rq;
 	dl_se->server_pick_task = pick_task;
 }
 
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 5b75232427..9c724d8232 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -8959,7 +8959,7 @@ static struct task_struct *__pick_next_task_fair(struct rq *rq, struct task_stru
 
 static struct task_struct *fair_server_pick_task(struct sched_dl_entity *dl_se)
 {
-	return pick_task_fair(dl_se->rq);
+	return pick_task_fair(dl_se->my_q);
 }
 
 void fair_server_init(struct rq *rq)
@@ -8968,7 +8968,7 @@ void fair_server_init(struct rq *rq)
 
 	init_dl_entity(dl_se);
 
-	dl_server_init(dl_se, rq, fair_server_pick_task);
+	dl_server_init(dl_se, &rq->dl, rq, fair_server_pick_task);
 }
 
 /*
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index adfb6e3409..10733b7cb7 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -408,7 +408,8 @@ extern s64 dl_scaled_delta_exec(struct rq *rq, struct sched_dl_entity *dl_se, s6
 extern void dl_server_update(struct sched_dl_entity *dl_se, s64 delta_exec);
 extern void dl_server_start(struct sched_dl_entity *dl_se);
 extern void dl_server_stop(struct sched_dl_entity *dl_se);
-extern void dl_server_init(struct sched_dl_entity *dl_se, struct rq *rq,
+extern void dl_server_init(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq,
+		    struct rq *served_rq,
 		    dl_server_pick_f pick_task);
 extern void sched_init_dl_servers(void);
 
-- 
2.51.0