From: Peter Zijlstra <peterz@infradead.org>
To: mingo@kernel.org
Cc: peterz@infradead.org, juri.lelli@redhat.com,
vincent.guittot@linaro.org, dietmar.eggemann@arm.com,
rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de,
vschneid@redhat.com, kprateek.nayak@amd.com, tj@kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 2/4] sched/fair: Fold cfs_rq_of(se) into for_each_sched_entity()
Date: Fri, 28 Aug 2026 09:41:01 +0200 [thread overview]
Message-ID: <20260828075558.438093356@infradead.org> (raw)
In-Reply-To: 20260828074059.232353141@infradead.org
Pretty much every for_each_sched_entity() loop does: cfs_rq = cfs_rq_of(se) as
the very first thing. Fold it into the for_each_sched_entity() macro.
This paves the way to have the macro track a backlink transparantly.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
kernel/sched/fair.c | 81 +++++++++++++++++++++++-----------------------------
1 file changed, 37 insertions(+), 44 deletions(-)
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -317,8 +317,8 @@ const struct sched_class fair_sched_clas
#ifdef CONFIG_FAIR_GROUP_SCHED
/* Walk up scheduling entities hierarchy */
-#define for_each_sched_entity(se) \
- for (; se; se = se->parent)
+#define for_each_sched_entity(se, cfs_rq) \
+ for (; (se) && ((cfs_rq) = cfs_rq_of(se)); (se) = (se)->parent)
static inline bool list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
{
@@ -452,8 +452,8 @@ static int se_is_idle(struct sched_entit
#else /* !CONFIG_FAIR_GROUP_SCHED: */
-#define for_each_sched_entity(se) \
- for (; se; se = NULL)
+#define for_each_sched_entity(se, cfs_rq) \
+ for (; (se) && ((cfs_rq) = cfs_of_of(se)); (se) = NULL)
static inline bool list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
{
@@ -2075,9 +2075,10 @@ static void update_curr(struct cfs_rq *c
static void update_curr_fair(struct rq *rq)
{
struct sched_entity *se = &rq->donor->se;
+ struct cfs_rq *cfs_rq;
- for_each_sched_entity(se)
- update_curr(cfs_rq_of(se));
+ for_each_sched_entity(se, cfs_rq)
+ update_curr(cfs_rq);
}
static inline void
@@ -4800,18 +4801,19 @@ static void reweight_task_fair(struct rq
{
struct sched_entity *se = &p->se;
unsigned long weight = NICE_0_LOAD;
+ struct cfs_rq *cfs_rq = cfs_rq_of(se);
if (se->on_rq)
update_curr_fair(rq);
- reweight_entity(cfs_rq_of(se), se, lw->weight);
+ reweight_entity(cfs_rq, se, lw->weight);
se->load.inv_weight = lw->inv_weight;
if (!se->on_rq)
return;
- for_each_sched_entity(se)
- weight = __calc_prop_weight(cfs_rq_of(se), se, weight);
+ for_each_sched_entity(se, cfs_rq)
+ weight = __calc_prop_weight(cfs_rq, se, weight);
reweight_eevdf(&rq->cfs, &p->se, weight, p->se.on_rq);
}
@@ -6382,6 +6384,8 @@ static __always_inline void return_cfs_r
static void set_delayed(struct sched_entity *se)
{
+ struct cfs_rq *cfs_rq;
+
se->sched_delayed = 1;
/*
@@ -6392,15 +6396,14 @@ static void set_delayed(struct sched_ent
if (!entity_is_task(se))
return;
- for_each_sched_entity(se) {
- struct cfs_rq *cfs_rq = cfs_rq_of(se);
-
+ for_each_sched_entity(se, cfs_rq)
cfs_rq->h_nr_runnable--;
- }
}
static void clear_delayed(struct sched_entity *se)
{
+ struct cfs_rq *cfs_rq;
+
se->sched_delayed = 0;
/*
@@ -6412,11 +6415,8 @@ static void clear_delayed(struct sched_e
if (!entity_is_task(se))
return;
- for_each_sched_entity(se) {
- struct cfs_rq *cfs_rq = cfs_rq_of(se);
-
+ for_each_sched_entity(se, cfs_rq)
cfs_rq->h_nr_runnable++;
- }
}
static void
@@ -7078,14 +7078,16 @@ void unthrottle_cfs_rq(struct cfs_rq *cf
walk_tg_tree_from(cfs_rq->tg, tg_nop, tg_unthrottle_up, (void *)rq);
if (!cfs_rq->load.weight) {
+ struct cfs_rq *cfs_rq_se;
+
if (!cfs_rq->on_list)
return;
/*
* Nothing to run but something to decay (on_list)?
* Complete the branch.
*/
- for_each_sched_entity(se) {
- if (list_add_leaf_cfs_rq(cfs_rq_of(se)))
+ for_each_sched_entity(se, cfs_rq_se) {
+ if (list_add_leaf_cfs_rq(cfs_rq_se))
break;
}
}
@@ -7931,13 +7933,12 @@ static unsigned long enqueue_hierarchy(s
struct sched_entity *se = &p->se;
int h_nr_idle = task_has_idle_policy(p);
int h_nr_runnable = 1;
+ struct cfs_rq *cfs_rq;
if (task_new && se->sched_delayed)
h_nr_runnable = 0;
- for_each_sched_entity(se) {
- struct cfs_rq *cfs_rq = cfs_rq_of(se);
-
+ for_each_sched_entity(se, cfs_rq) {
update_curr(cfs_rq);
if (!se->on_rq) {
@@ -8066,16 +8067,15 @@ static void dequeue_hierarchy(struct tas
bool task_sleep = flags & DEQUEUE_SLEEP;
bool task_delayed = flags & DEQUEUE_DELAYED;
bool task_throttled = flags & DEQUEUE_THROTTLE;
- int h_nr_runnable = 0;
int h_nr_idle = task_has_idle_policy(p);
+ int h_nr_runnable = 0;
+ struct cfs_rq *cfs_rq;
bool dequeue = true;
if (task_sleep || task_delayed || !se->sched_delayed)
h_nr_runnable = 1;
- for_each_sched_entity(se) {
- struct cfs_rq *cfs_rq = cfs_rq_of(se);
-
+ for_each_sched_entity(se, cfs_rq) {
update_curr(cfs_rq);
if (dequeue) {
@@ -11301,8 +11301,7 @@ static void update_cfs_rq_h_load(struct
return;
WRITE_ONCE(cfs_rq->h_load_next, NULL);
- for_each_sched_entity(se) {
- cfs_rq = cfs_rq_of(se);
+ for_each_sched_entity(se, cfs_rq) {
WRITE_ONCE(cfs_rq->h_load_next, se);
if (cfs_rq->last_h_load_update == now)
break;
@@ -14948,9 +14947,9 @@ static inline void task_tick_core(struct
static void se_fi_update(const struct sched_entity *se, unsigned int fi_seq,
bool forceidle)
{
- for_each_sched_entity(se) {
- struct cfs_rq *cfs_rq = cfs_rq_of(se);
+ struct cfs_rq *cfs_rq;
+ for_each_sched_entity(se, cfs_rq) {
if (forceidle) {
if (cfs_rq->forceidle_seq == fi_seq)
break;
@@ -15028,10 +15027,8 @@ static void task_tick_fair(struct rq *rq
unsigned long weight = NICE_0_LOAD;
struct cfs_rq *cfs_rq;
- for_each_sched_entity(se) {
- cfs_rq = cfs_rq_of(se);
+ for_each_sched_entity(se, cfs_rq) {
entity_tick(cfs_rq, se, hrtick);
-
weight = __calc_prop_weight(cfs_rq, se, weight);
}
@@ -15113,9 +15110,7 @@ static void propagate_entity_cfs_rq(stru
/* Start to propagate at parent */
se = se->parent;
- for_each_sched_entity(se) {
- cfs_rq = cfs_rq_of(se);
-
+ for_each_sched_entity(se, cfs_rq) {
update_load_avg(cfs_rq, se, UPDATE_TG);
if (!cfs_rq_pelt_clock_throttled(cfs_rq))
@@ -15218,9 +15213,7 @@ static void set_next_task_fair(struct rq
if (on_rq)
__dequeue_entity(cfs_rq, se);
- for_each_sched_entity(se) {
- cfs_rq = cfs_rq_of(se);
-
+ for_each_sched_entity(se, cfs_rq) {
if (!IS_ENABLED(CONFIG_FAIR_GROUP_SCHED) ||
!first || !cfs_rq->h_curr)
set_next_entity(cfs_rq, se);
@@ -15420,13 +15413,14 @@ static int __sched_group_set_shares(stru
for_each_possible_cpu(i) {
struct rq *rq = cpu_rq(i);
struct sched_entity *se = tg_se(tg, i);
+ struct cfs_rq *cfs_rq;
struct rq_flags rf;
/* Propagate contribution to hierarchy */
rq_lock_irqsave(rq, &rf);
update_rq_clock(rq);
- for_each_sched_entity(se) {
- update_load_avg(cfs_rq_of(se), se, UPDATE_TG);
+ for_each_sched_entity(se, cfs_rq) {
+ update_load_avg(cfs_rq, se, UPDATE_TG);
update_cfs_group(se);
}
rq_unlock_irqrestore(rq, &rf);
@@ -15473,6 +15467,7 @@ int sched_group_set_idle(struct task_gro
struct sched_entity *se = tg_se(tg, i);
struct cfs_rq *grp_cfs_rq = tg_cfs_rq(tg, i);
bool was_idle = cfs_rq_is_idle(grp_cfs_rq);
+ struct cfs_rq *cfs_rq;
long idle_task_delta;
struct rq_flags rf;
@@ -15487,9 +15482,7 @@ int sched_group_set_idle(struct task_gro
if (!cfs_rq_is_idle(grp_cfs_rq))
idle_task_delta *= -1;
- for_each_sched_entity(se) {
- struct cfs_rq *cfs_rq = cfs_rq_of(se);
-
+ for_each_sched_entity(se, cfs_rq) {
if (!se->on_rq)
break;
next prev parent reply other threads:[~2026-08-28 7:56 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-28 7:40 [PATCH 0/4] sched/fair: Rework tash_h_load() Peter Zijlstra
2026-08-28 7:41 ` [PATCH 1/4] sched: Rename/clarify sched_class::task_tick(.queued) argument Peter Zijlstra
2026-08-28 7:41 ` Peter Zijlstra [this message]
2026-08-28 7:41 ` [PATCH 3/4] sched/fair: Extend for_each_sched_entity() with a back-link Peter Zijlstra
2026-08-28 7:41 ` [PATCH 4/4] sched/fair: Rework/fix task_h_load() Peter Zijlstra
2026-08-31 10:10 ` Vincent Guittot
2026-08-31 10:37 ` Peter Zijlstra
2026-08-31 12:06 ` Vincent Guittot
2026-08-31 13:07 ` Peter Zijlstra
2026-09-02 5:26 ` Chen Yu
2026-09-02 7:55 ` Vincent Guittot
2026-09-02 8:13 ` Peter Zijlstra
2026-09-02 10:36 ` Peter Zijlstra
2026-09-02 10:39 ` Vincent Guittot
2026-09-02 10:37 ` Vincent Guittot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260828075558.438093356@infradead.org \
--to=peterz@infradead.org \
--cc=bsegall@google.com \
--cc=dietmar.eggemann@arm.com \
--cc=juri.lelli@redhat.com \
--cc=kprateek.nayak@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@suse.de \
--cc=mingo@kernel.org \
--cc=rostedt@goodmis.org \
--cc=tj@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=vschneid@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.