]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: au1000: move free_irq out of the close-time spinlocked section
authorRunyu Xiao <runyu.xiao@seu.edu.cn>
Fri, 19 Jun 2026 15:18:16 +0000 (23:18 +0800)
committerJakub Kicinski <kuba@kernel.org>
Wed, 24 Jun 2026 02:10:29 +0000 (19:10 -0700)
au1000_close() calls free_irq() while aup->lock is still held with
spin_lock_irqsave(). free_irq() can sleep because it takes the IRQ
descriptor request mutex, so it does not belong inside the close-time
spinlocked section.

This was found by our static analysis tool and then confirmed by manual
review of the in-tree au1000_close() .ndo_stop path. The reviewed path
keeps aup->lock held across the MAC reset, queue stop and
free_irq(dev->irq, dev).

A directed runtime validation kept that ndo_stop carrier and the same
free_irq(dev->irq, dev) operation under the driver lock. Lockdep reported
"BUG: sleeping function called from invalid context" and "Invalid wait
context" while free_irq() was taking desc->request_mutex, with
au1000_close() and free_irq() on the stack.

Drop aup->lock before freeing the IRQ. The protected close-time work still
stops the device and queue before IRQ teardown, but the sleepable IRQ core
path now runs outside the spinlocked section.

Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260619151816.1144289-1-runyu.xiao@seu.edu.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/amd/au1000_eth.c

index 9d35ac348ebe321a6ccfa5129d2d1511764f6445..5a04056e38fa391bf277aeab0300e1c17f4c47c4 100644 (file)
@@ -943,9 +943,10 @@ static int au1000_close(struct net_device *dev)
        /* stop the device */
        netif_stop_queue(dev);
 
+       spin_unlock_irqrestore(&aup->lock, flags);
+
        /* disable the interrupt */
        free_irq(dev->irq, dev);
-       spin_unlock_irqrestore(&aup->lock, flags);
 
        return 0;
 }