]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
genirq: Add a IRQF_NO_DEBUG flag
authorThomas Gleixner <tglx@linutronix.de>
Fri, 2 Apr 2021 06:23:25 +0000 (08:23 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Mon, 17 May 2021 18:01:35 +0000 (20:01 +0200)
The whole call to note_interrupt() can be avoided or return early when
interrupts would be marked accordingly. For IPI handlers which always
return HANDLED the whole procedure is pretty pointless to begin with.

Add a IRQF_NO_DEBUG flag and mark the interrupt accordingly if supplied
when the interrupt is requested.

When noirqdebug is set on the kernel commandline, then the interrupt is
marked unconditionally so that there is only one condition in the hotpath
to evaluate.

 [ clg: Add changelog ]

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/7a8ad02f-63a8-c1aa-fdd1-39d973593d02@kaod.org
include/linux/interrupt.h
include/linux/irq.h
kernel/irq/chip.c
kernel/irq/handle.c
kernel/irq/manage.c
kernel/irq/settings.h

index 4777850a6dc7cdafdaabc95dbac8746559e92094..a52109c3f3a4784813d551854a74cd401fff1394 100644 (file)
@@ -64,6 +64,8 @@
  * IRQF_NO_AUTOEN - Don't enable IRQ or NMI automatically when users request it.
  *                Users will enable it explicitly by enable_irq() or enable_nmi()
  *                later.
+ * IRQF_NO_DEBUG - Exclude from runnaway detection for IPI and similar handlers,
+ *                depends on IRQF_PERCPU.
  */
 #define IRQF_SHARED            0x00000080
 #define IRQF_PROBE_SHARED      0x00000100
@@ -78,6 +80,7 @@
 #define IRQF_EARLY_RESUME      0x00020000
 #define IRQF_COND_SUSPEND      0x00040000
 #define IRQF_NO_AUTOEN         0x00080000
+#define IRQF_NO_DEBUG          0x00100000
 
 #define IRQF_TIMER             (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)
 
index 31b347c9f8dd01300dfd02cd7662d40c514e7e5d..8e9a9ae471a6e462f4919b813e8a389b8e45bc2e 100644 (file)
@@ -72,6 +72,7 @@ enum irqchip_irq_state;
  *                               mechanism and from core side polling.
  * IRQ_DISABLE_UNLAZY          - Disable lazy irq disable
  * IRQ_HIDDEN                  - Don't show up in /proc/interrupts
+ * IRQ_NO_DEBUG                        - Exclude from note_interrupt() debugging
  */
 enum {
        IRQ_TYPE_NONE           = 0x00000000,
@@ -99,6 +100,7 @@ enum {
        IRQ_IS_POLLED           = (1 << 18),
        IRQ_DISABLE_UNLAZY      = (1 << 19),
        IRQ_HIDDEN              = (1 << 20),
+       IRQ_NO_DEBUG            = (1 << 21),
 };
 
 #define IRQF_MODIFY_MASK       \
index 8cc8e571328704f8dcab22c63da7cf7a5b6f4f45..7f04c7d8296e209423a14f03aa2267b46b12c22a 100644 (file)
@@ -481,7 +481,7 @@ void handle_nested_irq(unsigned int irq)
        for_each_action_of_desc(desc, action)
                action_ret |= action->thread_fn(action->irq, action->dev_id);
 
-       if (!noirqdebug)
+       if (!irq_settings_no_debug(desc))
                note_interrupt(desc, action_ret);
 
        raw_spin_lock_irq(&desc->lock);
index 762a928e18f925074ce9e57672f79c91761d5819..221d80c31e94ccfcb77fb13cdca6ac08fa3b393f 100644 (file)
@@ -197,7 +197,7 @@ irqreturn_t handle_irq_event_percpu(struct irq_desc *desc)
 
        add_interrupt_randomness(desc->irq_data.irq, flags);
 
-       if (!noirqdebug)
+       if (!irq_settings_no_debug(desc))
                note_interrupt(desc, retval);
        return retval;
 }
index 4c14356543d93bc394c12fbee9aee4418dafeed8..7bdd09e7d5f042a83ded96f41f6bdb61e596227b 100644 (file)
@@ -1686,8 +1686,13 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
                if (new->flags & IRQF_PERCPU) {
                        irqd_set(&desc->irq_data, IRQD_PER_CPU);
                        irq_settings_set_per_cpu(desc);
+                       if (new->flags & IRQF_NO_DEBUG)
+                               irq_settings_set_no_debug(desc);
                }
 
+               if (noirqdebug)
+                       irq_settings_set_no_debug(desc);
+
                if (new->flags & IRQF_ONESHOT)
                        desc->istate |= IRQS_ONESHOT;
 
index 403378b9947b9111ec8a5d55856a569047a744e5..7b7efb1a114bd8132e45409fcc99c7a10492b5e6 100644 (file)
@@ -18,6 +18,7 @@ enum {
        _IRQ_IS_POLLED          = IRQ_IS_POLLED,
        _IRQ_DISABLE_UNLAZY     = IRQ_DISABLE_UNLAZY,
        _IRQ_HIDDEN             = IRQ_HIDDEN,
+       _IRQ_NO_DEBUG           = IRQ_NO_DEBUG,
        _IRQF_MODIFY_MASK       = IRQF_MODIFY_MASK,
 };
 
@@ -33,6 +34,7 @@ enum {
 #define IRQ_IS_POLLED          GOT_YOU_MORON
 #define IRQ_DISABLE_UNLAZY     GOT_YOU_MORON
 #define IRQ_HIDDEN             GOT_YOU_MORON
+#define IRQ_NO_DEBUG           GOT_YOU_MORON
 #undef IRQF_MODIFY_MASK
 #define IRQF_MODIFY_MASK       GOT_YOU_MORON
 
@@ -174,3 +176,13 @@ static inline bool irq_settings_is_hidden(struct irq_desc *desc)
 {
        return desc->status_use_accessors & _IRQ_HIDDEN;
 }
+
+static inline void irq_settings_set_no_debug(struct irq_desc *desc)
+{
+       desc->status_use_accessors |= _IRQ_NO_DEBUG;
+}
+
+static inline bool irq_settings_no_debug(struct irq_desc *desc)
+{
+       return desc->status_use_accessors & _IRQ_NO_DEBUG;
+}