mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] sched/eevdf: Fix vprot across reweighting
@ 2026-10-03 11:46 Kayra Cizmeci
  2026-10-11  7:13 ` Christian Loehle
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Kayra Cizmeci @ 2026-10-03 11:46 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak
  Cc: kayracizmeci, christian.loehle, elif.topuz, linux-kernel, sh,
	Ingo Molnar

Currently in reweighting, while a tasks vruntime changes dead protection
could go alive, or alive protection could decrease, increase and go dead.

To fix this, implement rel_vprot similar to rel_deadline. Only
major difference is that rel_vprot is not dependent on
PLACE_REL_DEADLINE, because there are no mechanisms (unlike deadline)
that recalculate vprot. So it gets carried.

Fixes: 80390ead2080 ("sched/fair: Separate se->vlag from se->vprot")
Fixes: bcd74b2ffdd0 ("sched/fair: Only set slice protection at pick time")
Link: https://lore.kernel.org/all/20261001164609.244156-1-kayracizmeci@gmail.com/
Link: https://lore.kernel.org/all/e4700a93-ebd5-4c7e-88b5-d606437a13c0@arm.com/
Co-developed-by: Christian Loehle <christian.loehle@arm.com>
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Signed-off-by: Kayra Cizmeci <kayracizmeci@gmail.com>
---
Hi all,

Base is commit 4a3b51aab6e25244d97936aa65e6d5425adf98e1
on tip/sched/core.

NOTE: Christian, this version is really different from yours.
I still added the tags, hope that's not a problem.
If it is tho, please let me know.

I've thought a lot about this. I was at first thinking about
a simpler approach, but to be similar and consistent with the
current approaches to the similar problem on rel_deadline,
I thought this would be better. 


I also ran some tests, from a VM that was inside a VM that
was working on MacOS on my Mac. (This is like a war crime...)


MY GREAT AND DEFINITELY 100% CORRECT ULTRAMEGA TEST 

We first pin 2 tasks to the same CPU, (let's say TA and TB)
Then we change TA's nice value 3000 times between 0 and 10 (like, 0,10,0,10...)
We save weight and rem = (s64)(se->vprot - se->vruntime) on both
__dequeue_task() and enqueue_task_fair().

Then, we multiply weight and rem for both savings and
divide them. If they are between 0.95-1.05 we accept the
results as correct, if not well... Wrong.

I'm also terrible at math and a bit less terrible on coding
so these results should be 100% correct.

MY GREAT AND DEFINITELY 100% CORRECT ULTRAMEGA TEST RESULTS:

NRTP = NO_RUN_TO_PARITY

       Live Protection Wrong Counts
  +--------+-------------+--------------+
  |        |     BASE    | BASE + PATCH |
  +--------+-------------+--------------+
  | Normal |  6002/6002  |    0/6003    |
  +--------+-------------+--------------+
  |  NRTP  |    53/53    |     0/55     |
  +--------+-------------+--------------+

On Base Normal, maximum amount of increase was 4.49x,
while the maximum amount of decrease was 0.17x and the average was
1.64x.

While on Base NRTP, maximum amount of increase was 2.27x,
maximum amount of decrease was 0.31x and the average was
1.08x.

Well that's all. You may or may not ask where are the revived ones are.
This test does not really covers that part. 

Or as I like to say it, my computer ate that part.

That's really really all. Aside from the code :-).


 include/linux/sched.h |  1 +
 kernel/sched/core.c   |  1 +
 kernel/sched/fair.c   | 34 ++++++++++++++++++++++++----------
 3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 7b91cae4a59c..bd9e2d119910 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -584,6 +584,7 @@ struct sched_entity {
 	unsigned char			on_rq;
 	unsigned char			sched_delayed;
 	unsigned char			rel_deadline;
+	unsigned char			rel_vprot;
 	unsigned char			custom_slice;
 					/* hole */
 
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 71d3c948e14a..f1241f572cdc 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4638,6 +4638,7 @@ static void __sched_fork(u64 clone_flags, struct task_struct *p)
 	p->se.vruntime			= 0;
 	p->se.vlag			= 0;
 	p->se.rel_deadline		= 0;
+	p->se.rel_vprot			= 0;
 	INIT_LIST_HEAD(&p->se.group_node);
 
 	/* A delayed task cannot be in clone(). */
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index b42a0ca2a69e..0bcd3a77aba4 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4614,7 +4614,7 @@ dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
 }
 
 static void
-rescale_entity(struct sched_entity *se, unsigned long weight, bool rel_vprot)
+rescale_entity(struct sched_entity *se, unsigned long weight)
 {
 	long old_weight = se->h_load.weight;
 
@@ -4712,7 +4712,7 @@ rescale_entity(struct sched_entity *se, unsigned long weight, bool rel_vprot)
 	if (se->rel_deadline)
 		se->deadline = div64_long(se->deadline * old_weight, weight);
 
-	if (rel_vprot)
+	if (se->rel_vprot)
 		se->vprot = div64_long(se->vprot * old_weight, weight);
 }
 
@@ -4720,7 +4720,6 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
 			   unsigned long weight, bool on_rq)
 {
 	bool curr = cfs_rq->curr == se;
-	bool rel_vprot = false;
 	u64 avruntime = 0;
 
 	if (se->h_load.weight == weight)
@@ -4733,7 +4732,7 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
 		se->rel_deadline = 1;
 		if (curr && protect_slice(se)) {
 			se->vprot -= avruntime;
-			rel_vprot = true;
+			se->rel_vprot = 1;
 		}
 
 		cfs_rq->h_nr_queued--;
@@ -4741,17 +4740,23 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
 			__dequeue_entity(cfs_rq, se);
 	}
 
-	rescale_entity(se, weight, rel_vprot);
+	rescale_entity(se, weight);
 
 	update_load_set(&se->h_load, weight);
 
 	if (on_rq) {
-		if (rel_vprot)
-			se->vprot += avruntime;
 		se->deadline += avruntime;
 		se->rel_deadline = 0;
 		se->vruntime = avruntime - se->vlag;
 
+		if (se->rel_vprot) {
+			se->vprot += avruntime;
+			se->rel_vprot = 0;
+		} else if (curr) {
+			/* Reweighting must not revive expired slice protection. */
+			cancel_protect_slice(se);
+		}
+
 		if (!curr)
 			__enqueue_entity(cfs_rq, se);
 		cfs_rq->h_nr_queued++;
@@ -6297,6 +6302,11 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
 
 	se->vruntime = vruntime - lag;
 
+	if (se->rel_vprot) {
+		se->vprot += se->vruntime;
+		se->rel_vprot = 0;
+	}
+
 	if (update_zero)
 		update_zero_vruntime(cfs_rq, -lag);
 
@@ -8143,9 +8153,13 @@ static bool __dequeue_task(struct rq *rq, struct task_struct *p, int flags)
 
 	dequeue_hierarchy(p, flags);
 
-	if (sched_feat(PLACE_REL_DEADLINE) && !task_sleep) {
-		se->deadline -= se->vruntime;
-		se->rel_deadline = 1;
+	if (!task_sleep) {
+		se->vprot = protect_slice(se) ? se->vprot - se->vruntime : 0;
+		se->rel_vprot = 1;
+		if (sched_feat(PLACE_REL_DEADLINE)) {
+			se->deadline -= se->vruntime;
+			se->rel_deadline = 1;
+		}
 	}
 	if (se != cfs_rq->curr)
 		__dequeue_entity(cfs_rq, se);
-- 
2.53.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] sched/eevdf: Fix vprot across reweighting
  2026-10-03 11:46 [PATCH] sched/eevdf: Fix vprot across reweighting Kayra Cizmeci
@ 2026-10-11  7:13 ` Christian Loehle
  2026-10-11 10:06   ` Kayra Cizmeci
  2026-10-12  4:39 ` K Prateek Nayak
  2026-10-12 13:40 ` Vincent Guittot
  2 siblings, 1 reply; 9+ messages in thread
From: Christian Loehle @ 2026-10-11  7:13 UTC (permalink / raw)
  To: Kayra Cizmeci, Peter Zijlstra, Ingo Molnar, Juri Lelli,
	Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
	Mel Gorman, Valentin Schneider, K Prateek Nayak
  Cc: elif.topuz, linux-kernel, sh, Ingo Molnar

On 10/3/26 12:46, Kayra Cizmeci wrote:
> Currently in reweighting, while a tasks vruntime changes dead protection
> could go alive, or alive protection could decrease, increase and go dead.
> 
> To fix this, implement rel_vprot similar to rel_deadline. Only

Ah nice find, please allow me to look at this code for a bit if that's
the best way to implement this, will review then, for now

Tested-by: Christian Loehle <christian.loehle@arm.com>

> major difference is that rel_vprot is not dependent on
> PLACE_REL_DEADLINE, because there are no mechanisms (unlike deadline)
> that recalculate vprot. So it gets carried.
> 
> Fixes: 80390ead2080 ("sched/fair: Separate se->vlag from se->vprot")
> Fixes: bcd74b2ffdd0 ("sched/fair: Only set slice protection at pick time")
> Link: https://lore.kernel.org/all/20261001164609.244156-1-kayracizmeci@gmail.com/
> Link: https://lore.kernel.org/all/e4700a93-ebd5-4c7e-88b5-d606437a13c0@arm.com/
> Co-developed-by: Christian Loehle <christian.loehle@arm.com>
> Signed-off-by: Christian Loehle <christian.loehle@arm.com>

FWIW my SOB shouldn't be there anymore.

> Signed-off-by: Kayra Cizmeci <kayracizmeci@gmail.com>
> ---
> Hi all,
> 
> Base is commit 4a3b51aab6e25244d97936aa65e6d5425adf98e1
> on tip/sched/core.
> 
> NOTE: Christian, this version is really different from yours.
> I still added the tags, hope that's not a problem.
> If it is tho, please let me know.
> 
> I've thought a lot about this. I was at first thinking about
> a simpler approach, but to be similar and consistent with the
> current approaches to the similar problem on rel_deadline,
> I thought this would be better. 
> 
> 
> I also ran some tests, from a VM that was inside a VM that
> was working on MacOS on my Mac. (This is like a war crime...)
> 
> 
> MY GREAT AND DEFINITELY 100% CORRECT ULTRAMEGA TEST 
> 
> We first pin 2 tasks to the same CPU, (let's say TA and TB)
> Then we change TA's nice value 3000 times between 0 and 10 (like, 0,10,0,10...)
> We save weight and rem = (s64)(se->vprot - se->vruntime) on both
> __dequeue_task() and enqueue_task_fair().
> 
> Then, we multiply weight and rem for both savings and
> divide them. If they are between 0.95-1.05 we accept the
> results as correct, if not well... Wrong.
> 
> I'm also terrible at math and a bit less terrible on coding
> so these results should be 100% correct.
> 
> MY GREAT AND DEFINITELY 100% CORRECT ULTRAMEGA TEST RESULTS:
> 
> NRTP = NO_RUN_TO_PARITY
> 
>        Live Protection Wrong Counts
>   +--------+-------------+--------------+
>   |        |     BASE    | BASE + PATCH |
>   +--------+-------------+--------------+
>   | Normal |  6002/6002  |    0/6003    |
>   +--------+-------------+--------------+
>   |  NRTP  |    53/53    |     0/55     |
>   +--------+-------------+--------------+
> 
> On Base Normal, maximum amount of increase was 4.49x,
> while the maximum amount of decrease was 0.17x and the average was
> 1.64x.
> 
> While on Base NRTP, maximum amount of increase was 2.27x,
> maximum amount of decrease was 0.31x and the average was
> 1.08x.
> 
> Well that's all. You may or may not ask where are the revived ones are.
> This test does not really covers that part. 
> 
> Or as I like to say it, my computer ate that part.
> 
> That's really really all. Aside from the code :-).
> 
> 
>  include/linux/sched.h |  1 +
>  kernel/sched/core.c   |  1 +
>  kernel/sched/fair.c   | 34 ++++++++++++++++++++++++----------
>  3 files changed, 26 insertions(+), 10 deletions(-)
> 
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 7b91cae4a59c..bd9e2d119910 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -584,6 +584,7 @@ struct sched_entity {
>  	unsigned char			on_rq;
>  	unsigned char			sched_delayed;
>  	unsigned char			rel_deadline;
> +	unsigned char			rel_vprot;
>  	unsigned char			custom_slice;
>  					/* hole */
>  
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 71d3c948e14a..f1241f572cdc 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -4638,6 +4638,7 @@ static void __sched_fork(u64 clone_flags, struct task_struct *p)
>  	p->se.vruntime			= 0;
>  	p->se.vlag			= 0;
>  	p->se.rel_deadline		= 0;
> +	p->se.rel_vprot			= 0;
>  	INIT_LIST_HEAD(&p->se.group_node);
>  
>  	/* A delayed task cannot be in clone(). */
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index b42a0ca2a69e..0bcd3a77aba4 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -4614,7 +4614,7 @@ dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
>  }
>  
>  static void
> -rescale_entity(struct sched_entity *se, unsigned long weight, bool rel_vprot)
> +rescale_entity(struct sched_entity *se, unsigned long weight)
>  {
>  	long old_weight = se->h_load.weight;
>  
> @@ -4712,7 +4712,7 @@ rescale_entity(struct sched_entity *se, unsigned long weight, bool rel_vprot)
>  	if (se->rel_deadline)
>  		se->deadline = div64_long(se->deadline * old_weight, weight);
>  
> -	if (rel_vprot)
> +	if (se->rel_vprot)
>  		se->vprot = div64_long(se->vprot * old_weight, weight);
>  }
>  
> @@ -4720,7 +4720,6 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
>  			   unsigned long weight, bool on_rq)
>  {
>  	bool curr = cfs_rq->curr == se;
> -	bool rel_vprot = false;
>  	u64 avruntime = 0;
>  
>  	if (se->h_load.weight == weight)
> @@ -4733,7 +4732,7 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
>  		se->rel_deadline = 1;
>  		if (curr && protect_slice(se)) {
>  			se->vprot -= avruntime;
> -			rel_vprot = true;
> +			se->rel_vprot = 1;
>  		}
>  
>  		cfs_rq->h_nr_queued--;
> @@ -4741,17 +4740,23 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
>  			__dequeue_entity(cfs_rq, se);
>  	}
>  
> -	rescale_entity(se, weight, rel_vprot);
> +	rescale_entity(se, weight);
>  
>  	update_load_set(&se->h_load, weight);
>  
>  	if (on_rq) {
> -		if (rel_vprot)
> -			se->vprot += avruntime;
>  		se->deadline += avruntime;
>  		se->rel_deadline = 0;
>  		se->vruntime = avruntime - se->vlag;
>  
> +		if (se->rel_vprot) {
> +			se->vprot += avruntime;
> +			se->rel_vprot = 0;
> +		} else if (curr) {
> +			/* Reweighting must not revive expired slice protection. */
> +			cancel_protect_slice(se);
> +		}
> +
>  		if (!curr)
>  			__enqueue_entity(cfs_rq, se);
>  		cfs_rq->h_nr_queued++;
> @@ -6297,6 +6302,11 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
>  
>  	se->vruntime = vruntime - lag;
>  
> +	if (se->rel_vprot) {
> +		se->vprot += se->vruntime;
> +		se->rel_vprot = 0;
> +	}
> +
>  	if (update_zero)
>  		update_zero_vruntime(cfs_rq, -lag);
>  
> @@ -8143,9 +8153,13 @@ static bool __dequeue_task(struct rq *rq, struct task_struct *p, int flags)
>  
>  	dequeue_hierarchy(p, flags);
>  
> -	if (sched_feat(PLACE_REL_DEADLINE) && !task_sleep) {
> -		se->deadline -= se->vruntime;
> -		se->rel_deadline = 1;
> +	if (!task_sleep) {
> +		se->vprot = protect_slice(se) ? se->vprot - se->vruntime : 0;
> +		se->rel_vprot = 1;
> +		if (sched_feat(PLACE_REL_DEADLINE)) {
> +			se->deadline -= se->vruntime;
> +			se->rel_deadline = 1;
> +		}
>  	}
>  	if (se != cfs_rq->curr)
>  		__dequeue_entity(cfs_rq, se);


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] sched/eevdf: Fix vprot across reweighting
  2026-10-11  7:13 ` Christian Loehle
