[PATCH v2 1/5] sched/fair: Take slice protection into account when arming HRTICK
From: Christian Loehle
Date: Thu Oct 01 2026 - 09:48:13 EST
EEVDF can end a task's slice protection before its virtual deadline when
shorter requests compete on the runqueue. update_curr() requests a new
selection once protection expires, but hrtick_start_fair() still arms the
timer for the virtual deadline. Without an intervening scheduling event,
the next opportunity to reconsider the task can therefore arrive much
later than the protection boundary.
Arm the fair hrtick for the earlier of the virtual deadline and live
slice protection. Keep the deadline fallback once protection expires.
With RUN_TO_PARITY disabled, vprot remains the minimum progress quantum,
so the timer must reconsider current at that boundary too. A same-task
repick restarts the timer without renewing protection, so newly eligible
tasks can compete without waiting for another protected quantum.
A wakeup can shorten protection without preempting current. The enqueue
path calls hrtick_update() before wakeup_preempt_fair() updates protection,
and hrtick_update() leaves an active timer alone. Recompute the fair
hrtick after update_protect_slice() changes vprot, including when a timer
is already active. If the new protection boundary has already passed,
request lazy rescheduling, as update_curr() does on protection expiry,
instead of falling back to the later deadline.
Fixes: 74eec63661d4 ("sched/fair: Fix NO_RUN_TO_PARITY case")
Reported-by: Vincent Guittot <vincent.guittot@xxxxxxxxxx>
Link: https://lore.kernel.org/r/CAKfTPtD_aJeAh1biW6gKCLK6BnYcNtbz-FJvxUzZ1tD3V=43mw@xxxxxxxxxxxxxx/
Link: https://lore.kernel.org/r/CAKfTPtApFGcYA22Qtg3OyYEt6EJw_FW9_VV=_vgE_HtNY3V9og@xxxxxxxxxxxxxx/
Signed-off-by: Christian Loehle <christian.loehle@xxxxxxx>
---
kernel/sched/fair.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index a39c48704d40..85bf02570473 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -8018,9 +8018,13 @@ static void hrtick_start_fair(struct rq *rq, struct task_struct *p)
return;
/*
- * Compute time until virtual deadline
+ * Reconsider the pick when live slice protection expires, which can be
+ * earlier than the virtual deadline when shorter requests compete.
+ * Without live protection, use the virtual deadline instead.
*/
vdelta = se->deadline - se->vruntime;
+ if (protect_slice(se))
+ vdelta = min_vruntime(se->deadline, se->vprot) - se->vruntime;
if ((s64)vdelta < 0) {
if (task_current_donor(rq, p))
resched_curr(rq);
@@ -10261,8 +10265,18 @@ static void wakeup_preempt_fair(struct rq *rq, struct task_struct *p, int wake_f
if (preempt_action == PREEMPT_WAKEUP_SHORT && entity_eligible(cfs_rq, pse))
goto preempt;
update:
- if (sched_feat(RUN_TO_PARITY))
+ if (sched_feat(RUN_TO_PARITY)) {
+ u64 old_vprot = se->vprot;
+
update_protect_slice(cfs_rq, se);
+ if (hrtick_enabled_fair(rq) && se->vprot != old_vprot) {
+ /* The enqueue may have armed the timer before this update. */
+ if (protect_slice(se))
+ hrtick_start_fair(rq, donor);
+ else
+ resched_curr_lazy(rq);
+ }
+ }
return;
--
2.34.1