[PATCH 1/2] sched/eevdf: Cap protection when current has the shortest slice

From: Christian Loehle

Date: Wed Sep 30 2026 - 04:48:29 EST


Changing a task's slice does not discard its remaining request. With
PLACE_REL_DEADLINE, the preserved deadline can therefore extend beyond
the new slice after sched_setattr() reduces it.

set_protect_slice() starts from that deadline and only applies the slice
cap when another entity has a shorter slice. If current itself has the
shortest slice, a later pick can protect it for the remainder of the old
request. update_curr() then need not request another selection when a
competitor becomes eligible.

For a preserved deadline d beyond the new virtual slice vslice:

v v + vslice d
|---------------------|----------------------|
old: |<---------------- protection -------------->|
new: |<---- protection --->|

Commit aae2a33ea662 ("sched/eevdf: Ensure that vprot will never go above a
min slice") caps protection even when the ineligibility boundary is later,
but leaves this slice == se->slice case uncovered.

Apply the minimum-slice cap unconditionally, including when it is
current's own slice. Keep the earlier ineligibility boundary for the
PREEMPT_SHORT case when a shorter slice is competing. This preserves the
outstanding request while limiting protection at each fresh pick.

Fixes: 82e9d0456e06 ("sched/fair: Avoid re-setting virtual deadline on 'migrations'")
Signed-off-by: Christian Loehle <christian.loehle@xxxxxxx>
---
kernel/sched/fair.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 85bf02570473..868c3911337a 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1128,13 +1128,12 @@ static inline void set_protect_slice(struct cfs_rq *cfs_rq, struct sched_entity
slice = cfs_rq_min_slice(cfs_rq);

slice = min(slice, se->slice);
+ /* A preserved deadline can extend beyond the current slice. */
+ vprot = min_vruntime(vprot, se->vruntime + calc_delta_fair(slice, se));

/* If there are shorter slices than se's one */
- if (slice != se->slice) {
- vprot = min_vruntime(vprot, se->vruntime + calc_delta_fair(slice, se));
- if (sched_feat(PREEMPT_SHORT))
- vprot = min_vruntime(vprot, ineligible_vruntime(cfs_rq));
- }
+ if (sched_feat(PREEMPT_SHORT) && slice != se->slice)
+ vprot = min_vruntime(vprot, ineligible_vruntime(cfs_rq));

se->vprot = vprot;
}