@ 2026-10-11 10:06   ` Kayra Cizmeci
  0 siblings, 0 replies; 9+ messages in thread
From: Kayra Cizmeci @ 2026-10-11 10:06 UTC (permalink / raw)
  To: christian.loehle
  Cc: bsegall, dietmar.eggemann, elif.topuz, juri.lelli, kayracizmeci,
	kprateek.nayak, linux-kernel, mgorman, mingo, mingo, peterz,
	rostedt, sh, vincent.guittot, vschneid

Hi Christian,

> > Currently in reweighting, while a tasks vruntime changes dead protection
> > could go alive, or alive protection could decrease, increase and go dead.
> > 
> > To fix this, implement rel_vprot similar to rel_deadline. Only

> Ah nice find, please allow me to look at this code for a bit if that's
> the best way to implement this, will review then, for now

> Tested-by: Christian Loehle <christian.loehle@arm.com>

Thanks for testing! And yeah, take your time. 

> > major difference is that rel_vprot is not dependent on
> > PLACE_REL_DEADLINE, because there are no mechanisms (unlike deadline)
> > that recalculate vprot. So it gets carried.
> > 
> > Fixes: 80390ead2080 ("sched/fair: Separate se->vlag from se->vprot")
> > Fixes: bcd74b2ffdd0 ("sched/fair: Only set slice protection at pick time")
> > Link: https://lore.kernel.org/all/20261001164609.244156-1-kayracizmeci@gmail.com/
> > Link: https://lore.kernel.org/all/e4700a93-ebd5-4c7e-88b5-d606437a13c0@arm.com/
> > Co-developed-by: Christian Loehle <christian.loehle@arm.com>
> > Signed-off-by: Christian Loehle <christian.loehle@arm.com>

> FWIW my SOB shouldn't be there anymore.

Right. I'll remove it on v2 aside with Co-developed-by.

Thanks!
Kayra

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] sched/eevdf: Fix vprot across reweighting
  2026-10-03 11:46 [PATCH] sched/eevdf: Fix vprot across reweighting Kayra Cizmeci
  2026-10-11  7:13 ` Christian Loehle
