This is a note to let you know that I've just added the patch titled sched/eevdf: Fix miscalculation in reweight_entity() when se is not curr to the 6.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: sched-eevdf-fix-miscalculation-in-reweight_entity-wh.patch and it can be found in the queue-6.6 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit 430214b0569e1f00bb26ccbc9760f8ec85c505c8 Author: Tianchen Ding <dtcccc@xxxxxxxxxxxxxxxxx> Date: Wed Mar 6 10:21:33 2024 +0800 sched/eevdf: Fix miscalculation in reweight_entity() when se is not curr [ Upstream commit afae8002b4fd3560c8f5f1567f3c3202c30a70fa ] reweight_eevdf() only keeps V unchanged inside itself. When se != cfs_rq->curr, it would be dequeued from rb tree first. So that V is changed and the result is wrong. Pass the original V to reweight_eevdf() to fix this issue. Fixes: eab03c23c2a1 ("sched/eevdf: Fix vruntime adjustment on reweight") Signed-off-by: Tianchen Ding <dtcccc@xxxxxxxxxxxxxxxxx> [peterz: flip if() condition for clarity] Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> Reviewed-by: Abel Wu <wuyun.abel@xxxxxxxxxxxxx> Link: https://lkml.kernel.org/r/20240306022133.81008-3-dtcccc@xxxxxxxxxxxxxxxxx Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 71e7cf6f77f65..a5466eb6a1f15 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3626,11 +3626,10 @@ static inline void dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) { } #endif -static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se, +static void reweight_eevdf(struct sched_entity *se, u64 avruntime, unsigned long weight) { unsigned long old_weight = se->load.weight; - u64 avruntime = avg_vruntime(cfs_rq); s64 vlag, vslice; /* @@ -3737,24 +3736,26 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, unsigned long weight) { bool curr = cfs_rq->curr == se; + u64 avruntime; if (se->on_rq) { /* commit outstanding execution time */ update_curr(cfs_rq); + avruntime = avg_vruntime(cfs_rq); if (!curr) __dequeue_entity(cfs_rq, se); update_load_sub(&cfs_rq->load, se->load.weight); } dequeue_load_avg(cfs_rq, se); - if (!se->on_rq) { + if (se->on_rq) { + reweight_eevdf(se, avruntime, weight); + } else { /* * Because we keep se->vlag = V - v_i, while: lag_i = w_i*(V - v_i), * we need to scale se->vlag when w_i changes. */ se->vlag = div_s64(se->vlag * se->load.weight, weight); - } else { - reweight_eevdf(cfs_rq, se, weight); } update_load_set(&se->load, weight);