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

From: Vincent Guittot

Date: Mon Aug 31 2026 - 08:13:00 EST


On Mon, 31 Aug 2026 at 12:37, Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote:
>
> 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?

yes, looks good

>
> /*
> * These last two arguments can be NULL then used outside of
s/then/when/ ?

> * 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;
> > > +}