Skip to content

Commit 68775ca

Browse files
Frederic Weisbeckeringomolnar
authored andcommitted
genirq: Prevent early spurious wake-ups of interrupt threads
During initialization, the interrupt thread is created before the interrupt is enabled. The interrupt enablement happens before the actual kthread wake up point. Once the interrupt is enabled the hardware can raise an interrupt and once setup_irq() drops the descriptor lock a interrupt wake-up can happen. Even when such an interrupt can be considered premature, this is not a problem in general because at the point where the descriptor lock is dropped and the wakeup can happen, the data which is used by the thread is fully initialized. Though from the perspective of least surprise, the initial wakeup really should be performed by the setup code and not randomly by a premature interrupt. Prevent this by performing a wake-up only if the target is in state TASK_INTERRUPTIBLE, which the thread uses in wait_for_interrupt(). If the thread is still in state TASK_UNINTERRUPTIBLE, the wake-up is not lost because after the setup code completed the initial wake-up the thread will observe the IRQTF_RUNTHREAD and proceed with the handling. [ tglx: Simplified the changes and extended the changelog. ] Signed-off-by: Frederic Weisbecker <frederic@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://patch.msgid.link/20251121143500.42111-2-frederic@kernel.org
1 parent 9d3faec commit 68775ca

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

kernel/irq/handle.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,15 @@ void __irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
133133
*/
134134
atomic_inc(&desc->threads_active);
135135

136-
wake_up_process(action->thread);
136+
/*
137+
* This might be a premature wakeup before the thread reached the
138+
* thread function and set the IRQTF_READY bit. It's waiting in
139+
* kthread code with state UNINTERRUPTIBLE. Once it reaches the
140+
* thread function it waits with INTERRUPTIBLE. The wakeup is not
141+
* lost in that case because the thread is guaranteed to observe
142+
* the RUN flag before it goes to sleep in wait_for_interrupt().
143+
*/
144+
wake_up_state(action->thread, TASK_INTERRUPTIBLE);
137145
}
138146

139147
static DEFINE_STATIC_KEY_FALSE(irqhandler_duration_check_enabled);

0 commit comments

Comments
 (0)