diff options
author | Tianchen Ding <dtcccc@linux.alibaba.com> | 2024-03-06 05:21:33 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-05-02 17:35:34 +0300 |
commit | 2fb25655a12a270efd3b3efb07e8f0ec4690dc36 (patch) | |
tree | d22aac04d3e30e4f91a7086cdba8e4e8a7333fda | |
parent | 5154b1e37231a766f1d24fda9da6fd2b2f0d555f (diff) | |
download | linux-2fb25655a12a270efd3b3efb07e8f0ec4690dc36.tar.xz |
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@linux.alibaba.com>
[peterz: flip if() condition for clarity]
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Abel Wu <wuyun.abel@bytedance.com>
Link: https://lkml.kernel.org/r/20240306022133.81008-3-dtcccc@linux.alibaba.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r-- | kernel/sched/fair.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 69d215887342..b9ee4397b484 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3670,11 +3670,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; /* @@ -3781,24 +3780,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); |