Skip to content

Commit 76db054

Browse files
faickergregkh
authored andcommitted
net: net_failover: Fix the deadlock in slave register
commit b84c563 upstream. 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: 4c975fd ("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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent c5b3871 commit 76db054

2 files changed

Lines changed: 11 additions & 7 deletions

File tree

drivers/net/net_failover.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ static int net_failover_slave_register(struct net_device *slave_dev,
502502

503503
/* Align MTU of slave with failover dev */
504504
orig_mtu = slave_dev->mtu;
505-
err = dev_set_mtu(slave_dev, failover_dev->mtu);
505+
err = netif_set_mtu(slave_dev, failover_dev->mtu);
506506
if (err) {
507507
netdev_err(failover_dev, "unable to change mtu of %s to %u register failed\n",
508508
slave_dev->name, failover_dev->mtu);
@@ -512,11 +512,11 @@ static int net_failover_slave_register(struct net_device *slave_dev,
512512
dev_hold(slave_dev);
513513

514514
if (netif_running(failover_dev)) {
515-
err = dev_open(slave_dev, NULL);
515+
err = netif_open(slave_dev, NULL);
516516
if (err && (err != -EBUSY)) {
517517
netdev_err(failover_dev, "Opening slave %s failed err:%d\n",
518518
slave_dev->name, err);
519-
goto err_dev_open;
519+
goto err_netif_open;
520520
}
521521
}
522522

@@ -562,10 +562,10 @@ static int net_failover_slave_register(struct net_device *slave_dev,
562562
err_vlan_add:
563563
dev_uc_unsync(slave_dev, failover_dev);
564564
dev_mc_unsync(slave_dev, failover_dev);
565-
dev_close(slave_dev);
566-
err_dev_open:
565+
netif_close(slave_dev);
566+
err_netif_open:
567567
dev_put(slave_dev);
568-
dev_set_mtu(slave_dev, orig_mtu);
568+
netif_set_mtu(slave_dev, orig_mtu);
569569
done:
570570
return err;
571571
}

net/core/failover.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <uapi/linux/if_arp.h>
1313
#include <linux/rtnetlink.h>
1414
#include <linux/if_vlan.h>
15+
#include <net/netdev_lock.h>
1516
#include <net/failover.h>
1617

1718
static LIST_HEAD(failover_list);
@@ -221,8 +222,11 @@ failover_existing_slave_register(struct net_device *failover_dev)
221222
for_each_netdev(net, dev) {
222223
if (netif_is_failover(dev))
223224
continue;
224-
if (ether_addr_equal(failover_dev->perm_addr, dev->perm_addr))
225+
if (ether_addr_equal(failover_dev->perm_addr, dev->perm_addr)) {
226+
netdev_lock_ops(dev);
225227
failover_slave_register(dev);
228+
netdev_unlock_ops(dev);
229+
}
226230
}
227231
rtnl_unlock();
228232
}

0 commit comments

Comments
 (0)