]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/irq: Move IOAPIC misrouted and PIC/APIC error counts into irq_stats
authorThomas Gleixner <tglx@kernel.org>
Sun, 17 May 2026 20:01:59 +0000 (22:01 +0200)
committerThomas Gleixner <tglx@kernel.org>
Tue, 26 May 2026 14:21:12 +0000 (16:21 +0200)
The special treatment of these counts is just adding extra code for no real
value. The irq_stats mechanism allows to suppress output of counters, which
should never happen by default and provides a mechanism to enable them for
the rare case that they occur.

Move the IOAPIC misrouted and the PIC/APIC error counts into irq_stats,
mark them suppressed by default and update the sites which increment them.

This changes the output format of 'ERR' and 'MIS' in case there are events
to the regular per CPU display format and otherwise suppresses them
completely.

As a side effect this removes the arch_cpu_stat() mechanism from proc/stat
which was only there to account for the error interrupts on x86 and missed
to take the misrouted ones into account.

Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Tested-by: Michael Kelley <mhklinux@outlook.com>
Reviewed-by: Radu Rendec <radu@rendec.net>
Link: https://patch.msgid.link/20260517194931.361942103@kernel.org
arch/x86/include/asm/hardirq.h
arch/x86/include/asm/hw_irq.h
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/i8259.c
arch/x86/kernel/irq.c
fs/proc/stat.c

index 6723b512c6944739c12ca6649916572af300b770..dea60d66d97699df79108fbf18f9388f23c65768 100644 (file)
@@ -49,6 +49,10 @@ enum irq_stat_counts {
 #endif
 #ifdef CONFIG_X86_POSTED_MSI
        IRQ_COUNT_POSTED_MSI_NOTIFICATION,
+#endif
+       IRQ_COUNT_PIC_APIC_ERROR,
+#ifdef CONFIG_X86_IO_APIC
+       IRQ_COUNT_IOAPIC_MISROUTED,
 #endif
        IRQ_COUNT_MAX,
 };
@@ -81,9 +85,6 @@ extern void ack_bad_irq(unsigned int irq);
 #ifdef CONFIG_PROC_FS
 extern u64 arch_irq_stat_cpu(unsigned int cpu);
 #define arch_irq_stat_cpu      arch_irq_stat_cpu
-
-extern u64 arch_irq_stat(void);
-#define arch_irq_stat          arch_irq_stat
 #endif
 
 DECLARE_PER_CPU_CACHE_HOT(u16, __softirq_pending);
index cbe19e6690801ad5e4eff088bb041631fdec1250..47727d0b540b9752614e797a92ea9a403328ded5 100644 (file)
@@ -110,10 +110,6 @@ static inline void lock_vector_lock(void) {}
 static inline void unlock_vector_lock(void) {}
 #endif
 
-/* Statistics */
-extern atomic_t irq_err_count;
-extern atomic_t irq_mis_count;
-
 extern void elcr_set_level_irq(unsigned int irq);
 
 extern char irq_entries_start[];
index e27c263d6c13b5227a2700834bef214e558ecd79..3eeebc2c5a1d878288d89805f8f29d31e01fcb83 100644 (file)
@@ -2186,7 +2186,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_error_interrupt)
                apic_write(APIC_ESR, 0);
        v = apic_read(APIC_ESR);
        apic_eoi();
-       atomic_inc(&irq_err_count);
+       irq_stat_inc_and_enable(IRQ_COUNT_PIC_APIC_ERROR);
 
        apic_pr_debug("APIC error on CPU%d: %02x", smp_processor_id(), v);
 
index 352ed5558cbc0b11c42c0ccc863be867728938ab..7d7175d01228884f669f7cf3d2890a7eea817695 100644 (file)
@@ -1575,8 +1575,6 @@ static unsigned int startup_ioapic_irq(struct irq_data *data)
        return was_pending;
 }
 
