* [PATCH] genirq: Ignore tot_count for handle_percpu_irq() interrupts
@ 2026-11-06 5:19 Rosen Penev
0 siblings, 0 replies; only message in thread
From: Rosen Penev @ 2026-11-06 5:19 UTC (permalink / raw)
To: linux-kernel
Cc: Thomas Gleixner, Radu Rendec, Dmitry Ilvokhin, Waiman Long,
Davidlohr Bueso, Marc Zyngier
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
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-11-06 5:20 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-06 5:19 [PATCH] genirq: Ignore tot_count for handle_percpu_irq() interrupts Rosen Penev
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®