Re: [PATCH v16 4/7] sched: Fix runtime accounting w/ split exec & sched contexts

From: Peter Zijlstra
Date: Thu Apr 17 2025 - 07:13:03 EST


On Fri, Apr 11, 2025 at 11:02:38PM -0700, John Stultz wrote:

> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index e43993a4e5807..da8b0970c6655 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -1143,22 +1143,33 @@ static void update_tg_load_avg(struct cfs_rq *cfs_rq)
> }
> #endif /* CONFIG_SMP */
>
> -static s64 update_curr_se(struct rq *rq, struct sched_entity *curr)
> +static s64 update_se_times(struct rq *rq, struct sched_entity *se)

update_se()

> {
> u64 now = rq_clock_task(rq);
> s64 delta_exec;
>
> - delta_exec = now - curr->exec_start;
> + delta_exec = now - se->exec_start;
> if (unlikely(delta_exec <= 0))
> return delta_exec;
>
> - curr->exec_start = now;
> - curr->sum_exec_runtime += delta_exec;
> + se->exec_start = now;
> + if (entity_is_task(se)) {
> + struct task_struct *running = rq->curr;
> + /*
> + * If se is a task, we account the time against the running
> + * task, as w/ proxy-exec they may not be the same.
> + */
> + running->se.exec_start = now;
> + running->se.sum_exec_runtime += delta_exec;
> + } else {
> + /* If not task, account the time against se */
> + se->sum_exec_runtime += delta_exec;
> + }


So I am confused; you're accounting runtime to the actual running task,
but then accounting the same runtime to the cgroup of the donor.

This seems somewhat irregular.

Please consider all of update_curr_task(), and if they all want to be
against rq->curr, rather than rq->donor then more changes are needed.


> @@ -1213,7 +1224,7 @@ s64 update_curr_common(struct rq *rq)
> struct task_struct *donor = rq->donor;
> s64 delta_exec;
>
> - delta_exec = update_curr_se(rq, &donor->se);
> + delta_exec = update_se_times(rq, &donor->se);
> if (likely(delta_exec > 0))
> update_curr_task(donor, delta_exec);
>
> @@ -1233,7 +1244,7 @@ static void update_curr(struct cfs_rq *cfs_rq)
> if (unlikely(!curr))
> return;
>
> - delta_exec = update_curr_se(rq, curr);
> + delta_exec = update_se_times(rq, curr);
> if (unlikely(delta_exec <= 0))
> return;

I think I've tripped over this before, on how update_curr_common() uses
donor and update_curr() curr. This definitely needs a comment. Because
at first glance they're not the same.