Re: [PATCH] watchdog: wdt_pci: Fix shared IRQ storm and complete system lockup
From: Guenter Roeck
Date: Sat May 09 2026 - 09:52:31 EST
On 5/9/26 05:16, w15303746062@xxxxxxx wrote:
From: Mingyu Wang <25181214217@xxxxxxxxxxxxxxxxx>
The wdt_pci driver registers its interrupt handler with the IRQF_SHARED
flag. However, the interrupt handler wdtpci_interrupt() fails to check
whether the interrupt actually originated from the watchdog device.
If another device on the same shared IRQ line (e.g., an I2C controller)
triggers an interrupt, wdtpci_interrupt() will erroneously process it,
blindly log hardware status (e.g., "Reset in 5ms") to the console, and
unconditionally return IRQ_HANDLED.
This behavior defeats the kernel's spurious interrupt detector. Under
heavy load from other devices sharing the IRQ, it causes a severe printk
storm and keeps the CPU trapped in hard IRQ context. This eventually
leads to a complete system lockup and RCU/Hung Task panics.
Fix this by checking the WDC_SR_IRQ bit (which is active low) in the
status register. If the bit is high, the interrupt is not ours, and we
must release the lock and return IRQ_NONE immediately.
Signed-off-by: Mingyu Wang <25181214217@xxxxxxxxxxxxxxxxx>
Is this an actual observed problem ? Are you using this driver ?
Did you confirm that the change solves the problem, and that the
newly checked register bit is indeed active low as claimed ?
If so, please provide evidence that the problem is observed.
If not, please refrain from making such changes. This driver,
specifically, is completely outdated, the hardware it supports
is very unlikely to still be used, and making such changes without
actual need serves no practical purpose but to keep maintainers busy.
Thanks,
Guenter
---
drivers/watchdog/wdt_pci.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index 3918a600f2a0..a35ac064b690 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -304,6 +304,17 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id)
spin_lock(&wdtpci_lock);
status = inb(WDT_SR);
+ /*
+ * The WDT500/501 supports shared interrupts (IRQF_SHARED).
+ * We must check if the interrupt was generated by this device.
+ * WDC_SR_IRQ is active low, so if it is set (1), the interrupt
+ * belongs to another device on the shared line.
+ */
+ if (status & WDC_SR_IRQ) {
+ spin_unlock(&wdtpci_lock);
+ return IRQ_NONE;
+ }
+
udelay(8);
pr_crit("status %d\n", status);