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