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>
This commit is contained in:
parent
dc21662b5b
commit
2cf53d801d
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue