Commit b84c5632c7b3 for kernel

commit b84c5632c7b31f8910167075a8128cfb9e50fcfe
Author: Faicker Mo <faicker.mo@gmail.com>
Date:   Mon May 11 22:05:51 2026 +0800

    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: 4c975fd70002 ("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>

diff --git a/drivers/net/net_failover.c b/drivers/net/net_failover.c
index d0361aaf25ef..3f7d31033bae 100644
--- a/drivers/net/net_failover.c
+++ b/drivers/net/net_failover.c
@@ -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;
 }
diff --git a/net/core/failover.c b/net/core/failover.c
index 11bb183c7a1b..e43c59cd6868 100644
--- a/net/core/failover.c
+++ b/net/core/failover.c
@@ -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();
 }