-atomic_t irq_mis_count;
-
 #ifdef CONFIG_GENERIC_PENDING_IRQ
 static bool io_apic_level_ack_pending(struct mp_chip_data *data)
 {
@@ -1713,7 +1711,7 @@ static void ioapic_ack_level(struct irq_data *irq_data)
         * at the cpu.
         */
        if (!(v & (1 << (i & 0x1f)))) {
-               atomic_inc(&irq_mis_count);
+               irq_stat_inc_and_enable(IRQ_COUNT_IOAPIC_MISROUTED);
                eoi_ioapic_pin(cfg->vector, irq_data->chip_data);
        }
 
index f67063df67235e7c7024c993634c807e45d10994..f7a86b94a0dd53588bd27d3ad921b2e76cf0ffe8 100644 (file)
@@ -214,7 +214,7 @@ spurious_8259A_irq:
                               "spurious 8259A interrupt: IRQ%d.\n", irq);
                        spurious_irq_mask |= irqmask;
                }
-               atomic_inc(&irq_err_count);
+               irq_stat_inc_and_enable(IRQ_COUNT_PIC_APIC_ERROR);
                /*
                 * Theoretically we do not have to handle this IRQ,
                 * but in Linux this does not cause problems and is
index 2d8ca411661086a36cea2127ff0ae06b157d440c..9d98c81fcd24a5302813c7ba4499a7442819ca84 100644 (file)
@@ -39,8 +39,6 @@ EXPORT_PER_CPU_SYMBOL(__softirq_pending);
 
 DEFINE_PER_CPU_CACHE_HOT(struct irq_stack *, hardirq_stack_ptr);
 
-atomic_t irq_err_count;
-
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
  * each architecture has to answer this themselves.
@@ -123,6 +121,10 @@ static const struct irq_stat_info irq_stat_info[IRQ_COUNT_MAX] = {
 #endif
 #ifdef CONFIG_X86_POSTED_MSI
        ISS(POSTED_MSI_NOTIFICATION,    "PMN",  "  Posted MSI notification event\n"),
+#endif
+       IDS(PIC_APIC_ERROR,             "ERR",  "  PIC/APIC error interrupts\n"),
+#ifdef CONFIG_X86_IO_APIC
+       IDS(IOAPIC_MISROUTED,           "MIS",  "  Misrouted IO/APIC interrupts\n"),
 #endif
 };
 
@@ -183,10 +185,6 @@ int arch_show_interrupts(struct seq_file *p, int prec)
                irq_proc_emit_counts(p, &irq_stat.counts[i]);
                seq_puts(p, info->text);
        }
-
-       seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
-       if (IS_ENABLED(CONFIG_X86_IO_APIC))
-               seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count));
        return 0;
 }
 
@@ -202,12 +200,6 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
                sum += p->counts[i];
        return sum;
 }
-
-u64 arch_irq_stat(void)
-{
-       u64 sum = atomic_read(&irq_err_count);
-       return sum;
-}
 #endif /* CONFIG_PROC_FS */
 
 static __always_inline void handle_irq(struct irq_desc *desc,
index 8b444e862319caf585a395b04e162ec049dd5750..20c3df9a9b800316c88bd8b88750377d71b3e759 100644 (file)
@@ -18,9 +18,6 @@
 #ifndef arch_irq_stat_cpu
 #define arch_irq_stat_cpu(cpu) 0
 #endif
-#ifndef arch_irq_stat
-#define arch_irq_stat() 0
-#endif
 
 u64 get_idle_time(struct kernel_cpustat *kcs, int cpu)
 {
@@ -122,7 +119,6 @@ static int show_stat(struct seq_file *p, void *v)
                        sum_softirq += softirq_stat;
                }
        }
-       sum += arch_irq_stat();
 
        seq_put_decimal_ull(p, "cpu  ", nsec_to_clock_t(user));
        seq_put_decimal_ull(p, " ", nsec_to_clock_t(nice));