[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <174265456307.356712.11381775975226010571.stgit@pro.pro>
Date: Sat, 22 Mar 2025 17:42:43 +0300
From: Kirill Tkhai <tkhai@...ru>
To: netdev@...r.kernel.org,
linux-kernel@...r.kernel.org
Cc: tkhai@...ru
Subject: [PATCH NET-PREV 39/51] netvsc: Make joined device to share master's nd_lock
We don't want to do that from netvsc_netdev_event() since
we want to make netdevice notifiers be called under nd_lock
in future.
Also see comments in patch introducing schedule_delayed_event()
Signed-off-by: Kirill Tkhai <tkhai@...ru>
---
drivers/net/hyperv/netvsc_drv.c | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 44142245343d..be8038e6393f 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -2192,6 +2192,7 @@ static int netvsc_vf_join(struct net_device *vf_netdev,
struct net_device *ndev, int context)
{
struct net_device_context *ndev_ctx = netdev_priv(ndev);
+ struct nd_lock *nd_lock, *nd_lock2;
int ret;
ret = netdev_rx_handler_register(vf_netdev,
@@ -2203,8 +2204,12 @@ static int netvsc_vf_join(struct net_device *vf_netdev,
goto rx_handler_failed;
}
+ double_lock_netdev(ndev, &nd_lock, vf_netdev, &nd_lock2);
+ nd_lock_transfer_devices(&nd_lock, &nd_lock2);
+
ret = netdev_master_upper_dev_link(vf_netdev, ndev,
NULL, NULL, NULL);
+ double_unlock_netdev(nd_lock, nd_lock2);
if (ret != 0) {
netdev_err(vf_netdev,
"can not set master device %s (err = %d)\n",
@@ -2797,6 +2802,20 @@ static struct hv_driver netvsc_drv = {
},
};
+static void call_netvsc_register(struct net_device *dev)
+{
+ unsigned long event;
+
+ rtnl_lock();
+ netvsc_prepare_bonding(dev);
+ netvsc_register_vf(dev, VF_REG_IN_NOTIFIER);
+ event = NETDEV_GOING_DOWN;
+ if (netif_running(dev))
+ event = NETDEV_CHANGE;
+ netvsc_vf_changed(dev, event);
+ rtnl_unlock();
+}
+
/*
* On Hyper-V, every VF interface is matched with a corresponding
* synthetic interface. The synthetic interface is presented first
@@ -2814,10 +2833,10 @@ static int netvsc_netdev_event(struct notifier_block *this,
return NOTIFY_DONE;
switch (event) {
- case NETDEV_POST_INIT:
- return netvsc_prepare_bonding(event_dev);
case NETDEV_REGISTER:
- return netvsc_register_vf(event_dev, VF_REG_IN_NOTIFIER);
+ return schedule_delayed_event(event_dev,
+ call_netvsc_register);
+ return NOTIFY_DONE;
case NETDEV_UNREGISTER:
return netvsc_unregister_vf(event_dev);
case NETDEV_UP:
Powered by blists - more mailing lists