Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

tick/sched: Fix bogus condition in report_idle_softirq()

In commit 0345691b24c0 ("tick/rcu: Stop allowing RCU_SOFTIRQ in idle") the
new function report_idle_softirq() was created by breaking code out of the
existing can_stop_idle_tick() for kernels v5.18 and newer.

In doing so, the code essentially went from this form:

if (A) {
static int ratelimit;
if (ratelimit < 10 && !C && A&D) {
pr_warn("NOHZ tick-stop error: ...");
ratelimit++;
}
return false;
}

to a new function:

static bool report_idle_softirq(void)
{
static int ratelimit;

if (likely(!A))
return false;

if (ratelimit < 10)
return false;
...
pr_warn("NOHZ tick-stop error: local softirq work is pending, handler #%02x!!!\n",
pending);
ratelimit++;

return true;
}

commit a7e282c77785 ("tick/rcu: Fix bogus ratelimit condition") realized
ratelimit was essentially set to zero instead of ten, and hence *no*
softirq pending messages would ever be issued, but "fixed" it as:

- if (ratelimit < 10)
+ if (ratelimit >= 10)
return false;

However, this fix introduced another issue:

When ratelimit is greater than or equal 10, even if A is true, it will
directly return false. While ratelimit in the original code was only used
to control printing and will not affect the return value.

Restore the original logic and restrict ratelimit to control the printk and
not the return value.

Fixes: 0345691b24c0 ("tick/rcu: Stop allowing RCU_SOFTIRQ in idle")
Fixes: a7e282c77785 ("tick/rcu: Fix bogus ratelimit condition")
Signed-off-by: Wen Yang <wen.yang@linux.dev>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://patch.msgid.link/20251119174525.29470-1-wen.yang@linux.dev

authored by

Wen Yang and committed by
Thomas Gleixner
807e0d18 6a23ae0a

+5 -6
+5 -6
kernel/time/tick-sched.c
··· 1152 1152 return false; 1153 1153 } 1154 1154 1155 - if (ratelimit >= 10) 1156 - return false; 1157 - 1158 1155 /* On RT, softirq handling may be waiting on some lock */ 1159 1156 if (local_bh_blocked()) 1160 1157 return false; 1161 1158 1162 - pr_warn("NOHZ tick-stop error: local softirq work is pending, handler #%02x!!!\n", 1163 - pending); 1164 - ratelimit++; 1159 + if (ratelimit < 10) { 1160 + pr_warn("NOHZ tick-stop error: local softirq work is pending, handler #%02x!!!\n", 1161 + pending); 1162 + ratelimit++; 1163 + } 1165 1164 1166 1165 return true; 1167 1166 }