Files
linux/arch/x86/include/asm/hardirq.h
Thomas Gleixner d6b70b16b4 x86/irq: Move IOAPIC misrouted and PIC/APIC error counts into irq_stats
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
2026-05-26 16:21:12 +02:00

117 lines
2.9 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_X86_HARDIRQ_H
#define _ASM_X86_HARDIRQ_H
#include <linux/threads.h>
enum irq_stat_counts {
IRQ_COUNT_NMI,
#ifdef CONFIG_X86_LOCAL_APIC
IRQ_COUNT_APIC_TIMER,
IRQ_COUNT_SPURIOUS,
IRQ_COUNT_APIC_PERF,
IRQ_COUNT_IRQ_WORK,
IRQ_COUNT_ICR_READ_RETRY,
IRQ_COUNT_X86_PLATFORM_IPI,
#endif
#ifdef CONFIG_SMP
IRQ_COUNT_RESCHEDULE,
IRQ_COUNT_CALL_FUNCTION,
#endif
IRQ_COUNT_TLB,
#ifdef CONFIG_X86_THERMAL_VECTOR
IRQ_COUNT_THERMAL_APIC,
#endif
#ifdef CONFIG_X86_MCE_THRESHOLD
IRQ_COUNT_THRESHOLD_APIC,
#endif
#ifdef CONFIG_X86_MCE_AMD
IRQ_COUNT_DEFERRED_ERROR,
#endif
#ifdef CONFIG_X86_MCE
IRQ_COUNT_MCE_EXCEPTION,
IRQ_COUNT_MCE_POLL,
#endif
#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
IRQ_COUNT_HYPERVISOR_CALLBACK,
#endif
#if IS_ENABLED(CONFIG_HYPERV)
IRQ_COUNT_HYPERV_REENLIGHTENMENT,
IRQ_COUNT_HYPERV_STIMER0,
#endif
#if IS_ENABLED(CONFIG_KVM)
IRQ_COUNT_POSTED_INTR,
IRQ_COUNT_POSTED_INTR_NESTED,
IRQ_COUNT_POSTED_INTR_WAKEUP,
#endif
#ifdef CONFIG_GUEST_PERF_EVENTS
IRQ_COUNT_PERF_GUEST_MEDIATED_PMI,
#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,
};
typedef struct {
#if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL)
u8 kvm_cpu_l1tf_flush_l1d;
#endif
unsigned int counts[IRQ_COUNT_MAX];
} ____cacheline_aligned irq_cpustat_t;
DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
#ifdef CONFIG_X86_POSTED_MSI
DECLARE_PER_CPU_ALIGNED(struct pi_desc, posted_msi_pi_desc);
#endif
#define __ARCH_IRQ_STAT
#define inc_irq_stat(index) this_cpu_inc(irq_stat.counts[IRQ_COUNT_##index])
void irq_stat_inc_and_enable(enum irq_stat_counts which);
#ifdef CONFIG_X86_LOCAL_APIC
#define inc_perf_irq_stat() inc_irq_stat(APIC_PERF)
#else
#define inc_perf_irq_stat() do { } while (0)
#endif
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
#endif
DECLARE_PER_CPU_CACHE_HOT(u16, __softirq_pending);
#define local_softirq_pending_ref __softirq_pending
#if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL)
/*
* This function is called from noinstr interrupt contexts
* and must be inlined to not get instrumentation.
*/
static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void)
{
__this_cpu_write(irq_stat.kvm_cpu_l1tf_flush_l1d, 1);
}
static __always_inline void kvm_clear_cpu_l1tf_flush_l1d(void)
{
__this_cpu_write(irq_stat.kvm_cpu_l1tf_flush_l1d, 0);
}
static __always_inline bool kvm_get_cpu_l1tf_flush_l1d(void)
{
return __this_cpu_read(irq_stat.kvm_cpu_l1tf_flush_l1d);
}
#else /* !IS_ENABLED(CONFIG_KVM_INTEL) */
static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { }
#endif /* IS_ENABLED(CONFIG_KVM_INTEL) */
#endif /* _ASM_X86_HARDIRQ_H */