genirq: Allow interrupts to be excluded from /proc/interrupts

A number of architectures implement IPI statistics directly,
duplicating the core kstat_irqs accounting. As we move IPIs to
being actual IRQs, we would end-up with a confusing display
in /proc/interrupts (where the IPIs would appear twice).

In order to solve this, allow interrupts to be flagged as
"hidden", which excludes them from /proc/interrupts.

Reviewed-by: Valentin Schneider <valentin.schneider@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
Marc Zyngier 2020-05-19 14:58:13 +01:00
parent c5e5ec033c
commit 83cfac95c0
4 changed files with 12 additions and 2 deletions

View File

@ -71,6 +71,7 @@ enum irqchip_irq_state;
* it from the spurious interrupt detection * it from the spurious interrupt detection
* mechanism and from core side polling. * mechanism and from core side polling.
* IRQ_DISABLE_UNLAZY - Disable lazy irq disable * IRQ_DISABLE_UNLAZY - Disable lazy irq disable
* IRQ_HIDDEN - Don't show up in /proc/interrupts
*/ */
enum { enum {
IRQ_TYPE_NONE = 0x00000000, IRQ_TYPE_NONE = 0x00000000,
@ -97,13 +98,14 @@ enum {
IRQ_PER_CPU_DEVID = (1 << 17), IRQ_PER_CPU_DEVID = (1 << 17),
IRQ_IS_POLLED = (1 << 18), IRQ_IS_POLLED = (1 << 18),
IRQ_DISABLE_UNLAZY = (1 << 19), IRQ_DISABLE_UNLAZY = (1 << 19),
IRQ_HIDDEN = (1 << 20),
}; };
#define IRQF_MODIFY_MASK \ #define IRQF_MODIFY_MASK \
(IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \ (IRQ_TYPE_SENSE_MASK | IRQ_NOPROBE | IRQ_NOREQUEST | \
IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \ IRQ_NOAUTOEN | IRQ_MOVE_PCNTXT | IRQ_LEVEL | IRQ_NO_BALANCING | \
IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID | \ IRQ_PER_CPU | IRQ_NESTED_THREAD | IRQ_NOTHREAD | IRQ_PER_CPU_DEVID | \
IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY) IRQ_IS_POLLED | IRQ_DISABLE_UNLAZY | IRQ_HIDDEN)
#define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING) #define IRQ_NO_BALANCING_MASK (IRQ_PER_CPU | IRQ_NO_BALANCING)

View File

@ -136,6 +136,7 @@ static const struct irq_bit_descr irqdesc_states[] = {
BIT_MASK_DESCR(_IRQ_PER_CPU_DEVID), BIT_MASK_DESCR(_IRQ_PER_CPU_DEVID),
BIT_MASK_DESCR(_IRQ_IS_POLLED), BIT_MASK_DESCR(_IRQ_IS_POLLED),
BIT_MASK_DESCR(_IRQ_DISABLE_UNLAZY), BIT_MASK_DESCR(_IRQ_DISABLE_UNLAZY),
BIT_MASK_DESCR(_IRQ_HIDDEN),
}; };
static const struct irq_bit_descr irqdesc_istates[] = { static const struct irq_bit_descr irqdesc_istates[] = {

View File

@ -485,7 +485,7 @@ int show_interrupts(struct seq_file *p, void *v)
rcu_read_lock(); rcu_read_lock();
desc = irq_to_desc(i); desc = irq_to_desc(i);
if (!desc) if (!desc || irq_settings_is_hidden(desc))
goto outsparse; goto outsparse;
if (desc->kstat_irqs) if (desc->kstat_irqs)

View File

@ -17,6 +17,7 @@ enum {
_IRQ_PER_CPU_DEVID = IRQ_PER_CPU_DEVID, _IRQ_PER_CPU_DEVID = IRQ_PER_CPU_DEVID,
_IRQ_IS_POLLED = IRQ_IS_POLLED, _IRQ_IS_POLLED = IRQ_IS_POLLED,
_IRQ_DISABLE_UNLAZY = IRQ_DISABLE_UNLAZY, _IRQ_DISABLE_UNLAZY = IRQ_DISABLE_UNLAZY,
_IRQ_HIDDEN = IRQ_HIDDEN,
_IRQF_MODIFY_MASK = IRQF_MODIFY_MASK, _IRQF_MODIFY_MASK = IRQF_MODIFY_MASK,
}; };
@ -31,6 +32,7 @@ enum {
#define IRQ_PER_CPU_DEVID GOT_YOU_MORON #define IRQ_PER_CPU_DEVID GOT_YOU_MORON
#define IRQ_IS_POLLED GOT_YOU_MORON #define IRQ_IS_POLLED GOT_YOU_MORON
#define IRQ_DISABLE_UNLAZY GOT_YOU_MORON #define IRQ_DISABLE_UNLAZY GOT_YOU_MORON
#define IRQ_HIDDEN GOT_YOU_MORON
#undef IRQF_MODIFY_MASK #undef IRQF_MODIFY_MASK
#define IRQF_MODIFY_MASK GOT_YOU_MORON #define IRQF_MODIFY_MASK GOT_YOU_MORON
@ -167,3 +169,8 @@ static inline void irq_settings_clr_disable_unlazy(struct irq_desc *desc)
{ {
desc->status_use_accessors &= ~_IRQ_DISABLE_UNLAZY; desc->status_use_accessors &= ~_IRQ_DISABLE_UNLAZY;
} }
static inline bool irq_settings_is_hidden(struct irq_desc *desc)
{
return desc->status_use_accessors & _IRQ_HIDDEN;
}