[PATCH 2/4] sched/eevdf: Update se->vprot in reweight_entity()

Peter Zijlstra posted 4 patches 1 week, 3 days ago
[PATCH 2/4] sched/eevdf: Update se->vprot in reweight_entity()
Posted by Peter Zijlstra 1 week, 3 days ago
From: Wang Tao <wangtao554@huawei.com>

In the EEVDF framework with Run-to-Parity protection, `se->vprot` is an
independent variable defining the virtual protection timestamp.

When `reweight_entity()` is called (e.g., via nice/renice), it performs
the following actions to preserve Lag consistency:
 1. Scales `se->vlag` based on the new weight.
 2. Calls `place_entity()`, which recalculates `se->vruntime` based on
    the new weight and scaled lag.

However, the current implementation fails to update `se->vprot`, leading
to mismatches between the task's actual runtime and its expected duration.

Fixes: 63304558ba5d ("sched/eevdf: Curb wakeup-preemption")
Suggested-by: Zhang Qiao <zhangqiao22@huawei.com>
Signed-off-by: Wang Tao <wangtao554@huawei.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260120123113.3518950-1-wangtao554@huawei.com
---
 kernel/sched/fair.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3790,6 +3790,8 @@ static void reweight_entity(struct cfs_r
 			    unsigned long weight)
 {
 	bool curr = cfs_rq->curr == se;
+	bool rel_vprot = false;
+	u64 vprot;
 
 	if (se->on_rq) {
 		/* commit outstanding execution time */
@@ -3797,6 +3799,11 @@ static void reweight_entity(struct cfs_r
 		update_entity_lag(cfs_rq, se);
 		se->deadline -= se->vruntime;
 		se->rel_deadline = 1;
+		if (curr && protect_slice(se)) {
+			vprot = se->vprot - se->vruntime;
+			rel_vprot = true;
+		}
+
 		cfs_rq->nr_queued--;
 		if (!curr)
 			__dequeue_entity(cfs_rq, se);
@@ -3812,6 +3819,9 @@ static void reweight_entity(struct cfs_r
 	if (se->rel_deadline)
 		se->deadline = div_s64(se->deadline * se->load.weight, weight);
 
+	if (rel_vprot)
+		vprot = div_s64(vprot * se->load.weight, weight);
+
 	update_load_set(&se->load, weight);
 
 	do {
@@ -3823,6 +3833,8 @@ static void reweight_entity(struct cfs_r
 	enqueue_load_avg(cfs_rq, se);
 	if (se->on_rq) {
 		place_entity(cfs_rq, se, 0);
+		if (rel_vprot)
+			se->vprot = se->vruntime + vprot;
 		update_load_add(&cfs_rq->load, se->load.weight);
 		if (!curr)
 			__enqueue_entity(cfs_rq, se);
Re: [PATCH 2/4] sched/eevdf: Update se->vprot in reweight_entity()
Posted by Vincent Guittot 1 week, 2 days ago
On Fri, 30 Jan 2026 at 10:47, Peter Zijlstra <peterz@infradead.org> wrote:
>
> From: Wang Tao <wangtao554@huawei.com>
>
> In the EEVDF framework with Run-to-Parity protection, `se->vprot` is an
> independent variable defining the virtual protection timestamp.
>
> When `reweight_entity()` is called (e.g., via nice/renice), it performs
> the following actions to preserve Lag consistency:
>  1. Scales `se->vlag` based on the new weight.
>  2. Calls `place_entity()`, which recalculates `se->vruntime` based on
>     the new weight and scaled lag.
>
> However, the current implementation fails to update `se->vprot`, leading
> to mismatches between the task's actual runtime and its expected duration.
>
> Fixes: 63304558ba5d ("sched/eevdf: Curb wakeup-preemption")
> Suggested-by: Zhang Qiao <zhangqiao22@huawei.com>
> Signed-off-by: Wang Tao <wangtao554@huawei.com>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>

Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>

> Link: https://patch.msgid.link/20260120123113.3518950-1-wangtao554@huawei.com
> ---
>  kernel/sched/fair.c |   12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -3790,6 +3790,8 @@ static void reweight_entity(struct cfs_r
>                             unsigned long weight)
>  {
>         bool curr = cfs_rq->curr == se;
> +       bool rel_vprot = false;
> +       u64 vprot;
>
>         if (se->on_rq) {
>                 /* commit outstanding execution time */
> @@ -3797,6 +3799,11 @@ static void reweight_entity(struct cfs_r
>                 update_entity_lag(cfs_rq, se);
>                 se->deadline -= se->vruntime;
>                 se->rel_deadline = 1;
> +               if (curr && protect_slice(se)) {
> +                       vprot = se->vprot - se->vruntime;
> +                       rel_vprot = true;
> +               }
> +
>                 cfs_rq->nr_queued--;
>                 if (!curr)
>                         __dequeue_entity(cfs_rq, se);
> @@ -3812,6 +3819,9 @@ static void reweight_entity(struct cfs_r
>         if (se->rel_deadline)
>                 se->deadline = div_s64(se->deadline * se->load.weight, weight);
>
> +       if (rel_vprot)
> +               vprot = div_s64(vprot * se->load.weight, weight);
> +
>         update_load_set(&se->load, weight);
>
>         do {
> @@ -3823,6 +3833,8 @@ static void reweight_entity(struct cfs_r
>         enqueue_load_avg(cfs_rq, se);
>         if (se->on_rq) {
>                 place_entity(cfs_rq, se, 0);
> +               if (rel_vprot)
> +                       se->vprot = se->vruntime + vprot;
>                 update_load_add(&cfs_rq->load, se->load.weight);
>                 if (!curr)
>                         __enqueue_entity(cfs_rq, se);
>
>