Re: [PATCH v2] kernel/sched/fair: Fix the issue of virtual runtime conversion error

From: Peter Zijlstra

Date: Wed May 27 2026 - 08:00:01 EST


On Wed, May 27, 2026 at 03:21:13PM +0800, Li kunyu wrote:
> The logic of the function here should be to convert the virtual runtime
> into actual time by combining it with the weight of the scheduling
> entity.
> However, it cannot be converted by simply converting actual time into
> virtual running time. A reverse conversion is required to obtain the
> correct time.
>
> Signed-off-by: Li kunyu <likunyu10@xxxxxxx>
> ---
> v2: Use the div64_ul function to perform division operation
>
> kernel/sched/fair.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index 69361c63353a..53f3373c1735 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -7033,7 +7033,9 @@ static void hrtick_start_fair(struct rq *rq, struct task_struct *p)
> resched_curr(rq);
> return;
> }
> - delta = (se->load.weight * vdelta) / NICE_0_LOAD;
> +
> + if (unlikely(se->load.weight != NICE_0_LOAD))
> + delta = div64_ul(NICE_0_LOAD * vdelta, se->load.weight);
>
> /*
> * Correct for instantaneous load of other classes.

This seems wrong. Note that calc_delta_fair() does:

vdelta := (delta * NICE_0_LOAD) / se->load.weight

which gets us time -> vtime. Therefore the vtime -> time transform is
the inverse of that:

delta := (vdelta * se->load.weight) / NICE_0_LOAD;

which is exactly what the current code does.

Specifically:

NICE_0_LOAD se->load.weight
(delta * ---------------) * --------------- = delta
se->load.weight NICE_0_LOAD