[PATCH] sched/psi: Preserve PSI state on delayed dequeue

From: Shubhang Kaushik (Ampere)

Date: Tue Nov 03 2026 - 02:05:16 EST


EEVDF can retain a blocked fair task as sched_delayed until it becomes
eligible for final removal.

On the initial sleep, psi_dequeue() does nothing because the task is
still TSK_ONCPU. psi_sched_switch(..., sleep=true) then converts the
task from runnable to sleeping, retaining TSK_IOWAIT and persistent
memory-stall state.

A delayed task can later be physically removed while still asleep via:

wait_task_inactive()
-> dequeue_task(DEQUEUE_SLEEP | DEQUEUE_DELAYED)

or:

switching_from_fair()
-> dequeue_task(DEQUEUE_SLEEP | DEQUEUE_DELAYED | DEQUEUE_NOCLOCK)

psi_dequeue() currently clears all PSI flags, including TSK_IOWAIT,
even though the task remains asleep. This prematurely ends its
sleep-pressure accounting. On wakeup, psi_enqueue() expects to clear
the retained TSK_IOWAIT state.

DEQUEUE_DELAYED only completes the previously accounted sleep dequeue.
Keep PSI state unchanged for it, as for DEQUEUE_SAVE.

Fixes: f5aaff7bfa11 ("sched/core: Dequeue PSI signals for blocked tasks that are delayed")
Fixes: b7ca5743a260 ("sched/core: Tweak wait_task_inactive() to force dequeue sched_delayed tasks")
Signed-off-by: Shubhang Kaushik (Ampere) <sh@xxxxxxxxxx>
---
Testing on 80-core Ampere Altra:
- On v7.4-rc1 baseline, switching a delayed direct-I/O task from
SCHED_OTHER to SCHED_FIFO triggered: "psi: inconsistent task state"
- With this patch applied, the identical test emitted no PSI warning.
---
kernel/sched/stats.h | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h
index ebe0a7765f98e733af9f576033a0f8da65757f08..3e3f5cf4524d281816b01ba8165905fd1cbefc87 100644
--- a/kernel/sched/stats.h
+++ b/kernel/sched/stats.h
@@ -164,8 +164,13 @@ static inline void psi_dequeue(struct task_struct *p, int flags)
if (static_branch_likely(&psi_disabled))
return;

- /* Same runqueue, nothing changed for psi */
- if (flags & DEQUEUE_SAVE)
+ /*
+ * Saved dequeues retain task state across a dequeue/enqueue pair. A
+ * delayed dequeue completes a prior sleep dequeue after
+ * psi_sched_switch() accounted the runnable-to-sleeping transition.
+ * In both cases, keep the task's PSI state unchanged.
+ */
+ if (flags & (DEQUEUE_SAVE | DEQUEUE_DELAYED))
return;

/*

---
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20261102-psi-delayed-deq-9535d7ffd138

Best regards,
--
Shubhang Kaushik (Ampere) <sh@xxxxxxxxxx>