mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-29 12:47:47 -04:00
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
117 lines
2.9 KiB
C
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 */
|