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 B0D4E361DA8 for ; Wed, 1 Apr 2026 21:52:46 +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=1775080366; cv=none; b=FfBV1ziR+Gl3thyZNuicHrSJfKIvoBFjrN7eol9ggzHsbf5HUHVrzWQONFoKHSjoG2Y5YFwpF6EmhMrMFSZ7fUwvcjMNU4qWjkDTtm0IGjW5JSytKjXR6+aAF3X62+sQQAk/qEuCSooye4M2RF998IohNnc/bjjsgIt4A89+j8U= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775080366; c=relaxed/simple; bh=5zMH+K8VfDy0mb5xS2iBK59deSErqj4b+XrFDnZxk1A=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=FLKGMutr5uXolBibYT2RBJ5t+AImFfcUB3A2NxDXI2ZG/jE5fe8VCDvkQj+/v0zn+9G6qlWk7EOkGFWv/yN+dXCTkJy3kJveZUYNvWuFOCkq0ZgEs0S16XjWcXmclrsST62LWjIyZ6KPQ2bg4E7xEOsnnZ1+5pjtZNAP1RGN+dY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jC66Qth9; 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="jC66Qth9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C051DC4CEF7; Wed, 1 Apr 2026 21:52:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775080366; bh=5zMH+K8VfDy0mb5xS2iBK59deSErqj4b+XrFDnZxk1A=; h=Date:From:To:Cc:Subject:References:From; b=jC66Qth9C65CwIkKqb4m5t4rk2fBk1IbIRVPugiIi83grxgfzxvOhnv3mDF4Pt/b3 4AK+7f7DlLadG5nioPzK6TGc5lP8U6zKLJh2Y+bnlNyhGztMPNgtcMk2Hr3YwxvvWS z3XlpzgfB2ws2wGLm7K1mLlBWuiTSO7Qt4pKSTEkY505lWBeHX3mJ8+M/sgDb2RPBY ltUVhsPOX45v+6LziXzln8Izvd+tseZuMpqEKExSWDCu26dRICl8a0t8Kau5hnd0im L//71Bg5vuSecE/k1SWeUKvkpOyjJkG7z+rE5HUSnvKe5l0ADJo0tWSEuu2TOxgok7 KDbJBDbNEZdUw== Date: Wed, 01 Apr 2026 23:52:42 +0200 Message-ID: <20260401201348.964593116@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: x86@kernel.org, Michael Kelley , Dmitry Ilvokhin , Radu Rendec , Jan Kiszka , Kieran Bingham , Florian Fainelli , Marc Zyngier Subject: [patch V5 14/15] genirq/proc: Runtime size the chip name References: <20260401195625.213446764@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 From: Thomas Gleixner The chip name column in the /proc/interrupt output is 8 characters and right aligned, which causes visual clutter due to the fixed length and the alignment. Many interrupt chips, e.g. PCI/MSI[X] have way longer names. Update the length when a chip is assigned to an interrupt and utilize this information for the output. Align it left so all chip names start at the begin of the column. Update the GDB script as well. Signed-off-by: Thomas Gleixner Reviewed-by: Dmitry Ilvokhin --- V3: New patch --- kernel/irq/chip.c | 6 ++++-- kernel/irq/internals.h | 8 ++------ kernel/irq/irqdomain.c | 3 +++ kernel/irq/proc.c | 33 ++++++++++++++++++++++++++++----- kernel/irq/proc.h | 9 +++++++++ scripts/gdb/linux/interrupts.py | 25 ++++++++++++++++--------- 6 files changed, 62 insertions(+), 22 deletions(-) --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -46,9 +46,11 @@ int irq_set_chip(unsigned int irq, const scoped_irqdesc->irq_data.chip = (struct irq_chip *)(chip ?: &no_irq_chip); ret = 0; } - /* For !CONFIG_SPARSE_IRQ make the irq show up in allocated_irqs. */ - if (!ret) + if (!ret) { + /* For !CONFIG_SPARSE_IRQ make the irq show up in allocated_irqs. */ irq_mark_irq(irq); + irq_proc_update_chip(chip); + } return ret; } EXPORT_SYMBOL(irq_set_chip); --- a/kernel/irq/internals.h +++ b/kernel/irq/internals.h @@ -12,6 +12,8 @@ #include #include +#include "proc.h" + #ifdef CONFIG_SPARSE_IRQ # define MAX_SPARSE_IRQS INT_MAX #else @@ -149,12 +151,6 @@ static inline void unregister_handler_pr static inline void irq_proc_update_valid(struct irq_desc *desc) { } #endif -#if defined(CONFIG_PROC_FS) && defined(CONFIG_GENERIC_IRQ_SHOW) -void irq_proc_calc_prec(void); -#else -static inline void irq_proc_calc_prec(void) { } -#endif - struct irq_desc *irq_find_desc_at_or_after(unsigned int offset); extern bool irq_can_set_affinity_usr(unsigned int irq); --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -20,6 +20,8 @@ #include #include +#include "proc.h" + static LIST_HEAD(irq_domain_list); static DEFINE_MUTEX(irq_domain_mutex); @@ -1532,6 +1534,7 @@ int irq_domain_set_hwirq_and_chip(struct irq_data->chip = (struct irq_chip *)(chip ? chip : &no_irq_chip); irq_data->chip_data = chip_data; + irq_proc_update_chip(chip); return 0; } EXPORT_SYMBOL_GPL(irq_domain_set_hwirq_and_chip); --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -456,10 +456,14 @@ int __weak arch_show_interrupts(struct s return 0; } +static DEFINE_RAW_SPINLOCK(irq_proc_constraints_lock); + static struct irq_proc_constraints { unsigned int num_prec; + unsigned int chip_width; } irq_proc_constraints __read_mostly = { .num_prec = 3, + .chip_width = 8, }; #ifndef ACTUAL_NR_IRQS @@ -472,7 +476,23 @@ void irq_proc_calc_prec(void) for (prec = 3, n = 1000; prec < 10 && n <= total_nr_irqs; ++prec) n *= 10; - WRITE_ONCE(irq_proc_constraints.num_prec, prec); + + guard(raw_spinlock_irqsave)(&irq_proc_constraints_lock); + if (prec > irq_proc_constraints.num_prec) + WRITE_ONCE(irq_proc_constraints.num_prec, prec); +} + +void irq_proc_update_chip(const struct irq_chip *chip) +{ + unsigned int len = chip && chip->name ? strlen(chip->name) : 0; + + if (!len || len <= READ_ONCE(irq_proc_constraints.chip_width)) + return; + + /* Can be invoked from interrupt disabled contexts */ + guard(raw_spinlock_irqsave)(&irq_proc_constraints_lock); + if (len > irq_proc_constraints.chip_width) + WRITE_ONCE(irq_proc_constraints.chip_width, len); } #define ZSTR1 " 0" @@ -513,6 +533,7 @@ void irq_proc_emit_counts(struct seq_fil int show_interrupts(struct seq_file *p, void *v) { + unsigned int chip_width = READ_ONCE(irq_proc_constraints.chip_width); unsigned int prec = READ_ONCE(irq_proc_constraints.num_prec); int i = *(loff_t *) v, j; struct irqaction *action; @@ -548,18 +569,20 @@ int show_interrupts(struct seq_file *p, irq_proc_emit_counts(p, &desc->kstat_irqs->cnt); else irq_proc_emit_zero_counts(p, num_online_cpus()); - seq_putc(p, ' '); + + /* Enforce a visual gap */ + seq_write(p, " ", 2); guard(raw_spinlock_irq)(&desc->lock); if (desc->irq_data.chip) { if (desc->irq_data.chip->irq_print_chip) desc->irq_data.chip->irq_print_chip(&desc->irq_data, p); else if (desc->irq_data.chip->name) - seq_printf(p, "%8s", desc->irq_data.chip->name); + seq_printf(p, "%-*s", chip_width, desc->irq_data.chip->name); else - seq_printf(p, "%8s", "-"); + seq_printf(p, "%-*s", chip_width, "-"); } else { - seq_printf(p, "%8s", "None"); + seq_printf(p, "%-*s", chip_width, "None"); } seq_putc(p, ' '); --- /dev/null +++ b/kernel/irq/proc.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#if defined(CONFIG_PROC_FS) && defined(CONFIG_GENERIC_IRQ_SHOW) +void irq_proc_calc_prec(void); +void irq_proc_update_chip(const struct irq_chip *chip); +#else +static inline void irq_proc_calc_prec(void) { } +static inline void irq_proc_update_chip(const struct irq_chip *chip) { } +#endif --- a/scripts/gdb/linux/interrupts.py +++ b/scripts/gdb/linux/interrupts.py @@ -20,7 +20,7 @@ irq_desc_type = utils.CachedType("struct def irqd_is_level(desc): return desc['irq_data']['common']['state_use_accessors'] & constants.LX_IRQD_LEVEL -def show_irq_desc(prec, irq): +def show_irq_desc(prec, chip_width, irq): text = "" desc = mapletree.mtree_load(gdb.parse_and_eval("&sparse_irqs"), irq) @@ -48,7 +48,7 @@ irq_desc_type = utils.CachedType("struct count = cpus.per_cpu(desc['kstat_irqs'], cpu)['cnt'] else: count = 0 - text += "%10u" % (count) + text += "%10u " % (count) name = "None" if desc['irq_data']['chip']: @@ -58,7 +58,7 @@ irq_desc_type = utils.CachedType("struct else: name = "-" - text += " %8s" % (name) + text += " %-*s" % (chip_width, name) if desc['irq_data']['domain']: text += " %*lu" % (prec, desc['irq_data']['hwirq']) @@ -175,11 +175,18 @@ irq_desc_type = utils.CachedType("struct def invoke(self, arg, from_tty): nr_irqs = gdb.parse_and_eval("total_nr_irqs") - prec = 3 - j = 1000 - while prec < 10 and j <= nr_irqs: - prec += 1 - j *= 10 + constr = utils.gdb_eval_or_none('irq_proc_constraints') + + if constr: + prec = int(constr['num_prec']) + chip_width = int(constr['chip_width']) + else: + prec = 3 + j = 1000 + while prec < 10 and j <= nr_irqs: + prec += 1 + j *= 10 + chip_width = 8 gdb.write("%*s" % (prec + 8, "")) for cpu in cpus.each_online_cpu(): @@ -190,7 +197,7 @@ irq_desc_type = utils.CachedType("struct raise gdb.GdbError("Unable to find the sparse IRQ tree, is CONFIG_SPARSE_IRQ enabled?") for irq in range(nr_irqs): - gdb.write(show_irq_desc(prec, irq)) + gdb.write(show_irq_desc(prec, chip_width, irq)) gdb.write(arch_show_interrupts(prec))