@ 2026-10-12  4:39 ` K Prateek Nayak
  2026-10-12 13:40 ` Vincent Guittot
  2 siblings, 0 replies; 9+ messages in thread
From: K Prateek Nayak @ 2026-10-12  4:39 UTC (permalink / raw)
  To: Kayra Cizmeci, Peter Zijlstra, Ingo Molnar, Juri Lelli,
	Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
	Mel Gorman, Valentin Schneider
  Cc: christian.loehle, elif.topuz, linux-kernel, sh, Ingo Molnar

Hello Kayra,

On 10/3/2026 5:16 PM, Kayra Cizmeci wrote:
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 7b91cae4a59c..bd9e2d119910 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -584,6 +584,7 @@ struct sched_entity {
>  	unsigned char			on_rq;
>  	unsigned char			sched_delayed;
>  	unsigned char			rel_deadline;
> +	unsigned char			rel_vprot;
>  	unsigned char			custom_slice;
>  					/* hole */
>  
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 71d3c948e14a..f1241f572cdc 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -4638,6 +4638,7 @@ static void __sched_fork(u64 clone_flags, struct task_struct *p)
>  	p->se.vruntime			= 0;
>  	p->se.vlag			= 0;
>  	p->se.rel_deadline		= 0;
> +	p->se.rel_vprot			= 0;
>  	INIT_LIST_HEAD(&p->se.group_node);
>  
>  	/* A delayed task cannot be in clone(). */
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index b42a0ca2a69e..0bcd3a77aba4 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -4614,7 +4614,7 @@ dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
>  }
>  
>  static void
> -rescale_entity(struct sched_entity *se, unsigned long weight, bool rel_vprot)
> +rescale_entity(struct sched_entity *se, unsigned long weight)
>  {
>  	long old_weight = se->h_load.weight;
>  
> @@ -4712,7 +4712,7 @@ rescale_entity(struct sched_entity *se, unsigned long weight, bool rel_vprot)
>  	if (se->rel_deadline)
>  		se->deadline = div64_long(se->deadline * old_weight, weight);
>  
> -	if (rel_vprot)
> +	if (se->rel_vprot)
>  		se->vprot = div64_long(se->vprot * old_weight, weight);
>  }
>  
> @@ -4720,7 +4720,6 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
>  			   unsigned long weight, bool on_rq)
>  {
>  	bool curr = cfs_rq->curr == se;
> -	bool rel_vprot = false;
>  	u64 avruntime = 0;
>  
>  	if (se->h_load.weight == weight)
> @@ -4733,7 +4732,7 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
>  		se->rel_deadline = 1;
>  		if (curr && protect_slice(se)) {
>  			se->vprot -= avruntime;
> -			rel_vprot = true;
> +			se->rel_vprot = 1;
>  		}
>  
>  		cfs_rq->h_nr_queued--;
> @@ -4741,17 +4740,23 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
>  			__dequeue_entity(cfs_rq, se);
>  	}
>  
> -	rescale_entity(se, weight, rel_vprot);
> +	rescale_entity(se, weight);
>  
>  	update_load_set(&se->h_load, weight);
>  
>  	if (on_rq) {
> -		if (rel_vprot)
> -			se->vprot += avruntime;
>  		se->deadline += avruntime;
>  		se->rel_deadline = 0;
>  		se->vruntime = avruntime - se->vlag;
>  
> +		if (se->rel_vprot) {
> +			se->vprot += avruntime;
> +			se->rel_vprot = 0;
> +		} else if (curr) {
> +			/* Reweighting must not revive expired slice protection. */
> +			cancel_protect_slice(se);

This is the only genuine fix I see in this entire patch where
vruntime adjustment will make the tasks protected and we
probably need to cancel it in that case but i don't get why
we need a new se->rel_vprot for that ...

> +		}
> +
>  		if (!curr)
>  			__enqueue_entity(cfs_rq, se);
>  		cfs_rq->h_nr_queued++;
> @@ -6297,6 +6302,11 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
>  
>  	se->vruntime = vruntime - lag;
>  
> +	if (se->rel_vprot) {
> +		se->vprot += se->vruntime;
> +		se->rel_vprot = 0;
> +	}
> +
>  	if (update_zero)
>  		update_zero_vruntime(cfs_rq, -lag);
>  
> @@ -8143,9 +8153,13 @@ static bool __dequeue_task(struct rq *rq, struct task_struct *p, int flags)
>  
>  	dequeue_hierarchy(p, flags);
>  
> -	if (sched_feat(PLACE_REL_DEADLINE) && !task_sleep) {
> -		se->deadline -= se->vruntime;
> -		se->rel_deadline = 1;
> +	if (!task_sleep) {
> +		se->vprot = protect_slice(se) ? se->vprot - se->vruntime : 0;
> +		se->rel_vprot = 1;

I'm having a super hard time understanding why we need this.

Protect slice is only required for current entities so why do we
care about it during migration? The set_next_task() during next
selection will override it anyway.

What am I missing?

> +		if (sched_feat(PLACE_REL_DEADLINE)) {
> +			se->deadline -= se->vruntime;
> +			se->rel_deadline = 1;
> +		}
>  	}
>  	if (se != cfs_rq->curr)
>  		__dequeue_entity(cfs_rq, se);

-- 
Thanks and Regards,
Prateek


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] sched/eevdf: Fix vprot across reweighting
  2026-10-03 11:46 [PATCH] sched/eevdf: Fix vprot across reweighting Kayra Cizmeci
  2026-10-11  7:13 ` Christian Loehle
  2026-10-12  4:39 ` K Prateek Nayak
@ 2026-10-12 13:40 ` Vincent Guittot
  2026-10-12 13:59   ` Kayra Cizmeci
  2 siblings, 1 reply; 9+ messages in thread
From: Vincent Guittot @ 2026-10-12 13:40 UTC (permalink / raw)
  To: Kayra Cizmeci
  Cc: Peter Zijlstra, Ingo Molnar, Juri Lelli, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, christian.loehle, elif.topuz, linux-kernel, sh,
	Ingo Molnar

On Sat, 3 Oct 2026 at 13:47, Kayra Cizmeci <kayracizmeci@gmail.com> wrote:
>
> Currently in reweighting, while a tasks vruntime changes dead protection
> could go alive, or alive protection could decrease, increase and go dead.
>
> To fix this, implement rel_vprot similar to rel_deadline. Only
> major difference is that rel_vprot is not dependent on
> PLACE_REL_DEADLINE, because there are no mechanisms (unlike deadline)
> that recalculate vprot. So it gets carried.
>
> Fixes: 80390ead2080 ("sched/fair: Separate se->vlag from se->vprot")
> Fixes: bcd74b2ffdd0 ("sched/fair: Only set slice protection at pick time")
> Link: https://lore.kernel.org/all/20261001164609.244156-1-kayracizmeci@gmail.com/
> Link: https://lore.kernel.org/all/e4700a93-ebd5-4c7e-88b5-d606437a13c0@arm.com/
> Co-developed-by: Christian Loehle <christian.loehle@arm.com>
> Signed-off-by: Christian Loehle <christian.loehle@arm.com>
> Signed-off-by: Kayra Cizmeci <kayracizmeci@gmail.com>
> ---
> Hi all,
>
> Base is commit 4a3b51aab6e25244d97936aa65e6d5425adf98e1
> on tip/sched/core.
>
> NOTE: Christian, this version is really different from yours.
> I still added the tags, hope that's not a problem.
> If it is tho, please let me know.
>
> I've thought a lot about this. I was at first thinking about
> a simpler approach, but to be similar and consistent with the
> current approaches to the similar problem on rel_deadline,
> I thought this would be better.
>
>
> I also ran some tests, from a VM that was inside a VM that
> was working on MacOS on my Mac. (This is like a war crime...)
>
>
> MY GREAT AND DEFINITELY 100% CORRECT ULTRAMEGA TEST
>
> We first pin 2 tasks to the same CPU, (let's say TA and TB)
> Then we change TA's nice value 3000 times between 0 and 10 (like, 0,10,0,10...)
> We save weight and rem = (s64)(se->vprot - se->vruntime) on both
> __dequeue_task() and enqueue_task_fair().
>
> Then, we multiply weight and rem for both savings and
> divide them. If they are between 0.95-1.05 we accept the
> results as correct, if not well... Wrong.
>
> I'm also terrible at math and a bit less terrible on coding
> so these results should be 100% correct.
>
> MY GREAT AND DEFINITELY 100% CORRECT ULTRAMEGA TEST RESULTS:
>
> NRTP = NO_RUN_TO_PARITY
>
>        Live Protection Wrong Counts
>   +--------+-------------+--------------+
>   |        |     BASE    | BASE + PATCH |
>   +--------+-------------+--------------+
>   | Normal |  6002/6002  |    0/6003    |
>   +--------+-------------+--------------+
>   |  NRTP  |    53/53    |     0/55     |
>   +--------+-------------+--------------+
>
> On Base Normal, maximum amount of increase was 4.49x,
> while the maximum amount of decrease was 0.17x and the average was
> 1.64x.
>
> While on Base NRTP, maximum amount of increase was 2.27x,
> maximum amount of decrease was 0.31x and the average was
> 1.08x.
>
> Well that's all. You may or may not ask where are the revived ones are.
> This test does not really covers that part.
>
> Or as I like to say it, my computer ate that part.
>
> That's really really all. Aside from the code :-).
>
>
>  include/linux/sched.h |  1 +
>  kernel/sched/core.c   |  1 +
>  kernel/sched/fair.c   | 34 ++++++++++++++++++++++++----------
>  3 files changed, 26 insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 7b91cae4a59c..bd9e2d119910 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -584,6 +584,7 @@ struct sched_entity {
>         unsigned char                   on_rq;
>         unsigned char                   sched_delayed;
>         unsigned char                   rel_deadline;
> +       unsigned char                   rel_vprot;
>         unsigned char                   custom_slice;
>                                         /* hole */
>
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 71d3c948e14a..f1241f572cdc 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -4638,6 +4638,7 @@ static void __sched_fork(u64 clone_flags, struct task_struct *p)
>         p->se.vruntime                  = 0;
>         p->se.vlag                      = 0;
>         p->se.rel_deadline              = 0;
> +       p->se.rel_vprot                 = 0;
>         INIT_LIST_HEAD(&p->se.group_node);
>
>         /* A delayed task cannot be in clone(). */
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index b42a0ca2a69e..0bcd3a77aba4 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -4614,7 +4614,7 @@ dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se)
>  }
>
>  static void
> -rescale_entity(struct sched_entity *se, unsigned long weight, bool rel_vprot)
> +rescale_entity(struct sched_entity *se, unsigned long weight)
>  {
>         long old_weight = se->h_load.weight;
>
> @@ -4712,7 +4712,7 @@ rescale_entity(struct sched_entity *se, unsigned long weight, bool rel_vprot)
>         if (se->rel_deadline)
>                 se->deadline = div64_long(se->deadline * old_weight, weight);
>
> -       if (rel_vprot)
> +       if (se->rel_vprot)
>                 se->vprot = div64_long(se->vprot * old_weight, weight);
>  }
>
> @@ -4720,7 +4720,6 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
>                            unsigned long weight, bool on_rq)
>  {
>         bool curr = cfs_rq->curr == se;
> -       bool rel_vprot = false;
>         u64 avruntime = 0;
>
>         if (se->h_load.weight == weight)
> @@ -4733,7 +4732,7 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
>                 se->rel_deadline = 1;
>                 if (curr && protect_slice(se)) {
>                         se->vprot -= avruntime;
> -                       rel_vprot = true;
> +                       se->rel_vprot = 1;
>                 }
>
>                 cfs_rq->h_nr_queued--;
> @@ -4741,17 +4740,23 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
>                         __dequeue_entity(cfs_rq, se);
>         }
>
> -       rescale_entity(se, weight, rel_vprot);
> +       rescale_entity(se, weight);
>
>         update_load_set(&se->h_load, weight);
>
>         if (on_rq) {
> -               if (rel_vprot)
> -                       se->vprot += avruntime;
>                 se->deadline += avruntime;
>                 se->rel_deadline = 0;
>                 se->vruntime = avruntime - se->vlag;
>
> +               if (se->rel_vprot) {
> +                       se->vprot += avruntime;
> +                       se->rel_vprot = 0;
> +               } else if (curr) {
> +                       /* Reweighting must not revive expired slice protection. */
> +                       cancel_protect_slice(se);
> +               }
> +

I don't get why you need to a se->rel_vprot and all these changes . If
we want to ensure that protection will not be re enabled because of
rescale, we just need the below

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 5c98d8dfce5d..e83836fe44ef 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4951,12 +4951,15 @@ static void reweight_eevdf(struct cfs_rq
*cfs_rq, struct sched_entity *se,
        update_load_set(&se->h_load, weight);

        if (on_rq) {
-               if (rel_vprot)
-                       se->vprot += avruntime;
                se->deadline += avruntime;
                se->rel_deadline = 0;
                se->vruntime = avruntime - se->vlag;

+               if (rel_vprot)
+                       se->vprot += avruntime;
+               else if (curr)
+                       se->vprot = se->vruntime;
+
                if (!curr)
                        __enqueue_entity(cfs_rq, se);
                cfs_rq->h_nr_queued++;

or the below which is even simpler because vprot, vlag and deadline
are rescaled with the same ratio but it implies useless div64_long()
when the protection is already canceled

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 5c98d8dfce5d..5d1b16780b52 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4936,7 +4936,7 @@ static void reweight_eevdf(struct cfs_rq
*cfs_rq, struct sched_entity *se,
                se->vlag = entity_lag(cfs_rq, se, avruntime);
                se->deadline -= avruntime;
                se->rel_deadline = 1;
-               if (curr && protect_slice(se)) {
+               if (curr) {
                        se->vprot -= avruntime;
                        rel_vprot = true;
                }



>                 if (!curr)
>                         __enqueue_entity(cfs_rq, se);
>                 cfs_rq->h_nr_queued++;
> @@ -6297,6 +6302,11 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
>
>         se->vruntime = vruntime - lag;
>
> +       if (se->rel_vprot) {
> +               se->vprot += se->vruntime;
> +               se->rel_vprot = 0;
> +       }
> +
>         if (update_zero)
>                 update_zero_vruntime(cfs_rq, -lag);
>
> @@ -8143,9 +8153,13 @@ static bool __dequeue_task(struct rq *rq, struct task_struct *p, int flags)
>
>         dequeue_hierarchy(p, flags);
>
> -       if (sched_feat(PLACE_REL_DEADLINE) && !task_sleep) {
> -               se->deadline -= se->vruntime;
> -               se->rel_deadline = 1;
> +       if (!task_sleep) {
> +               se->vprot = protect_slice(se) ? se->vprot - se->vruntime : 0;
> +               se->rel_vprot = 1;
> +               if (sched_feat(PLACE_REL_DEADLINE)) {
> +                       se->deadline -= se->vruntime;
> +                       se->rel_deadline = 1;
> +               }
>         }
>         if (se != cfs_rq->curr)
>                 __dequeue_entity(cfs_rq, se);
> --
> 2.53.0
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] sched/eevdf: Fix vprot across reweighting
  2026-10-12 13:40 ` Vincent Guittot
@ 2026-10-12 13:59   ` Kayra Cizmeci
  2026-10-12 14:14     ` Vincent Guittot
  0 siblings, 1 reply; 9+ messages in thread
From: Kayra Cizmeci @ 2026-10-12 13:59 UTC (permalink / raw)
  To: vincent.guittot
  Cc: bsegall, christian.loehle, dietmar.eggemann, elif.topuz,
	juri.lelli, kayracizmeci, kprateek.nayak, linux-kernel, mgorman,
	mingo, mingo, peterz, rostedt, sh, vschneid

> I don't get why you need to a se->rel_vprot and all these changes . If
> we want to ensure that protection will not be re enabled because of
> rescale, we just need the below

> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index 5c98d8dfce5d..e83836fe44ef 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -4951,12 +4951,15 @@ static void reweight_eevdf(struct cfs_rq
> *cfs_rq, struct sched_entity *se,
>         update_load_set(&se->h_load, weight);
> 
>         if (on_rq) {
> -               if (rel_vprot)
> -                       se->vprot += avruntime;
>                 se->deadline += avruntime;
>                 se->rel_deadline = 0;
>                 se->vruntime = avruntime - se->vlag;
> 
> +               if (rel_vprot)
> +                       se->vprot += avruntime;
> +               else if (curr)
> +                       se->vprot = se->vruntime;
> +
>                 if (!curr)
>                         __enqueue_entity(cfs_rq, se);
>                 cfs_rq->h_nr_queued++;

> or the below which is even simpler because vprot, vlag and deadline
> are rescaled with the same ratio but it implies useless div64_long()
> when the protection is already canceled

> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index 5c98d8dfce5d..5d1b16780b52 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -4936,7 +4936,7 @@ static void reweight_eevdf(struct cfs_rq
> *cfs_rq, struct sched_entity *se,
>                 se->vlag = entity_lag(cfs_rq, se, avruntime);
>                 se->deadline -= avruntime;
>                 se->rel_deadline = 1;
> -               if (curr && protect_slice(se)) {
> +               if (curr) {
>                         se->vprot -= avruntime;
>                         rel_vprot = true;
>                 }

Here:

https://lore.kernel.org/all/20261001164609.244156-1-kayracizmeci@gmail.com/
https://lore.kernel.org/all/e4700a93-ebd5-4c7e-88b5-d606437a13c0@arm.com/

Because on_rq can get false. And alive protection complicates things.
And this diff alone wouldn't work.

IDK what else we could do to fix this both cases cleanly tbh.
But there could be a cleaner way.

Thanks,

Kayra



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] sched/eevdf: Fix vprot across reweighting
  2026-10-12 13:59   ` Kayra Cizmeci
@ 2026-10-12 14:14     ` Vincent Guittot
  2026-10-12 15:01       ` Kayra Cizmeci
  0 siblings, 1 reply; 9+ messages in thread
From: Vincent Guittot @ 2026-10-12 14:14 UTC (permalink / raw)
  To: Kayra Cizmeci
  Cc: bsegall, christian.loehle, dietmar.eggemann, elif.topuz,
	juri.lelli, kprateek.nayak, linux-kernel, mgorman, mingo, mingo,
	peterz, rostedt, sh, vschneid

On Mon, 12 Oct 2026 at 15:59, Kayra Cizmeci <kayracizmeci@gmail.com> wrote:
>
> > I don't get why you need to a se->rel_vprot and all these changes . If
> > we want to ensure that protection will not be re enabled because of
> > rescale, we just need the below
>
> > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> > index 5c98d8dfce5d..e83836fe44ef 100644
> > --- a/kernel/sched/fair.c
> > +++ b/kernel/sched/fair.c
> > @@ -4951,12 +4951,15 @@ static void reweight_eevdf(struct cfs_rq
> > *cfs_rq, struct sched_entity *se,
> >         update_load_set(&se->h_load, weight);
> >
> >         if (on_rq) {
> > -               if (rel_vprot)
> > -                       se->vprot += avruntime;
> >                 se->deadline += avruntime;
> >                 se->rel_deadline = 0;
> >                 se->vruntime = avruntime - se->vlag;
> >
> > +               if (rel_vprot)
> > +                       se->vprot += avruntime;
> > +               else if (curr)
> > +                       se->vprot = se->vruntime;
> > +
> >                 if (!curr)
> >                         __enqueue_entity(cfs_rq, se);
> >                 cfs_rq->h_nr_queued++;
>
> > or the below which is even simpler because vprot, vlag and deadline
> > are rescaled with the same ratio but it implies useless div64_long()
> > when the protection is already canceled
>
> > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> > index 5c98d8dfce5d..5d1b16780b52 100644
> > --- a/kernel/sched/fair.c
> > +++ b/kernel/sched/fair.c
> > @@ -4936,7 +4936,7 @@ static void reweight_eevdf(struct cfs_rq
> > *cfs_rq, struct sched_entity *se,
> >                 se->vlag = entity_lag(cfs_rq, se, avruntime);
> >                 se->deadline -= avruntime;
> >                 se->rel_deadline = 1;
> > -               if (curr && protect_slice(se)) {
> > +               if (curr) {
> >                         se->vprot -= avruntime;
> >                         rel_vprot = true;
> >                 }
>
> Here:
>
> https://lore.kernel.org/all/20261001164609.244156-1-kayracizmeci@gmail.com/
> https://lore.kernel.org/all/e4700a93-ebd5-4c7e-88b5-d606437a13c0@arm.com/
>
> Because on_rq can get false. And alive protection complicates things.
> And this diff alone wouldn't work.
>
> IDK what else we could do to fix this both cases cleanly tbh.
> But there could be a cleaner way.

Before 819224e506bc ("sched/fair: Remove dead code on
enqueue_task_fair()"), the reweight_eevdf() was not called for curr so
the false was always true. If we can finally have enqueue curr then we
should skip this case

>
> Thanks,
>
> Kayra
>
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] sched/eevdf: Fix vprot across reweighting
  2026-10-12 14:14     ` Vincent Guittot
@ 2026-10-12 15:01       ` Kayra Cizmeci
  2026-10-12 19:00         ` Kayra Cizmeci
  0 siblings, 1 reply; 9+ messages in thread
From: Kayra Cizmeci @ 2026-10-12 15:01 UTC (permalink / raw)
  To: vincent.guittot
  Cc: bsegall, christian.loehle, dietmar.eggemann, elif.topuz,
	juri.lelli, kayracizmeci, kprateek.nayak, linux-kernel, mgorman,
	mingo, mingo, peterz, rostedt, sh, vschneid

I send one mail, one more to reply comes. Ah.. I love it tho :-)

> Before 819224e506bc ("sched/fair: Remove dead code on
> enqueue_task_fair()"), the reweight_eevdf() was not called for curr so
> the false was always true. If we can finally have enqueue curr then we
> should skip this case

Yeah. The beast I created kills me. Pretty nice.

On sched_change_begin(), cfs_rq->curr is set to NULL. So while entering enqueue_task_fair(), curr is false.
on_rq is false too. But the tasks weight is changed and vprot never gets touched so it got wrong. Then on set_next_task_fair(),
the task is curr again.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] sched/eevdf: Fix vprot across reweighting
  2026-10-12 15:01       ` Kayra Cizmeci
@ 2026-10-12 19:00         ` Kayra Cizmeci
  0 siblings, 0 replies; 9+ messages in thread
From: Kayra Cizmeci @ 2026-10-12 19:00 UTC (permalink / raw)
  To: kayracizmeci, Ingo Molnar, Peter Zijlstra, Juri Lelli,
	Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall,
	Mel Gorman, Valentin Schneider, K Prateek Nayak
  Cc: christian.loehle, elif.topuz, linux-kernel, mingo, sh

> I send one mail, one more to reply comes. Ah.. I love it tho :-)

> > Before 819224e506bc ("sched/fair: Remove dead code on
> > enqueue_task_fair()"), the reweight_eevdf() was not called for curr so
> > the false was always true. If we can finally have enqueue curr then we
> > should skip this case

> Yeah. The beast I created kills me. Pretty nice.

> On sched_change_begin(), cfs_rq->curr is set to NULL. So while entering enqueue_task_fair(), curr is false.
> on_rq is false too. But the tasks weight is changed and vprot never gets touched so it got wrong. Then on set_next_task_fair(),
> the task is curr again.

Would something like this works?

This diff was coded in the middle of the night, so there might be some little issues about it.
Not even 1% tested. But it should 100% work since I'm too smart, right? Right? :-)

(Also, I'll test it tomorrow. Normally I was going to test this, but I lost my test script. And tbh
I'm too tired to make it right now. I mean normally I wouldn't test it, since I'm too smart and this
is 100% correct. And because of this 'dead' code removal patch, there could be some extra handy issues.
Ah... I wanna swear so bad. But, I'll be a good and kind. Goodnight, good morning, good afternoon and good-whatever.)


diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index b42a0ca2a69e..1bea7b7e9cb3 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4731,7 +4731,7 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
 		se->vlag = entity_lag(cfs_rq, se, avruntime);
 		se->deadline -= avruntime;
 		se->rel_deadline = 1;
-		if (curr && protect_slice(se)) {
+		if (curr) {
 			se->vprot -= avruntime;
 			rel_vprot = true;
 		}
@@ -7990,7 +7990,9 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
 	int task_new = !(flags & ENQUEUE_WAKEUP);
 	struct sched_entity *se = &p->se;
 	struct cfs_rq *cfs_rq = &rq->cfs;
-	unsigned long weight;
+	unsigned long weight, old_weight;
+	bool live;
+	u64 dist;
 
 	if (task_is_throttled(p) && enqueue_throttled_task(p))
 		return;
@@ -8024,8 +8026,23 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
 		requeue_delayed_entity(cfs_rq, se);
 
 	weight = enqueue_hierarchy(p, flags);
+	live = protect_slice(se);
+
+	if (live) {
+		old_weight = se->h_load.weight;
+		dist = se->vprot - se->vruntime;
+	}
 	reweight_eevdf(cfs_rq, se, weight, false);
 	place_entity(cfs_rq, se, flags | ENQUEUE_QUEUED);
+	if (!live)
+		cancel_protect_slice(se);
+	else {
+		if (weight != old_weight)
+			dist = div64_long(dist * old_weight, weight);
+
+		se->vprot = se->vruntime + dist;
+	}
+
 	__enqueue_entity(cfs_rq, se);
 
 	if (!rq_h_nr_queued && rq->cfs.h_nr_queued)

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-10-12 19:00 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-03 11:46 [PATCH] sched/eevdf: Fix vprot across reweighting Kayra Cizmeci
2026-10-11  7:13 ` Christian Loehle
2026-10-11 10:06   ` Kayra Cizmeci
2026-10-12  4:39 ` K Prateek Nayak
2026-10-12 13:40 ` Vincent Guittot
2026-10-12 13:59   ` Kayra Cizmeci
2026-10-12 14:14     ` Vincent Guittot
2026-10-12 15:01       ` Kayra Cizmeci
2026-10-12 19:00         ` Kayra Cizmeci

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®