mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
net: ibm: emac: mal: fix NAPI locking
Since commit413f0271f3("net: protect NAPI enablement with netdev_lock()"), napi_enable() and napi_disable() take netdev_lock(). mal_register_commac() and mal_unregister_commac() call these helpers while holding mal->lock with interrupts disabled. In the unregister path, napi_disable() may also wait for polling to finish, while the poll completion path takes mal->lock. Take netdev_lock() before mal->lock, use the locked NAPI helpers, and drop mal->lock before napi_disable_locked(). Fixes:413f0271f3("net: protect NAPI enablement with netdev_lock()") Cc: stable@vger.kernel.org Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20260811070813.377573-1-runyu.xiao@seu.edu.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
a22054d743
commit
43b0213529
|
|
@ -35,6 +35,7 @@ int mal_register_commac(struct mal_instance *mal, struct mal_commac *commac)
|
|||
{
|
||||
unsigned long flags;
|
||||
|
||||
netdev_lock(mal->napi.dev);
|
||||
spin_lock_irqsave(&mal->lock, flags);
|
||||
|
||||
MAL_DBG(mal, "reg(%08x, %08x)" NL,
|
||||
|
|
@ -44,18 +45,20 @@ int mal_register_commac(struct mal_instance *mal, struct mal_commac *commac)
|
|||
if ((mal->tx_chan_mask & commac->tx_chan_mask) ||
|
||||
(mal->rx_chan_mask & commac->rx_chan_mask)) {
|
||||
spin_unlock_irqrestore(&mal->lock, flags);
|
||||
netdev_unlock(mal->napi.dev);
|
||||
printk(KERN_WARNING "mal%d: COMMAC channels conflict!\n",
|
||||
mal->index);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (list_empty(&mal->list))
|
||||
napi_enable(&mal->napi);
|
||||
napi_enable_locked(&mal->napi);
|
||||
mal->tx_chan_mask |= commac->tx_chan_mask;
|
||||
mal->rx_chan_mask |= commac->rx_chan_mask;
|
||||
list_add(&commac->list, &mal->list);
|
||||
|
||||
spin_unlock_irqrestore(&mal->lock, flags);
|
||||
netdev_unlock(mal->napi.dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -64,7 +67,9 @@ void mal_unregister_commac(struct mal_instance *mal,
|
|||
struct mal_commac *commac)
|
||||
{
|
||||
unsigned long flags;
|
||||
bool disable_napi;
|
||||
|
||||
netdev_lock(mal->napi.dev);
|
||||
spin_lock_irqsave(&mal->lock, flags);
|
||||
|
||||
MAL_DBG(mal, "unreg(%08x, %08x)" NL,
|
||||
|
|
@ -73,10 +78,12 @@ void mal_unregister_commac(struct mal_instance *mal,
|
|||
mal->tx_chan_mask &= ~commac->tx_chan_mask;
|
||||
mal->rx_chan_mask &= ~commac->rx_chan_mask;
|
||||
list_del_init(&commac->list);
|
||||
if (list_empty(&mal->list))
|
||||
napi_disable(&mal->napi);
|
||||
disable_napi = list_empty(&mal->list);
|
||||
|
||||
spin_unlock_irqrestore(&mal->lock, flags);
|
||||
if (disable_napi)
|
||||
napi_disable_locked(&mal->napi);
|
||||
netdev_unlock(mal->napi.dev);
|
||||
}
|
||||
|
||||
int mal_set_rcbs(struct mal_instance *mal, int channel, unsigned long size)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user