@@ -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