mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-15 22:31:47 -04:00
net: net_failover: Fix the deadlock in slave register
There is netdev_lock_ops() before the NETDEV_REGISTER notifier
in register_netdevice(), so use the non-locking functions
in net_failover_slave_register().
failover_slave_register() in failover_existing_slave_register() adds lock
and unlock ops too.
Call Trace:
<TASK>
__schedule+0x30d/0x7a0
schedule+0x27/0x90
schedule_preempt_disabled+0x15/0x30
__mutex_lock.constprop.0+0x538/0x9e0
__mutex_lock_slowpath+0x13/0x20
mutex_lock+0x3b/0x50
dev_set_mtu+0x40/0xe0
net_failover_slave_register+0x24/0x280
failover_slave_register+0x103/0x1b0
failover_event+0x15e/0x210
? dropmon_net_event+0xac/0xe0
notifier_call_chain+0x5e/0xe0
raw_notifier_call_chain+0x16/0x30
call_netdevice_notifiers_info+0x52/0xa0
register_netdevice+0x5f4/0x7c0
register_netdev+0x1e/0x40
_mlx5e_probe+0xe2/0x370 [mlx5_core]
mlx5e_probe+0x59/0x70 [mlx5_core]
? __pfx_mlx5e_probe+0x10/0x10 [mlx5_core]
Fixes: 4c975fd700 ("net: hold instance lock during NETDEV_REGISTER/UP")
Signed-off-by: Faicker Mo <faicker.mo@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
9a390d34d5
commit
b84c5632c7
@@ -502,7 +502,7 @@ static int net_failover_slave_register(struct net_device *slave_dev,
|
||||
|
||||
/* Align MTU of slave with failover dev */
|
||||
orig_mtu = slave_dev->mtu;
|
||||
err = dev_set_mtu(slave_dev, failover_dev->mtu);
|
||||
err = netif_set_mtu(slave_dev, failover_dev->mtu);
|
||||
if (err) {
|
||||
netdev_err(failover_dev, "unable to change mtu of %s to %u register failed\n",
|
||||
slave_dev->name, failover_dev->mtu);
|
||||
@@ -512,11 +512,11 @@ static int net_failover_slave_register(struct net_device *slave_dev,
|
||||
dev_hold(slave_dev);
|
||||
|
||||
if (netif_running(failover_dev)) {
|
||||
err = dev_open(slave_dev, NULL);
|
||||
err = netif_open(slave_dev, NULL);
|
||||
if (err && (err != -EBUSY)) {
|
||||
netdev_err(failover_dev, "Opening slave %s failed err:%d\n",
|
||||
slave_dev->name, err);
|
||||
goto err_dev_open;
|
||||
goto err_netif_open;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,10 +562,10 @@ static int net_failover_slave_register(struct net_device *slave_dev,
|
||||
err_vlan_add:
|
||||
dev_uc_unsync(slave_dev, failover_dev);
|
||||
dev_mc_unsync(slave_dev, failover_dev);
|
||||
dev_close(slave_dev);
|
||||
err_dev_open:
|
||||
netif_close(slave_dev);
|
||||
err_netif_open:
|
||||
dev_put(slave_dev);
|
||||
dev_set_mtu(slave_dev, orig_mtu);
|
||||
netif_set_mtu(slave_dev, orig_mtu);
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <uapi/linux/if_arp.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <net/netdev_lock.h>
|
||||
#include <net/failover.h>
|
||||
|
||||
static LIST_HEAD(failover_list);
|
||||
@@ -221,8 +222,11 @@ failover_existing_slave_register(struct net_device *failover_dev)
|
||||
for_each_netdev(net, dev) {
|
||||
if (netif_is_failover(dev))
|
||||
continue;
|
||||
if (ether_addr_equal(failover_dev->perm_addr, dev->perm_addr))
|
||||
if (ether_addr_equal(failover_dev->perm_addr, dev->perm_addr)) {
|
||||
netdev_lock_ops(dev);
|
||||
failover_slave_register(dev);
|
||||
netdev_unlock_ops(dev);
|
||||
}
|
||||
}
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user