Skip to content

Commit

Permalink
sched/eevdf: Fix miscalculation in reweight_entity() when se is not curr
Browse files Browse the repository at this point in the history
[ Upstream commit afae800 ]

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: eab03c2 ("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>
  • Loading branch information
dtcccc authored and gregkh committed May 2, 2024
1 parent dc21662 commit 2cf53d8
Showing 1 changed file with 6 additions and 5 deletions.
11 changes: 6 additions & 5 deletions kernel/sched/fair.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/*
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 2cf53d8

Please sign in to comment.