@@ -2522,6 +2522,7 @@ static int netvsc_probe(struct hv_device *dev,
25222522 spin_lock_init (& net_device_ctx -> lock );
25232523 INIT_LIST_HEAD (& net_device_ctx -> reconfig_events );
25242524 INIT_DELAYED_WORK (& net_device_ctx -> vf_takeover , netvsc_vf_setup );
2525+ INIT_DELAYED_WORK (& net_device_ctx -> vfns_work , netvsc_vfns_work );
25252526
25262527 net_device_ctx -> vf_stats
25272528 = netdev_alloc_pcpu_stats (struct netvsc_vf_pcpu_stats );
@@ -2666,6 +2667,8 @@ static void netvsc_remove(struct hv_device *dev)
26662667 cancel_delayed_work_sync (& ndev_ctx -> dwork );
26672668
26682669 rtnl_lock ();
2670+ cancel_delayed_work_sync (& ndev_ctx -> vfns_work );
2671+
26692672 nvdev = rtnl_dereference (ndev_ctx -> nvdev );
26702673 if (nvdev ) {
26712674 cancel_work_sync (& nvdev -> subchan_work );
@@ -2707,6 +2710,7 @@ static int netvsc_suspend(struct hv_device *dev)
27072710 cancel_delayed_work_sync (& ndev_ctx -> dwork );
27082711
27092712 rtnl_lock ();
2713+ cancel_delayed_work_sync (& ndev_ctx -> vfns_work );
27102714
27112715 nvdev = rtnl_dereference (ndev_ctx -> nvdev );
27122716 if (nvdev == NULL ) {
@@ -2800,6 +2804,27 @@ static void netvsc_event_set_vf_ns(struct net_device *ndev)
28002804 }
28012805}
28022806
2807+ void netvsc_vfns_work (struct work_struct * w )
2808+ {
2809+ struct net_device_context * ndev_ctx =
2810+ container_of (w , struct net_device_context , vfns_work .work );
2811+ struct net_device * ndev ;
2812+
2813+ if (!rtnl_trylock ()) {
2814+ schedule_delayed_work (& ndev_ctx -> vfns_work , 1 );
2815+ return ;
2816+ }
2817+
2818+ ndev = hv_get_drvdata (ndev_ctx -> device_ctx );
2819+ if (!ndev )
2820+ goto out ;
2821+
2822+ netvsc_event_set_vf_ns (ndev );
2823+
2824+ out :
2825+ rtnl_unlock ();
2826+ }
2827+
28032828/*
28042829 * On Hyper-V, every VF interface is matched with a corresponding
28052830 * synthetic interface. The synthetic interface is presented first
@@ -2810,10 +2835,12 @@ static int netvsc_netdev_event(struct notifier_block *this,
28102835 unsigned long event , void * ptr )
28112836{
28122837 struct net_device * event_dev = netdev_notifier_info_to_dev (ptr );
2838+ struct net_device_context * ndev_ctx ;
28132839 int ret = 0 ;
28142840
28152841 if (event_dev -> netdev_ops == & device_ops && event == NETDEV_REGISTER ) {
2816- netvsc_event_set_vf_ns (event_dev );
2842+ ndev_ctx = netdev_priv (event_dev );
2843+ schedule_delayed_work (& ndev_ctx -> vfns_work , 0 );
28172844 return NOTIFY_DONE ;
28182845 }
28192846
0 commit comments