From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 278C33DA5DD for ; Wed, 4 Mar 2026 18:56:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772650587; cv=none; b=P0LOiipvEhIztNji0ETB/Sqjgnno/74eLwryECK/6w9IjIUX6DTq6rPsjjbmYIan7r9QZcuUqeS2YuRINUCwN7ttF0DmA0kJv13WzBOdOMqfxZSRikZY/4xUkC5hYzIDsLWy1/Exwpyzuwohds/zUxg+a3pnrD1NsvttSW0LRLg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772650587; c=relaxed/simple; bh=PGEc4KC2iWY9rDhQYE7v/0YdgSyfeejBfw29Au/4+4o=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=YiKcf0UNW3KUSCSgIU2Kj/KrKesfk/VFSDyp98lr/O3NYxL80+PWCIPw3387a21lN62Ti04lXMtArt9Bgu2Yl+ViADXyphO21eeTYsCIw/JJvCPJxrmCJDWARKTULGLaZg3KT9zGNxAtVFjpPlOz1RcYOZ1BjUh0UrwXHbymAG4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ojGrX0gy; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ojGrX0gy" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4D873C4CEF7; Wed, 4 Mar 2026 18:56:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1772650586; bh=PGEc4KC2iWY9rDhQYE7v/0YdgSyfeejBfw29Au/4+4o=; h=Date:From:To:Cc:Subject:References:From; b=ojGrX0gyijSnbKZihkwRS/N2r9FErkkpP5jRSfvyV3rJuN69Jij2t+/i1qJ2uyHHN j6cwbOGWsscVegxOt3wyKxKr70UWZQaQZLtfdCTJo9YzbRDlaB+l+wKuxZeOPp93GC hVfv++9xtmSoho7LFqsRtmOkeRVvS0GteogHX5qvGLf7dkwnujMQ80ZeI8C6YgomLQ HD0AZRuJ94mxfUqkYF7+ZVIzz2L9ugPwv1F/7CthoyVkEaER2kli/xrINCixoDiH17 xGunbNYzMzbUh+/nDXxH2268KRsXVAcO6Jr9D2iXzaGVUpJd7XbBfXVnc0lXr6xzqS hIXliGWqnlBYw== Date: Wed, 04 Mar 2026 19:56:24 +0100 Message-ID: <20260303154548.840416557@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: x86@kernel.org, Dmitry Ilvokhin , Neil Horman Subject: [patch 13/14] [RFC] genirq/proc: Provide architecture specific binary statistics References: <20260303150539.513068586@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Provide a binary statistics interface similar to the per device and per CPU interfaces to access the architecture specific interrupt statistics. The architecture has to select it in Kconfig and provide an accessor to the per CPU interrupt information and the number of architecture specific entries. The entries are ordered by a numerical index starting from 0, which corresponds to the ordering of those interrupts in /proc/interrupt. The output format is the same as for the per device and per CPU interfaces and only contains entries which have an interrupt count > 0. Reading the architecture specific counters of a 256 CPU x86 system takes 36us kernel time for 6 interrupts with non-zero counts and produces about 10k of data. Signed-off-by: Thomas Gleixner --- kernel/irq/Kconfig | 3 ++ kernel/irq/proc.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -18,6 +18,9 @@ config GENERIC_IRQ_SHOW config GENERIC_IRQ_SHOW_LEVEL bool +config GENERIC_IRQ_STATS_ARCH + bool + config GENERIC_IRQ_STATS_PERCPU bool --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -945,6 +945,61 @@ static __init void irq_pcp_stats_init(vo static inline void irq_pcp_stats_init(void) { } #endif /* !CONFIG_GENERIC_IRQ_STATS_PERCPU */ +#ifdef CONFIG_GENERIC_IRQ_STATS_ARCH +static inline void arch_stat_update_one(struct irq_proc_stat *s) +{ + struct irq_proc_stat_data *d = s->data; + unsigned int cpu, idx = s->irqnr; + + for_each_online_cpu(cpu) { + struct irq_proc_stat_cpu pcpu = { + .cpu = cpu, + .cnt = arch_get_irq_stat(cpu, idx), + }; + + if (pcpu.cnt) + d->pcpu[d->entries++] = pcpu; + } + + if (d->entries) { + d->irqnr = idx; + s->count = sizeof(*d) + d->entries * sizeof(*d->pcpu); + } +} + +static __always_inline bool arch_stat_next_data(struct irq_proc_stat *s) +{ + if (unlikely(s->first)) { + s->irqnr = 0; + s->first = false; + } + + for(; !s->count && s->irqnr < ARCH_IRQ_STATS_NUM_IRQS; s->irqnr++) + arch_stat_update_one(s); + return !!s->count; +} + +static ssize_t irq_arch_stats_read(struct kiocb *iocb, struct iov_iter *iter) +{ + return __irq_stats_read(iocb, iter, arch_stat_next_data); +} + +static const struct proc_ops irq_arch_stat_ops = { + .proc_flags = PROC_ENTRY_PERMANENT, + .proc_open = irq_stats_open, + .proc_release = irq_stats_release, + .proc_read_iter = irq_arch_stats_read, + .proc_lseek = irq_stats_llseek, +}; + +static __init void irq_arch_stats_init(void) +{ + proc_create("arch_stats", 0, root_irq_dir, &irq_arch_stat_ops); +} +#else /* CONFIG_GENERIC_IRQ_STATS_ARCH */ +static inline void irq_arch_stats_init(void) { } +#endif /* !CONFIG_GENERIC_IRQ_STATS_ARCH */ + static int __init irq_proc_init(void) { proc_create_seq("interrupts", 0, NULL, &irq_seq_ops); @@ -953,6 +1008,7 @@ static int __init irq_proc_init(void) proc_create("device_stats", 0, root_irq_dir, &irq_dev_stat_ops); irq_pcp_stats_init(); + irq_arch_stats_init(); return 0; } fs_initcall(irq_proc_init);