From: Rosen Penev <rosenp@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: Thomas Gleixner <tglx@kernel.org>, Radu Rendec <radu@rendec.net>,
Dmitry Ilvokhin <d@ilvokhin.com>,
Waiman Long <longman@redhat.com>,
Davidlohr Bueso <dbueso@suse.de>, Marc Zyngier <maz@kernel.org>
Subject: [PATCH] genirq: Ignore tot_count for handle_percpu_irq() interrupts
Date: Thu, 5 Nov 2026 21:19:59 -0800 [thread overview]
Message-ID: <20261106051959.901861-1-rosenp@gmail.com> (raw)
handle_percpu_irq() only increments the per CPU statistics and leaves
desc::tot_count untouched, but nothing marks the descriptors that use it
as per CPU. Both /proc/interrupts and kstat_irqs_desc() treat such an
interrupt as a device interrupt and trust desc::tot_count, which stays
zero.
Since /proc/interrupts started to emit zeros for device interrupts with
a zero desc::tot_count, every MIPS CPU interrupt reads as zero there,
including the timer and every device behind it. /proc/interrupts also
missed NMIs handled by handle_fasteoi_nmi(), which kstat_irqs_desc()
already excluded. The /proc/stat counts of handle_percpu_irq() users
have been zero since kstat_irqs_desc() started to use desc::tot_count.
Add irq_desc_has_tot_count(), which covers per CPU interrupts, NMIs and
handle_percpu_irq() users, and use it in both places.
Seen on ASUS RT-N16 and TP-LINK Archer C7 v2 (both MIPS 74K) router, where
the "gpio, ttyS0" lines stayed at zero while the GPIO interrupts chained
behind it counted.
Fixes: 0179464391af ("genirq/proc: Utilize irq_desc::tot_count to avoid evaluation")
Fixes: 1136b0728969 ("genirq: Avoid summation loops for /proc/stat")
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
kernel/irq/internals.h | 12 ++++++++++++
kernel/irq/irqdesc.c | 4 +---
kernel/irq/proc.c | 7 +++----
3 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 703a062be878..70dd3a010ce8 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -302,6 +302,18 @@ static inline bool irq_is_nmi(struct irq_desc *desc)
return desc->istate & IRQS_NMI;
}
+/*
+ * Per CPU interrupts, NMIs and interrupts handled by handle_percpu_irq()
+ * only update the per CPU statistics and leave desc::tot_count alone.
+ */
+static inline bool irq_desc_has_tot_count(struct irq_desc *desc)
+{
+ return !irq_settings_is_per_cpu_devid(desc) &&
+ !irq_settings_is_per_cpu(desc) &&
+ !irq_is_nmi(desc) &&
+ desc->handle_irq != handle_percpu_irq;
+}
+
#ifdef CONFIG_PM_SLEEP
void irq_pm_handle_wakeup(struct irq_desc *desc);
void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action);
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 7cbcc3fb9e6d..3f7bfe0adfd7 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -1020,9 +1020,7 @@ static unsigned int kstat_irqs_desc(struct irq_desc *desc, const struct cpumask
unsigned int sum = 0;
int cpu;
- if (!irq_settings_is_per_cpu_devid(desc) &&
- !irq_settings_is_per_cpu(desc) &&
- !irq_is_nmi(desc))
+ if (irq_desc_has_tot_count(desc))
return data_race(desc->tot_count);
for_each_cpu(cpu, cpumask)
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 0c0df16de581..c985515f5030 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -559,11 +559,10 @@ static int irq_seq_show(struct seq_file *p, void *v)
seq_putc(p, ':');
/*
- * Always output per CPU interrupts. Output device interrupts only when
- * desc::tot_count is not zero.
+ * Always output interrupts which do not maintain desc::tot_count.
+ * Output the others only when desc::tot_count is not zero.
*/
- if (irq_settings_is_per_cpu(desc) || irq_settings_is_per_cpu_devid(desc) ||
- data_race(desc->tot_count))
+ if (!irq_desc_has_tot_count(desc) || data_race(desc->tot_count))
irq_proc_emit_counts(p, &desc->kstat_irqs->cnt);
else
irq_proc_emit_zero_counts(p, num_online_cpus());
--
2.56.0
reply other threads:[~2026-11-06 5:20 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261106051959.901861-1-rosenp@gmail.com \
--to=rosenp@gmail.com \
--cc=d@ilvokhin.com \
--cc=dbueso@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=longman@redhat.com \
--cc=maz@kernel.org \
--cc=radu@rendec.net \
--cc=tglx@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®