From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.mindbit.ro (xs1.mindbit.ro [80.86.107.70]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 21EC831AAA8 for ; Sat, 28 Mar 2026 17:04:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.86.107.70 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774717478; cv=none; b=BmernU6MdVfmnATkjBvi5zw0yb5/smJAiaTqRMiPdI7HZmFGrWIWTZqviWbqlNCW3XmsLwcezXuEExfTNfLFVCAFSxp+b/SUevLrU8bBhK8Lw/tVMrQOPqTE9WnrwOItodO/Ln+mfgXoyuN3PVK4mQ5LlxZY7Oou4l42jKIY0qs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774717478; c=relaxed/simple; bh=reCbc3TLC6lwjrDp6ZGcy4N+wKI4ilngNf0bo9MMVXM=; h=Message-ID:Subject:From:To:Cc:Date:In-Reply-To:References: Content-Type:MIME-Version; b=cW9pY7WnGHVkdcpVgwlq+W3PYJ0WP2OyLUuwr/4MyLkFOKImecXZmqvokzJ4nz8IMoMD2M7bWJG9EELyRBaKWjthvUvpq6HNmt9jFQsBANTVIUVWZU30gChApa6weEjdOKEAEsZm61IC4kBZSkWbwf4x0pHoaW4yj84fEYTjWuU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=rendec.net; spf=pass smtp.mailfrom=rendec.net; dkim=pass (2048-bit key) header.d=rendec.net header.i=@rendec.net header.b=IeBa9F7T; arc=none smtp.client-ip=80.86.107.70 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=rendec.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rendec.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rendec.net header.i=@rendec.net header.b="IeBa9F7T" Received: from dog.kanata.rendec.net (pool-174-112-193-187.cpe.net.cable.rogers.com [174.112.193.187]) by mail.mindbit.ro (Postfix) with ESMTPSA id 37802C24D0; Sat, 28 Mar 2026 19:04:31 +0200 (EET) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.mindbit.ro 37802C24D0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rendec.net; s=default; t=1774717472; bh=zSv5B264FLXKQ23qHXOxzd+MyWnNwzcO6wf2DKM1HkQ=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=IeBa9F7ToI7XQnOTT3/cavMWsxmBsMkxbks+qezSju3W0t71DwEauvN331WCvr4qi ExbPlKhz+hMcfSkDa2z2eoXthBtPzcPa8M6TXzGU5pbxkJrAvmACR8OSLsd/9q89wU H4oAzhbHHUQbm4OO3eP3THJj9HDQGrC4HWFR9pR6SOA3wMUXxWGLs3Gk/Ny+J+3LjC sn3uC/QXk68KmYJMMZ+ONYJ/NcEnvh0Vs6XXxQPRDUroNQ4IOb8Bx6w9IWckMqOK/t 8FlF3T8MTt8AAa/Lwd+0MS3VkXYEDWMjgTHVmO3TIpBNikaevKSGcGpCwP0eVJVFAM yKiNYAUizdokw== Message-ID: Subject: Re: [patch V3 04/14] x86/irq: Make irqstats array based From: Radu Rendec To: Thomas Gleixner , LKML Cc: x86@kernel.org, Michael Kelley , Dmitry Ilvokhin , Jan Kiszka , Kieran Bingham , Florian Fainelli Date: Sat, 28 Mar 2026 13:04:29 -0400 In-Reply-To: <20260326215036.510699542@kernel.org> References: <20260326214345.019130211@kernel.org> <20260326215036.510699542@kernel.org> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.56.2 (3.56.2-2.fc42) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 On Thu, 2026-03-26 at 22:56 +0100, Thomas Gleixner wrote: > Having the x86 specific interrupt statistics as a data structure with > individual members instead of an array is just stupid as it requires > endless copy and paste in arch_show_interrupts() and arch_irq_stat_cpu(), > where the latter does not even take the latest interrupt additions into > account. The resulting #ifdef orgy is just disgusting. >=20 > Convert it to an array of counters, which does not make a difference in t= he > actual interrupt hotpath increment as the array index is constant and > therefore not any different than the member based access. >=20 > But in arch_show_interrupts() and arch_irq_stat_cpu() this just turns int= o > a loop, which reduces the text size by ~2k (~12%): >=20 > =C2=A0=C2=A0 text =C2=A0=C2=A0 data =C2=A0=C2=A0=C2=A0 bss =C2=A0=C2=A0= =C2=A0 dec =C2=A0=C2=A0=C2=A0 hex filename > =C2=A0 19643 =C2=A0 15250 =C2=A0=C2=A0=C2=A0 904 =C2=A0 35797 =C2=A0=C2= =A0 8bd5 ../build/arch/x86/kernel/irq.o > =C2=A0 17355 =C2=A0 15250 =C2=A0=C2=A0=C2=A0 904 =C2=A0 33509 =C2=A0=C2= =A0 82e5 ../build/arch/x86/kernel/irq.o >=20 > Adding a new vector or software counter only requires to update the table > and everything just works. Using the core provided emit function which > speeds up 0 outputs makes it significantly faster. >=20 > Signed-off-by: Thomas Gleixner > --- > V3: Add the missing #ifdeffery - 0-day > =C2=A0=C2=A0=C2=A0 Add the alignment back - Radu > =C2=A0=C2=A0=C2=A0 Address dyslexia for real - Michael >=20 > V2: Simplified and extended vector skip mechanism > =C2=A0=C2=A0=C2=A0 Fixup the typoes - Micheal, Dmitry > =C2=A0=C2=A0=C2=A0 Added the lost precision back for ERR/MIS - Dmitry > --- > =C2=A0arch/x86/events/amd/core.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/events/amd/ibs.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/events/core.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/events/intel/core.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/events/intel/knc.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/events/intel/p4.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/events/zhaoxin/core.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2= =A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/hyperv/hv_init.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/include/asm/hardirq.h=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2= =A0=C2=A0 77 ++++++----- > =C2=A0arch/x86/include/asm/irq.h=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/include/asm/mce.h=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 3=20 > =C2=A0arch/x86/kernel/apic/apic.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 |=C2=A0=C2=A0=C2=A0 4=20 > =C2=A0arch/x86/kernel/apic/ipi.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/kernel/cpu/acrn.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/kernel/cpu/mce/amd.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |= =C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/kernel/cpu/mce/core.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2= =A0=C2=A0=C2=A0 8 - > =C2=A0arch/x86/kernel/cpu/mce/threshold.c |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/kernel/cpu/mshyperv.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2= =A0=C2=A0=C2=A0 4=20 > =C2=A0arch/x86/kernel/irq.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 251 ++++++++++++-----------= ------------- > =C2=A0arch/x86/kernel/irq_work.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/kernel/irqinit.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/kernel/kvm.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/kernel/nmi.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 4=20 > =C2=A0arch/x86/kernel/smp.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 6=20 > =C2=A0arch/x86/mm/tlb.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0= =C2=A0 2=20 > =C2=A0arch/x86/xen/enlighten_hvm.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/xen/enlighten_pv.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A0arch/x86/xen/smp.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 = 6=20 > =C2=A0arch/x86/xen/smp_pv.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2=20 > =C2=A029 files changed, 170 insertions(+), 233 deletions(-) >=20 > --- a/arch/x86/events/amd/core.c > +++ b/arch/x86/events/amd/core.c > @@ -1032,7 +1032,7 @@ static int amd_pmu_v2_handle_irq(struct > =C2=A0 * Unmasking the LVTPC is not required as the Mask (M) bit of the = LVT > =C2=A0 * PMI entry is not set by the local APIC when a PMC overflow occu= rs > =C2=A0 */ > - inc_irq_stat(apic_perf_irqs); > + inc_perf_irq_stat(); > =C2=A0 > =C2=A0done: > =C2=A0 cpuc->enabled =3D pmu_enabled; > --- a/arch/x86/events/amd/ibs.c > +++ b/arch/x86/events/amd/ibs.c > @@ -1403,7 +1403,7 @@ perf_ibs_nmi_handler(unsigned int cmd, s > =C2=A0 handled +=3D perf_ibs_handle_irq(&perf_ibs_op, regs); > =C2=A0 > =C2=A0 if (handled) > - inc_irq_stat(apic_perf_irqs); > + inc_perf_irq_stat(); > =C2=A0 > =C2=A0 perf_sample_event_took(sched_clock() - stamp); > =C2=A0 > --- a/arch/x86/events/core.c > +++ b/arch/x86/events/core.c > @@ -1747,7 +1747,7 @@ int x86_pmu_handle_irq(struct pt_regs *r > =C2=A0 } > =C2=A0 > =C2=A0 if (handled) > - inc_irq_stat(apic_perf_irqs); > + inc_perf_irq_stat(); > =C2=A0 > =C2=A0 return handled; > =C2=A0} > --- a/arch/x86/events/intel/core.c > +++ b/arch/x86/events/intel/core.c > @@ -3504,7 +3504,7 @@ static int handle_pmi_common(struct pt_r > =C2=A0 int bit; > =C2=A0 int handled =3D 0; > =C2=A0 > - inc_irq_stat(apic_perf_irqs); > + inc_perf_irq_stat(); > =C2=A0 > =C2=A0 /* > =C2=A0 * Ignore a range of extra bits in status that do not indicate > --- a/arch/x86/events/intel/knc.c > +++ b/arch/x86/events/intel/knc.c > @@ -238,7 +238,7 @@ static int knc_pmu_handle_irq(struct pt_ > =C2=A0 goto done; > =C2=A0 } > =C2=A0 > - inc_irq_stat(apic_perf_irqs); > + inc_perf_irq_stat(); > =C2=A0 > =C2=A0 for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { > =C2=A0 struct perf_event *event =3D cpuc->events[bit]; > --- a/arch/x86/events/intel/p4.c > +++ b/arch/x86/events/intel/p4.c > @@ -1077,7 +1077,7 @@ static int p4_pmu_handle_irq(struct pt_r > =C2=A0 } > =C2=A0 > =C2=A0 if (handled) > - inc_irq_stat(apic_perf_irqs); > + inc_perf_irq_stat(); > =C2=A0 > =C2=A0 /* > =C2=A0 * When dealing with the unmasking of the LVTPC on P4 perf hw, it = has > --- a/arch/x86/events/zhaoxin/core.c > +++ b/arch/x86/events/zhaoxin/core.c > @@ -373,7 +373,7 @@ static int zhaoxin_pmu_handle_irq(struct > =C2=A0 else > =C2=A0 zhaoxin_pmu_ack_status(status); > =C2=A0 > - inc_irq_stat(apic_perf_irqs); > + inc_perf_irq_stat(); > =C2=A0 > =C2=A0 /* > =C2=A0 * CondChgd bit 63 doesn't mean any overflow status. Ignore > --- a/arch/x86/hyperv/hv_init.c > +++ b/arch/x86/hyperv/hv_init.c > @@ -219,7 +219,7 @@ static inline bool hv_reenlightenment_av > =C2=A0DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_reenlightenment) > =C2=A0{ > =C2=A0 apic_eoi(); > - inc_irq_stat(irq_hv_reenlightenment_count); > + inc_irq_stat(HYPERV_REENLIGHTENMENT); > =C2=A0 schedule_delayed_work(&hv_reenlightenment_work, HZ/10); > =C2=A0} > =C2=A0 > --- a/arch/x86/include/asm/hardirq.h > +++ b/arch/x86/include/asm/hardirq.h > @@ -4,51 +4,60 @@ > =C2=A0 > =C2=A0#include > =C2=A0 > -typedef struct { > -#if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL) > - u8 =C2=A0=C2=A0=C2=A0=C2=A0 kvm_cpu_l1tf_flush_l1d; > -#endif > - unsigned int __nmi_count; /* arch dependent */ > +enum irq_stat_counts { > + IRQ_COUNT_NMI, > =C2=A0#ifdef CONFIG_X86_LOCAL_APIC > - unsigned int apic_timer_irqs; /* arch dependent */ > - unsigned int irq_spurious_count; > - unsigned int icr_read_retry_count; > -#endif > -#if IS_ENABLED(CONFIG_KVM) > - unsigned int kvm_posted_intr_ipis; > - unsigned int kvm_posted_intr_wakeup_ipis; > - unsigned int kvm_posted_intr_nested_ipis; > + 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, > =C2=A0#endif > -#ifdef CONFIG_GUEST_PERF_EVENTS > - unsigned int perf_guest_mediated_pmis; > -#endif > - unsigned int x86_platform_ipis; /* arch dependent */ > - unsigned int apic_perf_irqs; > - unsigned int apic_irq_work_irqs; > =C2=A0#ifdef CONFIG_SMP > - unsigned int irq_resched_count; > - unsigned int irq_call_count; > + IRQ_COUNT_RESCHEDULE, > + IRQ_COUNT_CALL_FUNCTION, > =C2=A0#endif > - unsigned int irq_tlb_count; > + IRQ_COUNT_TLB, > =C2=A0#ifdef CONFIG_X86_THERMAL_VECTOR > - unsigned int irq_thermal_count; > + IRQ_COUNT_THERMAL_APIC, > =C2=A0#endif > =C2=A0#ifdef CONFIG_X86_MCE_THRESHOLD > - unsigned int irq_threshold_count; > + IRQ_COUNT_THRESHOLD_APIC, > =C2=A0#endif > =C2=A0#ifdef CONFIG_X86_MCE_AMD > - unsigned int irq_deferred_error_count; > + IRQ_COUNT_DEFERRED_ERROR, > +#endif > +#ifdef CONFIG_X86_MCE > + IRQ_COUNT_MCE_EXCEPTION, > + IRQ_COUNT_MCE_POLL, > =C2=A0#endif > =C2=A0#ifdef CONFIG_X86_HV_CALLBACK_VECTOR > - unsigned int irq_hv_callback_count; > + IRQ_COUNT_HYPERVISOR_CALLBACK, > =C2=A0#endif > =C2=A0#if IS_ENABLED(CONFIG_HYPERV) > - unsigned int irq_hv_reenlightenment_count; > - unsigned int hyperv_stimer0_count; > + 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, > =C2=A0#endif > =C2=A0#ifdef CONFIG_X86_POSTED_MSI > - unsigned int posted_msi_notification_count; > + IRQ_COUNT_POSTED_MSI_NOTIFICATION, > =C2=A0#endif > + IRQ_COUNT_MAX, > +}; > + > +typedef struct { > +#if IS_ENABLED(CONFIG_CPU_MITIGATIONS) && IS_ENABLED(CONFIG_KVM_INTEL) > + u8 =C2=A0=C2=A0=C2=A0=C2=A0 kvm_cpu_l1tf_flush_l1d; > +#endif > + unsigned int counts[IRQ_COUNT_MAX]; > =C2=A0} ____cacheline_aligned irq_cpustat_t; > =C2=A0 > =C2=A0DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); > @@ -58,15 +67,23 @@ DECLARE_PER_CPU_ALIGNED(struct pi_desc, > =C2=A0#endif > =C2=A0#define __ARCH_IRQ_STAT > =C2=A0 > -#define inc_irq_stat(member) this_cpu_inc(irq_stat.member) > +#define inc_irq_stat(index) this_cpu_inc(irq_stat.counts[IRQ_COUNT_##ind= ex]) > + > +#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 > =C2=A0 > =C2=A0extern void ack_bad_irq(unsigned int irq); > =C2=A0 > +#ifdef CONFIG_PROC_FS > =C2=A0extern u64 arch_irq_stat_cpu(unsigned int cpu); > =C2=A0#define arch_irq_stat_cpu arch_irq_stat_cpu > =C2=A0 > =C2=A0extern u64 arch_irq_stat(void); > =C2=A0#define arch_irq_stat arch_irq_stat > +#endif > =C2=A0 > =C2=A0DECLARE_PER_CPU_CACHE_HOT(u16, __softirq_pending); > =C2=A0#define local_softirq_pending_ref=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 __softirq_pending > --- a/arch/x86/include/asm/irq.h > +++ b/arch/x86/include/asm/irq.h > @@ -47,4 +47,6 @@ void arch_trigger_cpumask_backtrace(cons > =C2=A0#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtra= ce > =C2=A0#endif > =C2=A0 > +void irq_init_stats(void); > + > =C2=A0#endif /* _ASM_X86_IRQ_H */ > --- a/arch/x86/include/asm/mce.h > +++ b/arch/x86/include/asm/mce.h > @@ -291,9 +291,6 @@ bool mce_is_memory_error(struct mce *m); > =C2=A0bool mce_is_correctable(struct mce *m); > =C2=A0bool mce_usable_address(struct mce *m); > =C2=A0 > -DECLARE_PER_CPU(unsigned, mce_exception_count); > -DECLARE_PER_CPU(unsigned, mce_poll_count); > - > =C2=A0typedef DECLARE_BITMAP(mce_banks_t, MAX_NR_BANKS); > =C2=A0DECLARE_PER_CPU(mce_banks_t, mce_poll_banks); > =C2=A0 > --- a/arch/x86/kernel/apic/apic.c > +++ b/arch/x86/kernel/apic/apic.c > @@ -1040,7 +1040,7 @@ static void local_apic_timer_interrupt(v > =C2=A0 /* > =C2=A0 * the NMI deadlock-detector uses this. > =C2=A0 */ > - inc_irq_stat(apic_timer_irqs); > + inc_irq_stat(APIC_TIMER); > =C2=A0 > =C2=A0 evt->event_handler(evt); > =C2=A0} > @@ -2108,7 +2108,7 @@ static noinline void handle_spurious_int > =C2=A0 > =C2=A0 trace_spurious_apic_entry(vector); > =C2=A0 > - inc_irq_stat(irq_spurious_count); > + inc_irq_stat(SPURIOUS); > =C2=A0 > =C2=A0 /* > =C2=A0 * If this is a spurious interrupt then do not acknowledge > --- a/arch/x86/kernel/apic/ipi.c > +++ b/arch/x86/kernel/apic/ipi.c > @@ -120,7 +120,7 @@ u32 apic_mem_wait_icr_idle_timeout(void) > =C2=A0 for (cnt =3D 0; cnt < 1000; cnt++) { > =C2=A0 if (!(apic_read(APIC_ICR) & APIC_ICR_BUSY)) > =C2=A0 return 0; > - inc_irq_stat(icr_read_retry_count); > + inc_irq_stat(ICR_READ_RETRY); > =C2=A0 udelay(100); > =C2=A0 } > =C2=A0 return APIC_ICR_BUSY; > --- a/arch/x86/kernel/cpu/acrn.c > +++ b/arch/x86/kernel/cpu/acrn.c > @@ -52,7 +52,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_acrn_hv_ca > =C2=A0 * HYPERVISOR_CALLBACK_VECTOR. > =C2=A0 */ > =C2=A0 apic_eoi(); > - inc_irq_stat(irq_hv_callback_count); > + inc_irq_stat(HYPERVISOR_CALLBACK); > =C2=A0 > =C2=A0 if (acrn_intr_handler) > =C2=A0 acrn_intr_handler(); > --- a/arch/x86/kernel/cpu/mce/amd.c > +++ b/arch/x86/kernel/cpu/mce/amd.c > @@ -840,7 +840,7 @@ bool amd_mce_usable_address(struct mce * > =C2=A0DEFINE_IDTENTRY_SYSVEC(sysvec_deferred_error) > =C2=A0{ > =C2=A0 trace_deferred_error_apic_entry(DEFERRED_ERROR_VECTOR); > - inc_irq_stat(irq_deferred_error_count); > + inc_irq_stat(DEFERRED_ERROR); > =C2=A0 deferred_error_int_vector(); > =C2=A0 trace_deferred_error_apic_exit(DEFERRED_ERROR_VECTOR); > =C2=A0 apic_eoi(); > --- a/arch/x86/kernel/cpu/mce/core.c > +++ b/arch/x86/kernel/cpu/mce/core.c > @@ -67,8 +67,6 @@ static DEFINE_MUTEX(mce_sysfs_mutex); > =C2=A0 > =C2=A0#define SPINUNIT 100 /* 100ns */ > =C2=A0 > -DEFINE_PER_CPU(unsigned, mce_exception_count); > - > =C2=A0DEFINE_PER_CPU_READ_MOSTLY(unsigned int, mce_num_banks); > =C2=A0 > =C2=A0DEFINE_PER_CPU_READ_MOSTLY(struct mce_bank[MAX_NR_BANKS], mce_banks= _array); > @@ -716,8 +714,6 @@ static noinstr void mce_read_aux(struct > =C2=A0 } > =C2=A0} > =C2=A0 > -DEFINE_PER_CPU(unsigned, mce_poll_count); > - > =C2=A0/* > =C2=A0 * We have three scenarios for checking for Deferred errors: > =C2=A0 * > @@ -820,7 +816,7 @@ void machine_check_poll(enum mcp_flags f > =C2=A0 struct mce *m; > =C2=A0 int i; > =C2=A0 > - this_cpu_inc(mce_poll_count); > + inc_irq_stat(MCE_POLL); > =C2=A0 > =C2=A0 mce_gather_info(&err, NULL); > =C2=A0 m =3D &err.m; > @@ -1595,7 +1591,7 @@ noinstr void do_machine_check(struct pt_ > =C2=A0 */ > =C2=A0 lmce =3D 1; > =C2=A0 > - this_cpu_inc(mce_exception_count); > + inc_irq_stat(MCE_EXCEPTION); > =C2=A0 > =C2=A0 mce_gather_info(&err, regs); > =C2=A0 m =3D &err.m; > --- a/arch/x86/kernel/cpu/mce/threshold.c > +++ b/arch/x86/kernel/cpu/mce/threshold.c > @@ -37,7 +37,7 @@ void (*mce_threshold_vector)(void) =3D def > =C2=A0DEFINE_IDTENTRY_SYSVEC(sysvec_threshold) > =C2=A0{ > =C2=A0 trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR); > - inc_irq_stat(irq_threshold_count); > + inc_irq_stat(THRESHOLD_APIC); > =C2=A0 mce_threshold_vector(); > =C2=A0 trace_threshold_apic_exit(THRESHOLD_APIC_VECTOR); > =C2=A0 apic_eoi(); > --- a/arch/x86/kernel/cpu/mshyperv.c > +++ b/arch/x86/kernel/cpu/mshyperv.c > @@ -154,7 +154,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_cal > =C2=A0{ > =C2=A0 struct pt_regs *old_regs =3D set_irq_regs(regs); > =C2=A0 > - inc_irq_stat(irq_hv_callback_count); > + inc_irq_stat(HYPERVISOR_CALLBACK); > =C2=A0 if (mshv_handler) > =C2=A0 mshv_handler(); > =C2=A0 > @@ -191,7 +191,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_sti > =C2=A0{ > =C2=A0 struct pt_regs *old_regs =3D set_irq_regs(regs); > =C2=A0 > - inc_irq_stat(hyperv_stimer0_count); > + inc_irq_stat(HYPERV_STIMER0); > =C2=A0 if (hv_stimer0_handler) > =C2=A0 hv_stimer0_handler(); > =C2=A0 add_interrupt_randomness(HYPERV_STIMER0_VECTOR); > --- a/arch/x86/kernel/irq.c > +++ b/arch/x86/kernel/irq.c > @@ -62,156 +62,105 @@ void ack_bad_irq(unsigned int irq) > =C2=A0 apic_eoi(); > =C2=A0} > =C2=A0 > -/* > - * A helper routine for putting space and decimal number without overhea= d > - * from rich format of printf(). > - */ > -static void put_decimal(struct seq_file *p, unsigned long long num) > -{ > - const char *delimiter =3D " "; > - unsigned int width =3D 10; > +struct irq_stat_info { > + unsigned int skip_vector; > + const char *symbol; > + const char *text; > +}; > =C2=A0 > - seq_put_decimal_ull_width(p, delimiter, num, width); > -} > +#define ISS(idx, sym, txt) [IRQ_COUNT_##idx] =3D { .symbol =3D sym, .tex= t =3D txt } > =C2=A0 > -#define irq_stats(x) (&per_cpu(irq_stat, x)) > -/* > - * /proc/interrupts printing for arch specific interrupts > - */ > -int arch_show_interrupts(struct seq_file *p, int prec) > -{ > - int j; > +#define ITS(idx, sym, txt) [IRQ_COUNT_##idx] =3D \ > + { .skip_vector =3D idx## _VECTOR, .symbol =3D sym, .text =3D txt } > =C2=A0 > - seq_printf(p, "%*s:", prec, "NMI"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->__nmi_count); > - seq_puts(p, "=C2=A0 Non-maskable interrupts\n"); > +static struct irq_stat_info irq_stat_info[IRQ_COUNT_MAX] __ro_after_init= =3D { > + ISS(NMI, "NMI", "=C2=A0 Non-maskable interrupts\n"), > =C2=A0#ifdef CONFIG_X86_LOCAL_APIC > - seq_printf(p, "%*s:", prec, "LOC"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->apic_timer_irqs); > - seq_puts(p, "=C2=A0 Local timer interrupts\n"); > - > - seq_printf(p, "%*s:", prec, "SPU"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->irq_spurious_count); > - seq_puts(p, "=C2=A0 Spurious interrupts\n"); > - seq_printf(p, "%*s:", prec, "PMI"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->apic_perf_irqs); > - seq_puts(p, "=C2=A0 Performance monitoring interrupts\n"); > - seq_printf(p, "%*s:", prec, "IWI"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->apic_irq_work_irqs); > - seq_puts(p, "=C2=A0 IRQ work interrupts\n"); > - seq_printf(p, "%*s:", prec, "RTR"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->icr_read_retry_count); > - seq_puts(p, "=C2=A0 APIC ICR read retries\n"); > - if (x86_platform_ipi_callback) { > - seq_printf(p, "%*s:", prec, "PLT"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->x86_platform_ipis); > - seq_puts(p, "=C2=A0 Platform interrupts\n"); > - } > + ISS(APIC_TIMER, "LOC", "=C2=A0 Local timer interrupts\n"), > + ISS(SPURIOUS, "SPU", "=C2=A0 Spurious interrupts\n"), > + ISS(APIC_PERF, "PMI", "=C2=A0 Performance monitoring interrupts\n"), > + ISS(IRQ_WORK, "IWI", "=C2=A0 IRQ work interrupts\n"), > + ISS(ICR_READ_RETRY, "RTR", "=C2=A0 APIC ICR read retries\n"), > + ISS(X86_PLATFORM_IPI, "PLT", "=C2=A0 Platform interrupts\n"), > =C2=A0#endif > =C2=A0#ifdef CONFIG_SMP > - seq_printf(p, "%*s:", prec, "RES"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->irq_resched_count); > - seq_puts(p, "=C2=A0 Rescheduling interrupts\n"); > - seq_printf(p, "%*s:", prec, "CAL"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->irq_call_count); > - seq_puts(p, "=C2=A0 Function call interrupts\n"); > - seq_printf(p, "%*s:", prec, "TLB"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->irq_tlb_count); > - seq_puts(p, "=C2=A0 TLB shootdowns\n"); > + ISS(RESCHEDULE, "RES", "=C2=A0 Rescheduling interrupts\n"), > + ISS(CALL_FUNCTION, "CAL", "=C2=A0 Function call interrupts\n"), > =C2=A0#endif > + ISS(TLB, "TLB", "=C2=A0 TLB shootdowns\n"), > =C2=A0#ifdef CONFIG_X86_THERMAL_VECTOR > - seq_printf(p, "%*s:", prec, "TRM"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->irq_thermal_count); > - seq_puts(p, "=C2=A0 Thermal event interrupts\n"); > + ISS(THERMAL_APIC, "TRM", "=C2=A0 Thermal event interrupt\n"), > =C2=A0#endif > =C2=A0#ifdef CONFIG_X86_MCE_THRESHOLD > - seq_printf(p, "%*s:", prec, "THR"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->irq_threshold_count); > - seq_puts(p, "=C2=A0 Threshold APIC interrupts\n"); > + ISS(THRESHOLD_APIC, "THR", "=C2=A0 Threshold APIC interrupts\n"), > =C2=A0#endif > =C2=A0#ifdef CONFIG_X86_MCE_AMD > - seq_printf(p, "%*s:", prec, "DFR"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->irq_deferred_error_count); > - seq_puts(p, "=C2=A0 Deferred Error APIC interrupts\n"); > + ISS(DEFERRED_ERROR, "DFR", "=C2=A0 Deferred Error APIC interrupts\n"), > =C2=A0#endif > =C2=A0#ifdef CONFIG_X86_MCE > - seq_printf(p, "%*s:", prec, "MCE"); > - for_each_online_cpu(j) > - put_decimal(p, per_cpu(mce_exception_count, j)); > - seq_puts(p, "=C2=A0 Machine check exceptions\n"); > - seq_printf(p, "%*s:", prec, "MCP"); > - for_each_online_cpu(j) > - put_decimal(p, per_cpu(mce_poll_count, j)); > - seq_puts(p, "=C2=A0 Machine check polls\n"); > + ISS(MCE_EXCEPTION, "MCE", "=C2=A0 Machine check exceptions\n"), > + ISS(MCE_POLL, "MCP", "=C2=A0 Machine check polls\n"), > =C2=A0#endif > =C2=A0#ifdef CONFIG_X86_HV_CALLBACK_VECTOR > - if (test_bit(HYPERVISOR_CALLBACK_VECTOR, system_vectors)) { > - seq_printf(p, "%*s:", prec, "HYP"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->irq_hv_callback_count); > - seq_puts(p, "=C2=A0 Hypervisor callback interrupts\n"); > - } > + ITS(HYPERVISOR_CALLBACK, "HYP", "=C2=A0 Hypervisor callback interrupts\= n"), > =C2=A0#endif > =C2=A0#if IS_ENABLED(CONFIG_HYPERV) > - if (test_bit(HYPERV_REENLIGHTENMENT_VECTOR, system_vectors)) { > - seq_printf(p, "%*s:", prec, "HRE"); > - for_each_online_cpu(j) > - put_decimal(p, > - =C2=A0=C2=A0=C2=A0 irq_stats(j)->irq_hv_reenlightenment_count); > - seq_puts(p, "=C2=A0 Hyper-V reenlightenment interrupts\n"); > - } > - if (test_bit(HYPERV_STIMER0_VECTOR, system_vectors)) { > - seq_printf(p, "%*s:", prec, "HVS"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->hyperv_stimer0_count); > - seq_puts(p, "=C2=A0 Hyper-V stimer0 interrupts\n"); > - } > -#endif > - seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); > -#if defined(CONFIG_X86_IO_APIC) > - seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count)); > + ITS(HYPERV_REENLIGHTENMENT, "HRE", "=C2=A0 Hyper-V reenlightenment inte= rrupts\n"), > + ITS(HYPERV_STIMER0, "HVS", "=C2=A0 Hyper-V stimer0 interrupts\n"), > =C2=A0#endif > =C2=A0#if IS_ENABLED(CONFIG_KVM) > - seq_printf(p, "%*s:", prec, "PIN"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->kvm_posted_intr_ipis); > - seq_puts(p, "=C2=A0 Posted-interrupt notification event\n"); > - > - seq_printf(p, "%*s:", prec, "NPI"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->kvm_posted_intr_nested_ipis); > - seq_puts(p, "=C2=A0 Nested posted-interrupt event\n"); > - > - seq_printf(p, "%*s:", prec, "PIW"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->kvm_posted_intr_wakeup_ipis); > - seq_puts(p, "=C2=A0 Posted-interrupt wakeup event\n"); > + ITS(POSTED_INTR, "PIN", "=C2=A0 Posted-interrupt notification event\n"= ), > + ITS(POSTED_INTR_NESTED, "NPI", "=C2=A0 Nested posted-interrupt event\n= "), > + ITS(POSTED_INTR_WAKEUP, "PIW", "=C2=A0 Posted-interrupt wakeup event\n= "), > =C2=A0#endif > =C2=A0#ifdef CONFIG_GUEST_PERF_EVENTS > - seq_printf(p, "%*s:", prec, "VPMI"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->perf_guest_mediated_pmis); > - seq_puts(p, " Perf Guest Mediated PMI\n"); > + ISS(PERF_GUEST_MEDIATED_PMI, "VPMI", " Perf Guest Mediated PMI\n"), > =C2=A0#endif > =C2=A0#ifdef CONFIG_X86_POSTED_MSI > - seq_printf(p, "%*s:", prec, "PMN"); > - for_each_online_cpu(j) > - put_decimal(p, irq_stats(j)->posted_msi_notification_count); > - seq_puts(p, "=C2=A0 Posted MSI notification event\n"); > + ISS(POSTED_MSI_NOTIFICATION, "PMN", "=C2=A0 Posted MSI notification eve= nt\n"), > =C2=A0#endif > +}; > + > +void __init irq_init_stats(void) > +{ > + struct irq_stat_info *info =3D irq_stat_info; > + > + for (unsigned int i =3D 0; i < ARRAY_SIZE(irq_stat_info); i++, info++) = { > + if (info->skip_vector && test_bit(info->skip_vector, system_vectors)) > + info->skip_vector =3D 0; > + } > + > +#ifdef CONFIG_X86_LOCAL_APIC > + if (!x86_platform_ipi_callback) > + irq_stat_info[IRQ_COUNT_X86_PLATFORM_IPI].skip_vector =3D 1; > +#endif > + > +#ifdef CONFIG_X86_POSTED_MSI > + if (!posted_msi_enabled()) > + irq_stat_info[IRQ_COUNT_POSTED_MSI_NOTIFICATION].skip_vector =3D 1; > +#endif > +} > + > +#ifdef CONFIG_PROC_FS > +/* > + * /proc/interrupts printing for arch specific interrupts > + */ > +int arch_show_interrupts(struct seq_file *p, int prec) > +{ > + const struct irq_stat_info *info =3D irq_stat_info; > + > + for (unsigned int i =3D 0; i < ARRAY_SIZE(irq_stat_info); i++, info++) = { > + if (info->skip_vector) > + continue; > + > + seq_printf(p, "%*s:", prec, info->symbol); > + 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))= ; > =C2=A0 return 0; > =C2=A0} > =C2=A0 > @@ -220,38 +169,11 @@ int arch_show_interrupts(struct seq_file > =C2=A0 */ > =C2=A0u64 arch_irq_stat_cpu(unsigned int cpu) > =C2=A0{ > - u64 sum =3D irq_stats(cpu)->__nmi_count; > + irq_cpustat_t *p =3D per_cpu_ptr(&irq_stat, cpu); > + u64 sum =3D 0; > =C2=A0 > -#ifdef CONFIG_X86_LOCAL_APIC > - sum +=3D irq_stats(cpu)->apic_timer_irqs; > - sum +=3D irq_stats(cpu)->irq_spurious_count; > - sum +=3D irq_stats(cpu)->apic_perf_irqs; > - sum +=3D irq_stats(cpu)->apic_irq_work_irqs; > - sum +=3D irq_stats(cpu)->icr_read_retry_count; > - if (x86_platform_ipi_callback) > - sum +=3D irq_stats(cpu)->x86_platform_ipis; > -#endif > -#ifdef CONFIG_SMP > - sum +=3D irq_stats(cpu)->irq_resched_count; > - sum +=3D irq_stats(cpu)->irq_call_count; > -#endif > -#ifdef CONFIG_X86_THERMAL_VECTOR > - sum +=3D irq_stats(cpu)->irq_thermal_count; > -#endif > -#ifdef CONFIG_X86_MCE_THRESHOLD > - sum +=3D irq_stats(cpu)->irq_threshold_count; > -#endif > -#ifdef CONFIG_X86_HV_CALLBACK_VECTOR > - sum +=3D irq_stats(cpu)->irq_hv_callback_count; > -#endif > -#if IS_ENABLED(CONFIG_HYPERV) > - sum +=3D irq_stats(cpu)->irq_hv_reenlightenment_count; > - sum +=3D irq_stats(cpu)->hyperv_stimer0_count; > -#endif > -#ifdef CONFIG_X86_MCE > - sum +=3D per_cpu(mce_exception_count, cpu); > - sum +=3D per_cpu(mce_poll_count, cpu); > -#endif > + for (unsigned int i =3D 0; i < ARRAY_SIZE(irq_stat_info); i++) > + sum +=3D p->counts[i]; > =C2=A0 return sum; > =C2=A0} > =C2=A0 > @@ -260,6 +182,7 @@ u64 arch_irq_stat(void) > =C2=A0 u64 sum =3D atomic_read(&irq_err_count); > =C2=A0 return sum; > =C2=A0} > +#endif /* CONFIG_PROC_FS */ > =C2=A0 > =C2=A0static __always_inline void handle_irq(struct irq_desc *desc, > =C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 struct pt_regs *regs) > @@ -344,7 +267,7 @@ DEFINE_IDTENTRY_IRQ(common_interrupt) > =C2=A0 > =C2=A0#ifdef CONFIG_X86_LOCAL_APIC > =C2=A0/* Function pointer for generic interrupt vector handling */ > -void (*x86_platform_ipi_callback)(void) =3D NULL; > +void (*x86_platform_ipi_callback)(void) __ro_after_init =3D NULL; > =C2=A0/* > =C2=A0 * Handler for X86_PLATFORM_IPI_VECTOR. > =C2=A0 */ > @@ -354,7 +277,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_x86_platfo > =C2=A0 > =C2=A0 apic_eoi(); > =C2=A0 trace_x86_platform_ipi_entry(X86_PLATFORM_IPI_VECTOR); > - inc_irq_stat(x86_platform_ipis); > + inc_irq_stat(X86_PLATFORM_IPI); > =C2=A0 if (x86_platform_ipi_callback) > =C2=A0 x86_platform_ipi_callback(); > =C2=A0 trace_x86_platform_ipi_exit(X86_PLATFORM_IPI_VECTOR); > @@ -369,7 +292,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_x86_platfo > =C2=A0DEFINE_IDTENTRY_SYSVEC(sysvec_perf_guest_mediated_pmi_handler) > =C2=A0{ > =C2=A0 apic_eoi(); > - inc_irq_stat(perf_guest_mediated_pmis); > + inc_irq_stat(PERF_GUEST_MEDIATED_PMI); > =C2=A0 perf_guest_handle_mediated_pmi(); > =C2=A0} > =C2=A0#endif > @@ -395,7 +318,7 @@ EXPORT_SYMBOL_FOR_KVM(kvm_set_posted_int > =C2=A0DEFINE_IDTENTRY_SYSVEC_SIMPLE(sysvec_kvm_posted_intr_ipi) > =C2=A0{ > =C2=A0 apic_eoi(); > - inc_irq_stat(kvm_posted_intr_ipis); > + inc_irq_stat(POSTED_INTR); > =C2=A0} > =C2=A0 > =C2=A0/* > @@ -404,7 +327,7 @@ DEFINE_IDTENTRY_SYSVEC_SIMPLE(sysvec_kvm > =C2=A0DEFINE_IDTENTRY_SYSVEC(sysvec_kvm_posted_intr_wakeup_ipi) > =C2=A0{ > =C2=A0 apic_eoi(); > - inc_irq_stat(kvm_posted_intr_wakeup_ipis); > + inc_irq_stat(POSTED_INTR_WAKEUP); > =C2=A0 kvm_posted_intr_wakeup_handler(); > =C2=A0} > =C2=A0 > @@ -414,7 +337,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_kvm_posted > =C2=A0DEFINE_IDTENTRY_SYSVEC_SIMPLE(sysvec_kvm_posted_intr_nested_ipi) > =C2=A0{ > =C2=A0 apic_eoi(); > - inc_irq_stat(kvm_posted_intr_nested_ipis); > + inc_irq_stat(POSTED_INTR_NESTED); > =C2=A0} > =C2=A0#endif > =C2=A0 > @@ -488,7 +411,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_posted_msi > =C2=A0 > =C2=A0 /* Mark the handler active for intel_ack_posted_msi_irq() */ > =C2=A0 __this_cpu_write(posted_msi_handler_active, true); > - inc_irq_stat(posted_msi_notification_count); > + inc_irq_stat(POSTED_MSI_NOTIFICATION); > =C2=A0 irq_enter(); > =C2=A0 > =C2=A0 /* > @@ -583,7 +506,7 @@ static void smp_thermal_vector(void) > =C2=A0DEFINE_IDTENTRY_SYSVEC(sysvec_thermal) > =C2=A0{ > =C2=A0 trace_thermal_apic_entry(THERMAL_APIC_VECTOR); > - inc_irq_stat(irq_thermal_count); > + inc_irq_stat(THERMAL_APIC); > =C2=A0 smp_thermal_vector(); > =C2=A0 trace_thermal_apic_exit(THERMAL_APIC_VECTOR); > =C2=A0 apic_eoi(); > --- a/arch/x86/kernel/irq_work.c > +++ b/arch/x86/kernel/irq_work.c > @@ -18,7 +18,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_irq_work) > =C2=A0{ > =C2=A0 apic_eoi(); > =C2=A0 trace_irq_work_entry(IRQ_WORK_VECTOR); > - inc_irq_stat(apic_irq_work_irqs); > + inc_irq_stat(IRQ_WORK); > =C2=A0 irq_work_run(); > =C2=A0 trace_irq_work_exit(IRQ_WORK_VECTOR); > =C2=A0} > --- a/arch/x86/kernel/irqinit.c > +++ b/arch/x86/kernel/irqinit.c > @@ -104,6 +104,8 @@ void __init native_init_IRQ(void) > =C2=A0 if (!cpu_feature_enabled(X86_FEATURE_FRED)) > =C2=A0 idt_setup_apic_and_irq_gates(); > =C2=A0 > + irq_init_stats(); > + > =C2=A0 lapic_assign_system_vectors(); > =C2=A0 > =C2=A0 if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs()) { > --- a/arch/x86/kernel/kvm.c > +++ b/arch/x86/kernel/kvm.c > @@ -310,7 +310,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_kvm_asyncp > =C2=A0 > =C2=A0 apic_eoi(); > =C2=A0 > - inc_irq_stat(irq_hv_callback_count); > + inc_irq_stat(HYPERVISOR_CALLBACK); > =C2=A0 > =C2=A0 if (__this_cpu_read(async_pf_enabled)) { > =C2=A0 token =3D __this_cpu_read(apf_reason.token); > --- a/arch/x86/kernel/nmi.c > +++ b/arch/x86/kernel/nmi.c > @@ -576,7 +576,7 @@ DEFINE_IDTENTRY_RAW(exc_nmi) > =C2=A0 > =C2=A0 irq_state =3D irqentry_nmi_enter(regs); > =C2=A0 > - inc_irq_stat(__nmi_count); > + inc_irq_stat(NMI); > =C2=A0 > =C2=A0 if (IS_ENABLED(CONFIG_NMI_CHECK_CPU) && ignore_nmis) { > =C2=A0 WRITE_ONCE(nsp->idt_ignored, nsp->idt_ignored + 1); > @@ -725,7 +725,7 @@ DEFINE_FREDENTRY_NMI(exc_nmi) > =C2=A0 > =C2=A0 irq_state =3D irqentry_nmi_enter(regs); > =C2=A0 > - inc_irq_stat(__nmi_count); > + inc_irq_stat(NMI); > =C2=A0 default_do_nmi(regs); > =C2=A0 > =C2=A0 irqentry_nmi_exit(regs, irq_state); > --- a/arch/x86/kernel/smp.c > +++ b/arch/x86/kernel/smp.c > @@ -249,7 +249,7 @@ DEFINE_IDTENTRY_SYSVEC_SIMPLE(sysvec_res > =C2=A0{ > =C2=A0 apic_eoi(); > =C2=A0 trace_reschedule_entry(RESCHEDULE_VECTOR); > - inc_irq_stat(irq_resched_count); > + inc_irq_stat(RESCHEDULE); > =C2=A0 scheduler_ipi(); > =C2=A0 trace_reschedule_exit(RESCHEDULE_VECTOR); > =C2=A0} > @@ -258,7 +258,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_call_funct > =C2=A0{ > =C2=A0 apic_eoi(); > =C2=A0 trace_call_function_entry(CALL_FUNCTION_VECTOR); > - inc_irq_stat(irq_call_count); > + inc_irq_stat(CALL_FUNCTION); > =C2=A0 generic_smp_call_function_interrupt(); > =C2=A0 trace_call_function_exit(CALL_FUNCTION_VECTOR); > =C2=A0} > @@ -267,7 +267,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_call_funct > =C2=A0{ > =C2=A0 apic_eoi(); > =C2=A0 trace_call_function_single_entry(CALL_FUNCTION_SINGLE_VECTOR); > - inc_irq_stat(irq_call_count); > + inc_irq_stat(CALL_FUNCTION); > =C2=A0 generic_smp_call_function_single_interrupt(); > =C2=A0 trace_call_function_single_exit(CALL_FUNCTION_SINGLE_VECTOR); > =C2=A0} > --- a/arch/x86/mm/tlb.c > +++ b/arch/x86/mm/tlb.c > @@ -1144,7 +1144,7 @@ static void flush_tlb_func(void *info) > =C2=A0 VM_WARN_ON(!irqs_disabled()); > =C2=A0 > =C2=A0 if (!local) { > - inc_irq_stat(irq_tlb_count); > + inc_irq_stat(TLB); > =C2=A0 count_vm_tlb_event(NR_TLB_REMOTE_FLUSH_RECEIVED); > =C2=A0 } > =C2=A0 > --- a/arch/x86/xen/enlighten_hvm.c > +++ b/arch/x86/xen/enlighten_hvm.c > @@ -125,7 +125,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_xen_hvm_ca > =C2=A0 if (xen_percpu_upcall) > =C2=A0 apic_eoi(); > =C2=A0 > - inc_irq_stat(irq_hv_callback_count); > + inc_irq_stat(HYPERVISOR_CALLBACK); > =C2=A0 > =C2=A0 xen_evtchn_do_upcall(); > =C2=A0 > --- a/arch/x86/xen/enlighten_pv.c > +++ b/arch/x86/xen/enlighten_pv.c > @@ -728,7 +728,7 @@ static void __xen_pv_evtchn_do_upcall(st > =C2=A0{ > =C2=A0 struct pt_regs *old_regs =3D set_irq_regs(regs); > =C2=A0 > - inc_irq_stat(irq_hv_callback_count); > + inc_irq_stat(HYPERVISOR_CALLBACK); > =C2=A0 > =C2=A0 xen_evtchn_do_upcall(); > =C2=A0 > --- a/arch/x86/xen/smp.c > +++ b/arch/x86/xen/smp.c > @@ -23,7 +23,7 @@ static irqreturn_t xen_call_function_sin > =C2=A0 */ > =C2=A0static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id) > =C2=A0{ > - inc_irq_stat(irq_resched_count); > + inc_irq_stat(RESCHEDULE); > =C2=A0 scheduler_ipi(); > =C2=A0 > =C2=A0 return IRQ_HANDLED; > @@ -254,7 +254,7 @@ void xen_send_IPI_allbutself(int vector) > =C2=A0static irqreturn_t xen_call_function_interrupt(int irq, void *dev_i= d) > =C2=A0{ > =C2=A0 generic_smp_call_function_interrupt(); > - inc_irq_stat(irq_call_count); > + inc_irq_stat(CALL_FUNCTION); > =C2=A0 > =C2=A0 return IRQ_HANDLED; > =C2=A0} > @@ -262,7 +262,7 @@ static irqreturn_t xen_call_function_int > =C2=A0static irqreturn_t xen_call_function_single_interrupt(int irq, void= *dev_id) > =C2=A0{ > =C2=A0 generic_smp_call_function_single_interrupt(); > - inc_irq_stat(irq_call_count); > + inc_irq_stat(CALL_FUNCTION); > =C2=A0 > =C2=A0 return IRQ_HANDLED; > =C2=A0} > --- a/arch/x86/xen/smp_pv.c > +++ b/arch/x86/xen/smp_pv.c > @@ -400,7 +400,7 @@ static void xen_pv_stop_other_cpus(int w > =C2=A0static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id) > =C2=A0{ > =C2=A0 irq_work_run(); > - inc_irq_stat(apic_irq_work_irqs); > + inc_irq_stat(IRQ_WORK); > =C2=A0 > =C2=A0 return IRQ_HANDLED; > =C2=A0} Reviewed-by: Radu Rendec