@@ -2516,6 +2516,7 @@ static int netvsc_probe(struct hv_device *dev,
25162516	spin_lock_init (& net_device_ctx -> lock );
25172517	INIT_LIST_HEAD (& net_device_ctx -> reconfig_events );
25182518	INIT_DELAYED_WORK (& net_device_ctx -> vf_takeover , netvsc_vf_setup );
2519+ 	INIT_DELAYED_WORK (& net_device_ctx -> vfns_work , netvsc_vfns_work );
25192520
25202521	net_device_ctx -> vf_stats 
25212522		=  netdev_alloc_pcpu_stats (struct  netvsc_vf_pcpu_stats );
@@ -2658,6 +2659,8 @@ static void netvsc_remove(struct hv_device *dev)
26582659	cancel_delayed_work_sync (& ndev_ctx -> dwork );
26592660
26602661	rtnl_lock ();
2662+ 	cancel_delayed_work_sync (& ndev_ctx -> vfns_work );
2663+ 
26612664	nvdev  =  rtnl_dereference (ndev_ctx -> nvdev );
26622665	if  (nvdev ) {
26632666		cancel_work_sync (& nvdev -> subchan_work );
@@ -2699,6 +2702,7 @@ static int netvsc_suspend(struct hv_device *dev)
26992702	cancel_delayed_work_sync (& ndev_ctx -> dwork );
27002703
27012704	rtnl_lock ();
2705+ 	cancel_delayed_work_sync (& ndev_ctx -> vfns_work );
27022706
27032707	nvdev  =  rtnl_dereference (ndev_ctx -> nvdev );
27042708	if  (nvdev  ==  NULL ) {
@@ -2792,6 +2796,27 @@ static void netvsc_event_set_vf_ns(struct net_device *ndev)
27922796	}
27932797}
27942798
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+ 
27952820/* 
27962821 * On Hyper-V, every VF interface is matched with a corresponding 
27972822 * synthetic interface. The synthetic interface is presented first 
@@ -2802,10 +2827,12 @@ static int netvsc_netdev_event(struct notifier_block *this,
28022827			       unsigned long  event , void  * ptr )
28032828{
28042829	struct  net_device  * event_dev  =  netdev_notifier_info_to_dev (ptr );
2830+ 	struct  net_device_context  * ndev_ctx ;
28052831	int  ret  =  0 ;
28062832
28072833	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 );
28092836		return  NOTIFY_DONE ;
28102837	}
28112838
0 commit comments