[PATCH v2 3/4] sched/fair: Extend for_each_sched_entity() with a back-link
From: Peter Zijlstra
Date: Tue Sep 29 2026 - 04:55:24 EST
Leave a trail of bread crumbs, such that we can find our way back down the
hierarchy. No actual users yet, but split out because its a bit tricky.
Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
---
kernel/sched/fair.c | 14 +++++++++++---
kernel/sched/sched.h | 1 +
2 files changed, 12 insertions(+), 3 deletions(-)
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -318,8 +318,13 @@ const struct sched_class fair_sched_clas
#ifdef CONFIG_FAIR_GROUP_SCHED
/* Walk up scheduling entities hierarchy */
-#define for_each_sched_entity(se, cfs_rq) \
- for (; (se) && ((cfs_rq) = cfs_rq_of(se)); (se) = (se)->parent)
+#define for_each_sched_entity(se, cfs_rq) \
+ for (struct sched_entity *_BL = NULL; \
+ (se) && ((cfs_rq) = cfs_rq_of(se), (cfs_rq)->backlink = _BL, true);\
+ (se) = (se)->parent, _BL = (se))
+
+#define for_each_sched_entity_bl(se, cfs_rq) \
+ for (; ((se) = (cfs_rq)->backlink); (cfs_rq) = group_cfs_rq(se))
static inline bool list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
{
@@ -456,6 +461,9 @@ static int se_is_idle(struct sched_entit
#define for_each_sched_entity(se, cfs_rq) \
for (; (se) && ((cfs_rq) = cfs_rq_of(se)); (se) = NULL)
+#define for_each_sched_entity_bl(se, cfs_rq) \
+ for (; ((se) = NULL);)
+
static inline bool list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
{
return true;
@@ -15233,7 +15241,7 @@ static inline void task_tick_core(struct
/*
* se_fi_update - Update the cfs_rq->zero_vruntime_fi in a CFS hierarchy if needed.
*/
-static void se_fi_update(const struct sched_entity *se, unsigned int fi_seq,
+static void se_fi_update(struct sched_entity *se, unsigned int fi_seq,
bool forceidle)
{
struct cfs_rq *cfs_rq;
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -726,6 +726,7 @@ struct cfs_rq {
unsigned long tg_runnable_avg_contrib;
long propagate;
long prop_runnable_sum;
+ struct sched_entity *backlink;
/*
* h_load = weight * f(tg)