@@ -2206,9 +2206,6 @@ static int netvsc_vf_join(struct net_device *vf_netdev,
2206
2206
goto upper_link_failed ;
2207
2207
}
2208
2208
2209
- /* set slave flag before open to prevent IPv6 addrconf */
2210
- vf_netdev -> flags |= IFF_SLAVE ;
2211
-
2212
2209
schedule_delayed_work (& ndev_ctx -> vf_takeover , VF_TAKEOVER_INT );
2213
2210
2214
2211
call_netdevice_notifiers (NETDEV_JOIN , vf_netdev );
@@ -2315,23 +2312,38 @@ static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
2315
2312
2316
2313
}
2317
2314
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.
2320
2321
*/
2321
2322
list_for_each_entry (ndev_ctx , & netvsc_dev_list , list ) {
2322
2323
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 ))
2326
2326
return ndev ;
2327
- }
2328
2327
}
2329
2328
2330
2329
netdev_notice (vf_netdev ,
2331
2330
"no netdev found for vf serial:%u\n" , serial );
2332
2331
return NULL ;
2333
2332
}
2334
2333
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
+
2335
2347
static int netvsc_register_vf (struct net_device * vf_netdev )
2336
2348
{
2337
2349
struct net_device_context * net_device_ctx ;
@@ -2531,25 +2543,30 @@ static int netvsc_probe(struct hv_device *dev,
2531
2543
goto devinfo_failed ;
2532
2544
}
2533
2545
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
-
2543
2546
/* We must get rtnl lock before scheduling nvdev->subchan_work,
2544
2547
* otherwise netvsc_subchan_work() can get rtnl lock first and wait
2545
2548
* all subchannels to show up, but that may not happen because
2546
2549
* netvsc_probe() can't get rtnl lock and as a result vmbus_onoffer()
2547
2550
* -> ... -> device_add() -> ... -> __device_attach() can't get
2548
2551
* the device lock, so all the subchannels can't be processed --
2549
2552
* 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.
2550
2558
*/
2551
2559
rtnl_lock ();
2552
2560
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
+
2553
2570
if (nvdev -> num_chn > 1 )
2554
2571
schedule_work (& nvdev -> subchan_work );
2555
2572
@@ -2586,9 +2603,9 @@ static int netvsc_probe(struct hv_device *dev,
2586
2603
return 0 ;
2587
2604
2588
2605
register_failed :
2589
- rtnl_unlock ();
2590
2606
rndis_filter_device_remove (dev , nvdev );
2591
2607
rndis_failed :
2608
+ rtnl_unlock ();
2592
2609
netvsc_devinfo_put (device_info );
2593
2610
devinfo_failed :
2594
2611
free_percpu (net_device_ctx -> vf_stats );
@@ -2753,6 +2770,8 @@ static int netvsc_netdev_event(struct notifier_block *this,
2753
2770
return NOTIFY_DONE ;
2754
2771
2755
2772
switch (event ) {
2773
+ case NETDEV_POST_INIT :
2774
+ return netvsc_prepare_bonding (event_dev );
2756
2775
case NETDEV_REGISTER :
2757
2776
return netvsc_register_vf (event_dev );
2758
2777
case NETDEV_UNREGISTER :
@@ -2788,12 +2807,17 @@ static int __init netvsc_drv_init(void)
2788
2807
}
2789
2808
netvsc_ring_bytes = ring_size * PAGE_SIZE ;
2790
2809
2810
+ register_netdevice_notifier (& netvsc_netdev_notifier );
2811
+
2791
2812
ret = vmbus_driver_register (& netvsc_drv );
2792
2813
if (ret )
2793
- return ret ;
2814
+ goto err_vmbus_reg ;
2794
2815
2795
- register_netdevice_notifier (& netvsc_netdev_notifier );
2796
2816
return 0 ;
2817
+
2818
+ err_vmbus_reg :
2819
+ unregister_netdevice_notifier (& netvsc_netdev_notifier );
2820
+ return ret ;
2797
2821
}
2798
2822
2799
2823
MODULE_LICENSE ("GPL" );
0 commit comments