@@ -2531,6 +2531,7 @@ static int netvsc_probe(struct hv_device *dev,
25312531 spin_lock_init (& net_device_ctx -> lock );
25322532 INIT_LIST_HEAD (& net_device_ctx -> reconfig_events );
25332533 INIT_DELAYED_WORK (& net_device_ctx -> vf_takeover , netvsc_vf_setup );
2534+ INIT_DELAYED_WORK (& net_device_ctx -> vfns_work , netvsc_vfns_work );
25342535
25352536 net_device_ctx -> vf_stats
25362537 = netdev_alloc_pcpu_stats (struct netvsc_vf_pcpu_stats );
@@ -2673,6 +2674,8 @@ static void netvsc_remove(struct hv_device *dev)
26732674 cancel_delayed_work_sync (& ndev_ctx -> dwork );
26742675
26752676 rtnl_lock ();
2677+ cancel_delayed_work_sync (& ndev_ctx -> vfns_work );
2678+
26762679 nvdev = rtnl_dereference (ndev_ctx -> nvdev );
26772680 if (nvdev ) {
26782681 cancel_work_sync (& nvdev -> subchan_work );
@@ -2714,6 +2717,7 @@ static int netvsc_suspend(struct hv_device *dev)
27142717 cancel_delayed_work_sync (& ndev_ctx -> dwork );
27152718
27162719 rtnl_lock ();
2720+ cancel_delayed_work_sync (& ndev_ctx -> vfns_work );
27172721
27182722 nvdev = rtnl_dereference (ndev_ctx -> nvdev );
27192723 if (nvdev == NULL ) {
@@ -2807,6 +2811,27 @@ static void netvsc_event_set_vf_ns(struct net_device *ndev)
28072811 }
28082812}
28092813
2814+ void netvsc_vfns_work (struct work_struct * w )
2815+ {
2816+ struct net_device_context * ndev_ctx =
2817+ container_of (w , struct net_device_context , vfns_work .work );
2818+ struct net_device * ndev ;
2819+
2820+ if (!rtnl_trylock ()) {
2821+ schedule_delayed_work (& ndev_ctx -> vfns_work , 1 );
2822+ return ;
2823+ }
2824+
2825+ ndev = hv_get_drvdata (ndev_ctx -> device_ctx );
2826+ if (!ndev )
2827+ goto out ;
2828+
2829+ netvsc_event_set_vf_ns (ndev );
2830+
2831+ out :
2832+ rtnl_unlock ();
2833+ }
2834+
28102835/*
28112836 * On Hyper-V, every VF interface is matched with a corresponding
28122837 * synthetic interface. The synthetic interface is presented first
@@ -2817,10 +2842,12 @@ static int netvsc_netdev_event(struct notifier_block *this,
28172842 unsigned long event , void * ptr )
28182843{
28192844 struct net_device * event_dev = netdev_notifier_info_to_dev (ptr );
2845+ struct net_device_context * ndev_ctx ;
28202846 int ret = 0 ;
28212847
28222848 if (event_dev -> netdev_ops == & device_ops && event == NETDEV_REGISTER ) {
2823- netvsc_event_set_vf_ns (event_dev );
2849+ ndev_ctx = netdev_priv (event_dev );
2850+ schedule_delayed_work (& ndev_ctx -> vfns_work , 0 );
28242851 return NOTIFY_DONE ;
28252852 }
28262853
0 commit comments