@@ -2206,9 +2206,6 @@ static int netvsc_vf_join(struct net_device *vf_netdev,
22062206 goto upper_link_failed ;
22072207 }
22082208
2209- /* set slave flag before open to prevent IPv6 addrconf */
2210- vf_netdev -> flags |= IFF_SLAVE ;
2211-
22122209 schedule_delayed_work (& ndev_ctx -> vf_takeover , VF_TAKEOVER_INT );
22132210
22142211 call_netdevice_notifiers (NETDEV_JOIN , vf_netdev );
@@ -2315,23 +2312,38 @@ static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
23152312
23162313 }
23172314
2318- /* Fallback path to check synthetic vf with
2319- * help of mac addr
2315+ /* Fallback path to check synthetic vf with help of mac addr.
2316+ * Because this function can be called before vf_netdev is
2317+ * initialized (NETDEV_POST_INIT) when its perm_addr has not been copied
2318+ * from dev_addr, also try to match to its dev_addr.
2319+ * Note: On Hyper-V and Azure, it's not possible to set a MAC address
2320+ * on a VF that matches to the MAC of a unrelated NETVSC device.
23202321 */
23212322 list_for_each_entry (ndev_ctx , & netvsc_dev_list , list ) {
23222323 ndev = hv_get_drvdata (ndev_ctx -> device_ctx );
2323- if (ether_addr_equal (vf_netdev -> perm_addr , ndev -> perm_addr )) {
2324- netdev_notice (vf_netdev ,
2325- "falling back to mac addr based matching\n" );
2324+ if (ether_addr_equal (vf_netdev -> perm_addr , ndev -> perm_addr ) ||
2325+ ether_addr_equal (vf_netdev -> dev_addr , ndev -> perm_addr ))
23262326 return ndev ;
2327- }
23282327 }
23292328
23302329 netdev_notice (vf_netdev ,
23312330 "no netdev found for vf serial:%u\n" , serial );
23322331 return NULL ;
23332332}
23342333
2334+ static int netvsc_prepare_bonding (struct net_device * vf_netdev )
2335+ {
2336+ struct net_device * ndev ;
2337+
2338+ ndev = get_netvsc_byslot (vf_netdev );
2339+ if (!ndev )
2340+ return NOTIFY_DONE ;
2341+
2342+ /* set slave flag before open to prevent IPv6 addrconf */
2343+ vf_netdev -> flags |= IFF_SLAVE ;
2344+ return NOTIFY_DONE ;
2345+ }
2346+
23352347static int netvsc_register_vf (struct net_device * vf_netdev )
23362348{
23372349 struct net_device_context * net_device_ctx ;
@@ -2531,25 +2543,30 @@ static int netvsc_probe(struct hv_device *dev,
25312543 goto devinfo_failed ;
25322544 }
25332545
2534- nvdev = rndis_filter_device_add (dev , device_info );
2535- if (IS_ERR (nvdev )) {
2536- ret = PTR_ERR (nvdev );
2537- netdev_err (net , "unable to add netvsc device (ret %d)\n" , ret );
2538- goto rndis_failed ;
2539- }
2540-
2541- eth_hw_addr_set (net , device_info -> mac_adr );
2542-
25432546 /* We must get rtnl lock before scheduling nvdev->subchan_work,
25442547 * otherwise netvsc_subchan_work() can get rtnl lock first and wait
25452548 * all subchannels to show up, but that may not happen because
25462549 * netvsc_probe() can't get rtnl lock and as a result vmbus_onoffer()
25472550 * -> ... -> device_add() -> ... -> __device_attach() can't get
25482551 * the device lock, so all the subchannels can't be processed --
25492552 * finally netvsc_subchan_work() hangs forever.
2553+ *
2554+ * The rtnl lock also needs to be held before rndis_filter_device_add()
2555+ * which advertises nvsp_2_vsc_capability / sriov bit, and triggers
2556+ * VF NIC offering and registering. If VF NIC finished register_netdev()
2557+ * earlier it may cause name based config failure.
25502558 */
25512559 rtnl_lock ();
25522560
2561+ nvdev = rndis_filter_device_add (dev , device_info );
2562+ if (IS_ERR (nvdev )) {
2563+ ret = PTR_ERR (nvdev );
2564+ netdev_err (net , "unable to add netvsc device (ret %d)\n" , ret );
2565+ goto rndis_failed ;
2566+ }
2567+
2568+ eth_hw_addr_set (net , device_info -> mac_adr );
2569+
25532570 if (nvdev -> num_chn > 1 )
25542571 schedule_work (& nvdev -> subchan_work );
25552572
@@ -2586,9 +2603,9 @@ static int netvsc_probe(struct hv_device *dev,
25862603 return 0 ;
25872604
25882605register_failed :
2589- rtnl_unlock ();
25902606 rndis_filter_device_remove (dev , nvdev );
25912607rndis_failed :
2608+ rtnl_unlock ();
25922609 netvsc_devinfo_put (device_info );
25932610devinfo_failed :
25942611 free_percpu (net_device_ctx -> vf_stats );
@@ -2753,6 +2770,8 @@ static int netvsc_netdev_event(struct notifier_block *this,
27532770 return NOTIFY_DONE ;
27542771
27552772 switch (event ) {
2773+ case NETDEV_POST_INIT :
2774+ return netvsc_prepare_bonding (event_dev );
27562775 case NETDEV_REGISTER :
27572776 return netvsc_register_vf (event_dev );
27582777 case NETDEV_UNREGISTER :
@@ -2788,12 +2807,17 @@ static int __init netvsc_drv_init(void)
27882807 }
27892808 netvsc_ring_bytes = ring_size * PAGE_SIZE ;
27902809
2810+ register_netdevice_notifier (& netvsc_netdev_notifier );
2811+
27912812 ret = vmbus_driver_register (& netvsc_drv );
27922813 if (ret )
2793- return ret ;
2814+ goto err_vmbus_reg ;
27942815
2795- register_netdevice_notifier (& netvsc_netdev_notifier );
27962816 return 0 ;
2817+
2818+ err_vmbus_reg :
2819+ unregister_netdevice_notifier (& netvsc_netdev_notifier );
2820+ return ret ;
27972821}
27982822
27992823MODULE_LICENSE ("GPL" );
0 commit comments