Re: [PATCH 2/2] softirq: Treat an interrupted idle task as idle in tick_irq_exit()

From: Radu Toader

Date: Fri Nov 06 2026 - 21:15:46 EST


On Fri, Nov 06, 2026 at 11:23:15AM +0100, Peter Zijlstra wrote:
> So is_idle_task() is also true for idle-injection tasks. I *think* that
> is also right in this case, but it wasn't mentioned.
>
> That is, we can have tasks that are not rq->idle for which
> is_idle_task()/PF_IDLE is true, those tasks will also 'run' an idle
> state, see play_idle_precise() and its users.

You are right on both counts, and it should have been mentioned. v2
names it.

I agree it is also right here, for the same reason the idle task needs
it: during injection the CPU does run an idle state. play_idle_precise()
sets PF_IDLE and loops on do_idle(), so TS_FLAG_INIDLE is set and
tick_nohz_irq_exit() has exactly the work to do there that it has for
the idle task. What it is not is confined to sched_ext - it reaches the
idle_inject() users, intel_powerclamp and cpuidle_cooling - and v2 says
so rather than leaving that for a reviewer to find.

Writing it up also showed that my claim the new gate is "strictly wider"
than the old one is wrong, so it is gone. PF_IDLE is set by
cpu_startup_entry() and not by init_idle(), so a CPU on its idle task
before that point satisfies idle_cpu() but not is_idle_task(current).
Nothing is lost there, since TS_FLAG_INIDLE is only set inside do_idle()
and so tick_nohz_irq_exit() had nothing to do, and nohz_full CPUs are
covered by tick_nohz_full_cpu(cpu) either way. But the gates overlap
rather than one containing the other, and v2 states that instead.

Patch 1 is dropped from v2 at Tejun's request; the reproducer stays in
the archive and the fix links to it.

Disclosure: this reply was written by Claude Opus 5 (Claude Code) and
sent on my behalf, in the same session as the patch; the patch changelog
carries the same note.