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 BA8423CB2C1 for ; Tue, 31 Mar 2026 07:26:38 +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=1774941998; cv=none; b=PJ7S9AB+UbDLb8spp2Y32rdLo5XHxwzAjXHGpoAWyU+aUoav8sKPZNxLIT8Xz36FqeN4OzlD+0IVjosMDGFKbhMIwOGjJmzAafmQrhjSdh+lTHqtnD2l9fT2TSuxhYrWI01zOQfC5UStB9HibSsuPc44s5kRR6ihxdAWBmzcJqg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774941998; c=relaxed/simple; bh=n8QsHiTQzv25MN0pTa/gdMrhZR3Hzt7NluoTpNWg/yw=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=AedGoKJG++bFLnXI01fnyxW15yuQgfXmuzwyqwpbtLVRIH8oBfrZczNBUMGXRtgmzo1YzUWg+NM+a4jC+7s1KQHjTbV0VdtAUBgsno5zdMPG5CjjPCwyla13LWmfHdUNMUFjWmIbnW1Gp7nPgxxRC7zHyaxmd1FBoeLunrmvSRk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=elvX0hbf; 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="elvX0hbf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id EAEDDC19423; Tue, 31 Mar 2026 07:26:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1774941998; bh=n8QsHiTQzv25MN0pTa/gdMrhZR3Hzt7NluoTpNWg/yw=; h=Date:From:To:Cc:Subject:References:From; b=elvX0hbfLaHvzuMEMjt5VMecv9zGEHRErP546H490cacTuhXpWwSYsa10/Md9T/Bx Qk9sULwym56Kfj73qiPlWKMtG5fDEW7jeS8K1oCgQkp6vBYbdtPXQgrxHfEqwip/+z ZxbzjzMgsJGz+iy5GLEt0af0YP/bKsGRZ8547YJewLPQ3+t2Fj/RpQCpGhYGtj0+mR +OiqcNU+QxKbeTB6HFDtJR4864CeRfdD7qV/oAPyUNagdXzQtZEFdHZ2By/MTziB4O oINDJpjgtw/LJr3XyQjBCAYty7QWL1Lte0PsBgecZufATF4g8mJmpBtikycBb92BHz Wvh2iDyhGMxDg== Date: Tue, 31 Mar 2026 09:26:35 +0200 Message-ID: <20260331072419.483417758@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 V4 14/15] genirq/proc: Runtime size the chip name References: <20260331071453.172185305@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 --- 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))