Re: [PATCH 4/4] sched/fair: Rework/fix task_h_load()

From: Peter Zijlstra

Date: Mon Aug 31 2026 - 06:38:11 EST


On Mon, Aug 31, 2026 at 12:10:42PM +0200, Vincent Guittot wrote:
> > +static inline void __update_cfs_rq_h_load(struct cfs_rq *cfs_rq,
> > + struct sched_entity *se,
> > + struct cfs_rq *p_cfs_rq)
> > +{
> > + unsigned long load = cfs_rq->avg.load_avg;
> > +
> > + if (cfs_rq != &cfs_rq->rq->cfs) {
>
> A comment explaining that the 2 belows are used for the case where
> for_each_sched_entity has not been called to set backlink would be
> helpful

Fair enough; something like so?

/*
* These last two arguments can be NULL then used outside of
* the for_each_sched_entity() hierarchy iteration. Like in
* __update_blocked_fair() where leaf_cfs_rq_list is iterated
* instead.
*/

> > + if (!se)
> > + se = &container_of(cfs_rq, struct cfs_tg_state, cfs_rq)->se;
> > + if (!p_cfs_rq)
> > + p_cfs_rq = cfs_rq_of(se);
> > +
> > + load = p_cfs_rq->h_load;
> > + load = div64_ul(load * se->avg.load_avg,
> > + p_cfs_rq->avg.load_avg + 1);
> > + }
> > +
> > + WRITE_ONCE(cfs_rq->h_load, load);
> > +}
> > +
> > +static inline bool update_cfs_rq_h_load(struct cfs_rq *cfs_rq,
> > + struct sched_entity *se,
> > + struct cfs_rq *p_cfs_rq)
> > +{
> > + /*
> > + * Mask out the segment bits, if the remaining bits match, then there
> > + * hasn't been a decay since the last time.
> > + */
> > + if ((cfs_rq->last_h_load_update & ~PELT_SEGMENT_MASK) ==
> > + (cfs_rq->avg.last_update_time & ~PELT_SEGMENT_MASK))
> > + return false;
> > +
> > + __update_cfs_rq_h_load(cfs_rq, se, p_cfs_rq);
> > +
> > + cfs_rq->last_h_load_update = cfs_rq->avg.last_update_time;
> > + return true;
> > +}