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 ADF5726CE11 for ; Mon, 23 Mar 2026 20:59:04 +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=1774299546; cv=none; b=Py+5sSpuCJsW+kflsjxOHhLzuVj04qXHWfC6jHC3umlaIrVLykBkc0I1qq0D9aWXEVnPO5UPWjC7GYGg2FoWzPuLrEwjWm0bnDeWjZ0XhL5ciSoW98ypxc1ltBm4E1xXB4kenfE35wF2f5uEus3XoIgPc/RgjSBCRiVrmx6CNZQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774299546; c=relaxed/simple; bh=cMQXqhWu2RrjMkD7cMsBUSLhKHAQlAd1M9+JtDPJ+rY=; h=Message-ID:Subject:From:To:Cc:Date:In-Reply-To:References: Content-Type:MIME-Version; b=pJjX9JoO8CaPtlk3feeb06QN0LF8uPm86H57PhPylV7L6xCHcmURPiGQJ9SPN9ub2oFACzmuhlk6UXAr2vGU7vDQROWMa5X3+8tlvAeAenO7gbgEDICTWHcKmfQuE2eUTcA70WLXfin4hvlu9J0TNZjM02bmPTnJ+3Fxfrwh7Zs= 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=H59FHiPF; 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="H59FHiPF" 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 C8CD2C244F; Mon, 23 Mar 2026 22:58:55 +0200 (EET) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.mindbit.ro C8CD2C244F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rendec.net; s=default; t=1774299536; bh=hAA2lZ7x9dHIDG5CUlS6wmtVRC6pDhO9BM/PdNv88l8=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=H59FHiPFmqYTY0vZS1fj/QHxNgQtBY/7xLhgYSCQAlWxprFkoNwyBwmh2SpYd065d xwqIc+g6YX3P7RYEo/oVXGhixSaidhPOhujOAnF2szWAodOzoB3Q03AAVzD/xmg3zR rzEMINXDh/4GbH3vSwhbPnDAePioOp4ubsv9MhVuGaYBw1CQcr3RwA7+cSkVzZt4tV te0BEl8VbfVx50vI0eu9nSxsb2Zm8FQurH6cMGbRWif9eLaKzLTTz94Bcz+o2OhzT7 KF64xRAf20dw7YSNJXfBlgFKpRDFRuia3JqLKqHYP3vdT/J54xr+tvZDlrBihiqLdo TGz7o+riv7qqQ== Message-ID: <7d0dcf3dc90152a71de920dd22cc5eed57bab695.camel@rendec.net> Subject: Re: [patch v2 06/14] genirq: Cache the condition for /proc/interrupts exposure From: Radu Rendec To: Thomas Gleixner , LKML Cc: x86@kernel.org, Dmitry Ilvokhin , Neil Horman Date: Mon, 23 Mar 2026 16:58:54 -0400 In-Reply-To: <20260320132102.431714412@kernel.org> References: <20260320131108.344376329@kernel.org> <20260320132102.431714412@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 Fri, 2026-03-20 at 14:21 +0100, Thomas Gleixner wrote: > show_interrupts() evaluates a boatload of conditions to establish whether > exposing an interrupt in /proc/interrupts or not. >=20 > That can be simplified by caching the condition in an internal status fla= g, > which is updated when one of the relevant inputs changes. >=20 > As a result the number of instructions and branches for reading > /proc/interrupts is reduced significantly. >=20 > Signed-off-by: Thomas Gleixner > Reviewed-by: Dmitry Ilvokhin > --- > V2: s/IRQF_/IRQ/ and fixup the enum treatment - Dmitry > --- > =C2=A0include/linux/irq.h=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 1 + > =C2=A0kernel/irq/chip.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0= 2 ++ > =C2=A0kernel/irq/internals.h |=C2=A0=C2=A0=C2=A0 2 ++ > =C2=A0kernel/irq/manage.c=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0=C2=A0 2 ++ > =C2=A0kernel/irq/proc.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0=C2=A0 16 ++= ++++++++++---- > =C2=A0kernel/irq/settings.h=C2=A0 |=C2=A0=C2=A0 13 +++++++++++++ > =C2=A06 files changed, 32 insertions(+), 4 deletions(-) >=20 > --- a/include/linux/irq.h > +++ b/include/linux/irq.h > @@ -99,6 +99,7 @@ enum { > =C2=A0 IRQ_DISABLE_UNLAZY =3D (1 << 19), > =C2=A0 IRQ_HIDDEN =3D (1 << 20), > =C2=A0 IRQ_NO_DEBUG =3D (1 << 21), > + IRQ_RESERVED =3D (1 << 22), > =C2=A0}; > =C2=A0 > =C2=A0#define IRQF_MODIFY_MASK \ > --- a/kernel/irq/chip.c > +++ b/kernel/irq/chip.c > @@ -1004,6 +1004,7 @@ static void > =C2=A0 WARN_ON(irq_chip_pm_get(irq_desc_get_irq_data(desc))); > =C2=A0 irq_activate_and_startup(desc, IRQ_RESEND); > =C2=A0 } > + irq_proc_update_valid(desc); > =C2=A0} > =C2=A0 > =C2=A0void __irq_set_handler(unsigned int irq, irq_flow_handler_t handle,= int is_chained, > @@ -1064,6 +1065,7 @@ void irq_modify_status(unsigned int irq, > =C2=A0 trigger =3D tmp; > =C2=A0 > =C2=A0 irqd_set(&desc->irq_data, trigger); > + irq_proc_update_valid(desc); > =C2=A0 } > =C2=A0} > =C2=A0EXPORT_SYMBOL_GPL(irq_modify_status); > --- a/kernel/irq/internals.h > +++ b/kernel/irq/internals.h > @@ -123,6 +123,7 @@ extern void register_irq_proc(unsigned i > =C2=A0extern void unregister_irq_proc(unsigned int irq, struct irq_desc *= desc); > =C2=A0extern void register_handler_proc(unsigned int irq, struct irqactio= n *action); > =C2=A0extern void unregister_handler_proc(unsigned int irq, struct irqact= ion *action); > +void irq_proc_update_valid(struct irq_desc *desc); > =C2=A0#else > =C2=A0static inline void register_irq_proc(unsigned int irq, struct irq_d= esc *desc) { } > =C2=A0static inline void unregister_irq_proc(unsigned int irq, struct irq= _desc *desc) { } > @@ -130,6 +131,7 @@ static inline void register_handler_proc > =C2=A0 struct irqaction *action) { } > =C2=A0static inline void unregister_handler_proc(unsigned int irq, > =C2=A0 =C2=A0=C2=A0 struct irqaction *action) { } > +static inline void irq_proc_update_valid(struct irq_desc *desc) { } > =C2=A0#endif > =C2=A0 > =C2=A0extern bool irq_can_set_affinity_usr(unsigned int irq); > --- a/kernel/irq/manage.c > +++ b/kernel/irq/manage.c > @@ -1802,6 +1802,7 @@ static int > =C2=A0 __enable_irq(desc); > =C2=A0 } > =C2=A0 > + irq_proc_update_valid(desc); > =C2=A0 raw_spin_unlock_irqrestore(&desc->lock, flags); > =C2=A0 chip_bus_sync_unlock(desc); > =C2=A0 mutex_unlock(&desc->request_mutex); > @@ -1906,6 +1907,7 @@ static struct irqaction *__free_irq(stru > =C2=A0 desc->affinity_hint =3D NULL; > =C2=A0#endif > =C2=A0 > + irq_proc_update_valid(desc); > =C2=A0 raw_spin_unlock_irqrestore(&desc->lock, flags); > =C2=A0 /* > =C2=A0 * Drop bus_lock here so the changes which were done in the chip > --- a/kernel/irq/proc.c > +++ b/kernel/irq/proc.c > @@ -439,6 +439,17 @@ void init_irq_proc(void) > =C2=A0 register_irq_proc(irq, desc); > =C2=A0} > =C2=A0 > +void irq_proc_update_valid(struct irq_desc *desc) > +{ > + u32 set =3D _IRQ_PROC_VALID; > + > + if (irq_settings_is_hidden(desc) || !desc->action || > + =C2=A0=C2=A0=C2=A0 irq_desc_is_chained(desc) || !desc->kstat_irqs) Can desc->kstat_irqs ever be NULL? Looking at kernel/irq/irqdesc.c, it seems to me that it's allocated always and very early (before every other field in struct irq_desc), and with an explicit check for NULL on allocation. It's also deallocated late, right before struct irq_desc itself is deallocated (in irq_kobj_release()). Other than that, LGTM. > + set =3D 0; > + > + irq_settings_update_proc_valid(desc, set); > +} > + > =C2=A0#ifdef CONFIG_GENERIC_IRQ_SHOW > =C2=A0 > =C2=A0int __weak arch_show_interrupts(struct seq_file *p, int prec) > @@ -514,10 +525,7 @@ int show_interrupts(struct seq_file *p, > =C2=A0 > =C2=A0 guard(rcu)(); > =C2=A0 desc =3D irq_to_desc(i); > - if (!desc || irq_settings_is_hidden(desc)) > - return 0; > - > - if (!desc->action || irq_desc_is_chained(desc) || !desc->kstat_irqs) > + if (!desc || !irq_settings_proc_valid(desc)) > =C2=A0 return 0; > =C2=A0 > =C2=A0 seq_printf(p, "%*d:", prec, i); > --- a/kernel/irq/settings.h > +++ b/kernel/irq/settings.h > @@ -18,6 +18,7 @@ enum { > =C2=A0 _IRQ_DISABLE_UNLAZY =3D IRQ_DISABLE_UNLAZY, > =C2=A0 _IRQ_HIDDEN =3D IRQ_HIDDEN, > =C2=A0 _IRQ_NO_DEBUG =3D IRQ_NO_DEBUG, > + _IRQ_PROC_VALID =3D IRQ_RESERVED, > =C2=A0 _IRQF_MODIFY_MASK =3D IRQF_MODIFY_MASK, > =C2=A0}; > =C2=A0 > @@ -34,6 +35,7 @@ enum { > =C2=A0#define IRQ_DISABLE_UNLAZY GOT_YOU_MORON > =C2=A0#define IRQ_HIDDEN GOT_YOU_MORON > =C2=A0#define IRQ_NO_DEBUG GOT_YOU_MORON > +#define IRQ_RESERVED GOT_YOU_MORON > =C2=A0#undef IRQF_MODIFY_MASK > =C2=A0#define IRQF_MODIFY_MASK GOT_YOU_MORON > =C2=A0 > @@ -180,3 +182,14 @@ static inline bool irq_settings_no_debug > =C2=A0{ > =C2=A0 return desc->status_use_accessors & _IRQ_NO_DEBUG; > =C2=A0} > + > +static inline bool irq_settings_proc_valid(struct irq_desc *desc) > +{ > + return desc->status_use_accessors & _IRQ_PROC_VALID; > +} > + > +static inline void irq_settings_update_proc_valid(struct irq_desc *desc,= u32 set) > +{ > + desc->status_use_accessors &=3D ~_IRQ_PROC_VALID; > + desc->status_use_accessors |=3D (set & _IRQ_PROC_VALID); > +}