7.3-stable review patch. If anyone has any objections, please let me know. ------------------ From: Peng Wang [ Upstream commit e389ae428847a2e6a3b698b5967df68ccf90361c ] The nohz full kick relies on interrupt exit to reevaluate the tick. However, a remote kick can also be flushed from task context without an interrupt exit guaranteed to follow. If a tick dependency is set or an earlier timer is queued after the idle-exit reevaluation, the required tick update can be delayed until another interrupt. Reevaluate the tick directly from the callback outside hardirq context. Keep the existing interrupt exit handling for hardirq callbacks. The offline flush remains harmless because tick_sched_timer_dying() has already cleared TS_FLAG_NOHZ. Fixes: 4b44a21dd640 ("irq_work, smp: Allow irq_work on call_single_queue") Fixes: a5183862e76f ("tick/nohz: Conditionally restart tick on idle exit") Suggested-by: Frederic Weisbecker Co-developed-by: He Rongguang Signed-off-by: He Rongguang Signed-off-by: Peng Wang Signed-off-by: Thomas Gleixner Reviewed-by: Frederic Weisbecker Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20261023145101.8217-1-peng_wang@linux.alibaba.com Signed-off-by: Sasha Levin --- kernel/time/tick-sched.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 6c3fea3867139..baa3ac9b48f88 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -400,9 +400,21 @@ static bool can_stop_full_tick(int cpu, struct tick_sched *ts) return true; } +static void tick_nohz_full_update_tick(struct tick_sched *ts); + static void nohz_full_kick_func(struct irq_work *work) { - /* Empty, the tick restart happens on tick_nohz_irq_exit() */ + struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched); + + if (WARN_ON_ONCE(!tick_nohz_full_cpu(smp_processor_id()))) + return; + + /* Task-context flushes may not be followed by an IRQ exit. */ + if (!in_hardirq()) { + if (WARN_ON_ONCE(tick_sched_flag_test(ts, TS_FLAG_INIDLE))) + return; + tick_nohz_full_update_tick(ts); + } } static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = -- 2.53.0