@@ -2565,6 +2565,7 @@ static int netvsc_probe(struct hv_device *dev,
25652565	spin_lock_init (& net_device_ctx -> lock );
25662566	INIT_LIST_HEAD (& net_device_ctx -> reconfig_events );
25672567	INIT_DELAYED_WORK (& net_device_ctx -> vf_takeover , netvsc_vf_setup );
2568+ 	INIT_DELAYED_WORK (& net_device_ctx -> vfns_work , netvsc_vfns_work );
25682569
25692570	net_device_ctx -> vf_stats 
25702571		=  netdev_alloc_pcpu_stats (struct  netvsc_vf_pcpu_stats );
@@ -2707,6 +2708,8 @@ static void netvsc_remove(struct hv_device *dev)
27072708	cancel_delayed_work_sync (& ndev_ctx -> dwork );
27082709
27092710	rtnl_lock ();
2711+ 	cancel_delayed_work_sync (& ndev_ctx -> vfns_work );
2712+ 
27102713	nvdev  =  rtnl_dereference (ndev_ctx -> nvdev );
27112714	if  (nvdev ) {
27122715		cancel_work_sync (& nvdev -> subchan_work );
@@ -2748,6 +2751,7 @@ static int netvsc_suspend(struct hv_device *dev)
27482751	cancel_delayed_work_sync (& ndev_ctx -> dwork );
27492752
27502753	rtnl_lock ();
2754+ 	cancel_delayed_work_sync (& ndev_ctx -> vfns_work );
27512755
27522756	nvdev  =  rtnl_dereference (ndev_ctx -> nvdev );
27532757	if  (nvdev  ==  NULL ) {
@@ -2841,6 +2845,27 @@ static void netvsc_event_set_vf_ns(struct net_device *ndev)
28412845	}
28422846}
28432847
2848+ void  netvsc_vfns_work (struct  work_struct  * w )
2849+ {
2850+ 	struct  net_device_context  * ndev_ctx  = 
2851+ 		container_of (w , struct  net_device_context , vfns_work .work );
2852+ 	struct  net_device  * ndev ;
2853+ 
2854+ 	if  (!rtnl_trylock ()) {
2855+ 		schedule_delayed_work (& ndev_ctx -> vfns_work , 1 );
2856+ 		return ;
2857+ 	}
2858+ 
2859+ 	ndev  =  hv_get_drvdata (ndev_ctx -> device_ctx );
2860+ 	if  (!ndev )
2861+ 		goto out ;
2862+ 
2863+ 	netvsc_event_set_vf_ns (ndev );
2864+ 
2865+ out :
2866+ 	rtnl_unlock ();
2867+ }
2868+ 
28442869/* 
28452870 * On Hyper-V, every VF interface is matched with a corresponding 
28462871 * synthetic interface. The synthetic interface is presented first 
@@ -2851,10 +2876,12 @@ static int netvsc_netdev_event(struct notifier_block *this,
28512876			       unsigned long  event , void  * ptr )
28522877{
28532878	struct  net_device  * event_dev  =  netdev_notifier_info_to_dev (ptr );
2879+ 	struct  net_device_context  * ndev_ctx ;
28542880	int  ret  =  0 ;
28552881
28562882	if  (event_dev -> netdev_ops  ==  & device_ops  &&  event  ==  NETDEV_REGISTER ) {
2857- 		netvsc_event_set_vf_ns (event_dev );
2883+ 		ndev_ctx  =  netdev_priv (event_dev );
2884+ 		schedule_delayed_work (& ndev_ctx -> vfns_work , 0 );
28582885		return  NOTIFY_DONE ;
28592886	}
28602887
0 commit comments