Commit 48d963c7 authored by Tianchen Ding's avatar Tianchen Ding Committed by Ma Wupeng
Browse files

sched/eevdf: Fix miscalculation in reweight_entity() when se is not curr

stable inclusion
from stable-v6.6.30
commit 2cf53d801da728968b762299068868c13478df94
bugzilla: https://gitee.com/openeuler/kernel/issues/I9MPZ8

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=2cf53d801da728968b762299068868c13478df94



--------------------------------

[ 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: default avatarTianchen Ding <dtcccc@linux.alibaba.com>
[peterz: flip if() condition for clarity]
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarAbel Wu <wuyun.abel@bytedance.com>
Link: https://lkml.kernel.org/r/20240306022133.81008-3-dtcccc@linux.alibaba.com


Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarZhangPeng <zhangpeng362@huawei.com>
parent b76b74c5
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -3777,11 +3777,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;

	/*
@@ -3888,24 +3887,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);