@@ -2513,6 +2513,7 @@ static int netvsc_probe(struct hv_device *dev,
2513
2513
spin_lock_init (& net_device_ctx -> lock );
2514
2514
INIT_LIST_HEAD (& net_device_ctx -> reconfig_events );
2515
2515
INIT_DELAYED_WORK (& net_device_ctx -> vf_takeover , netvsc_vf_setup );
2516
+ INIT_DELAYED_WORK (& net_device_ctx -> vfns_work , netvsc_vfns_work );
2516
2517
2517
2518
net_device_ctx -> vf_stats
2518
2519
= netdev_alloc_pcpu_stats (struct netvsc_vf_pcpu_stats );
@@ -2655,6 +2656,8 @@ static void netvsc_remove(struct hv_device *dev)
2655
2656
cancel_delayed_work_sync (& ndev_ctx -> dwork );
2656
2657
2657
2658
rtnl_lock ();
2659
+ cancel_delayed_work_sync (& ndev_ctx -> vfns_work );
2660
+
2658
2661
nvdev = rtnl_dereference (ndev_ctx -> nvdev );
2659
2662
if (nvdev ) {
2660
2663
cancel_work_sync (& nvdev -> subchan_work );
@@ -2696,6 +2699,7 @@ static int netvsc_suspend(struct hv_device *dev)
2696
2699
cancel_delayed_work_sync (& ndev_ctx -> dwork );
2697
2700
2698
2701
rtnl_lock ();
2702
+ cancel_delayed_work_sync (& ndev_ctx -> vfns_work );
2699
2703
2700
2704
nvdev = rtnl_dereference (ndev_ctx -> nvdev );
2701
2705
if (nvdev == NULL ) {
@@ -2789,6 +2793,27 @@ static void netvsc_event_set_vf_ns(struct net_device *ndev)
2789
2793
}
2790
2794
}
2791
2795
2796
+ void netvsc_vfns_work (struct work_struct * w )
2797
+ {
2798
+ struct net_device_context * ndev_ctx =
2799
+ container_of (w , struct net_device_context , vfns_work .work );
2800
+ struct net_device * ndev ;
2801
+
2802
+ if (!rtnl_trylock ()) {
2803
+ schedule_delayed_work (& ndev_ctx -> vfns_work , 1 );
2804
+ return ;
2805
+ }
2806
+
2807
+ ndev = hv_get_drvdata (ndev_ctx -> device_ctx );
2808
+ if (!ndev )
2809
+ goto out ;
2810
+
2811
+ netvsc_event_set_vf_ns (ndev );
2812
+
2813
+ out :
2814
+ rtnl_unlock ();
2815
+ }
2816
+
2792
2817
/*
2793
2818
* On Hyper-V, every VF interface is matched with a corresponding
2794
2819
* synthetic interface. The synthetic interface is presented first
@@ -2799,10 +2824,12 @@ static int netvsc_netdev_event(struct notifier_block *this,
2799
2824
unsigned long event , void * ptr )
2800
2825
{
2801
2826
struct net_device * event_dev = netdev_notifier_info_to_dev (ptr );
2827
+ struct net_device_context * ndev_ctx ;
2802
2828
int ret = 0 ;
2803
2829
2804
2830
if (event_dev -> netdev_ops == & device_ops && event == NETDEV_REGISTER ) {
2805
- netvsc_event_set_vf_ns (event_dev );
2831
+ ndev_ctx = netdev_priv (event_dev );
2832
+ schedule_delayed_work (& ndev_ctx -> vfns_work , 0 );
2806
2833
return NOTIFY_DONE ;
2807
2834
}
2808
2835
0 commit comments