[PATCH 2/2] wifi: ipw2200: drain IRQ tasklet during teardown

From: Jiale Yao

Date: Wed Oct 28 2026 - 00:58:01 EST


The interrupt handler can queue irq_tasklet just before teardown frees
the IRQ. free_irq() prevents further hard IRQ handlers, but a tasklet
that is already queued can still run while the remove and probe failure
paths release its queues, command log, MMIO mapping, and private data.

Kill the tasklet after freeing the IRQ and before releasing resources it
can access.

Fixes: 43f66a6ce8da ("Add ipw2200 wireless driver.")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Jiale Yao <yaojiale02@xxxxxxx>
---
drivers/net/wireless/intel/ipw2x00/ipw2200.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
index 8249d493ee22..e8112ef3150e 100644
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
@@ -11720,6 +11720,7 @@ static int ipw_pci_probe(struct pci_dev *pdev,
sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
out_release_irq:
free_irq(pdev->irq, priv);
+ tasklet_kill(&priv->irq_tasklet);
out_iounmap:
iounmap(priv->hw_base);
out_pci_release_regions:
@@ -11751,6 +11752,9 @@ static void ipw_pci_remove(struct pci_dev *pdev)

unregister_netdev(priv->net_dev);

+ free_irq(pdev->irq, priv);
+ tasklet_kill(&priv->irq_tasklet);
+
if (priv->rxq) {
ipw_rx_queue_free(priv, priv->rxq);
priv->rxq = NULL;
@@ -11802,7 +11806,6 @@ static void ipw_pci_remove(struct pci_dev *pdev)
ipw_prom_free(priv);
#endif

- free_irq(pdev->irq, priv);
iounmap(priv->hw_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
--
2.34.1