@@ -1649,63 +1649,49 @@ static int netvsc_register_vf(struct net_device *vf_netdev)
1649
1649
return NOTIFY_OK ;
1650
1650
}
1651
1651
1652
- /* Change datapath */
1653
- static void netvsc_vf_update (struct work_struct * w )
1652
+ static int netvsc_vf_up (struct net_device * vf_netdev )
1654
1653
{
1655
- struct net_device_context * ndev_ctx
1656
- = container_of (w , struct net_device_context , vf_notify );
1657
- struct net_device * ndev = hv_get_drvdata (ndev_ctx -> device_ctx );
1654
+ struct net_device_context * net_device_ctx ;
1658
1655
struct netvsc_device * netvsc_dev ;
1659
- struct net_device * vf_netdev ;
1660
- bool vf_is_up ;
1661
-
1662
- if (!rtnl_trylock ()) {
1663
- schedule_work (w );
1664
- return ;
1665
- }
1656
+ struct net_device * ndev ;
1666
1657
1667
- vf_netdev = rtnl_dereference ( ndev_ctx -> vf_netdev );
1668
- if (!vf_netdev )
1669
- goto unlock ;
1658
+ ndev = get_netvsc_byref ( vf_netdev );
1659
+ if (!ndev )
1660
+ return NOTIFY_DONE ;
1670
1661
1671
- netvsc_dev = rtnl_dereference (ndev_ctx -> nvdev );
1662
+ net_device_ctx = netdev_priv (ndev );
1663
+ netvsc_dev = rtnl_dereference (net_device_ctx -> nvdev );
1672
1664
if (!netvsc_dev )
1673
- goto unlock ;
1674
-
1675
- vf_is_up = netif_running (vf_netdev );
1676
- if (vf_is_up != ndev_ctx -> datapath ) {
1677
- if (vf_is_up ) {
1678
- netdev_info (ndev , "VF up: %s\n" , vf_netdev -> name );
1679
- rndis_filter_open (netvsc_dev );
1680
- netvsc_switch_datapath (ndev , true);
1681
- netdev_info (ndev , "Data path switched to VF: %s\n" ,
1682
- vf_netdev -> name );
1683
- } else {
1684
- netdev_info (ndev , "VF down: %s\n" , vf_netdev -> name );
1685
- netvsc_switch_datapath (ndev , false);
1686
- rndis_filter_close (netvsc_dev );
1687
- netdev_info (ndev , "Data path switched from VF: %s\n" ,
1688
- vf_netdev -> name );
1689
- }
1665
+ return NOTIFY_DONE ;
1690
1666
1691
- /* Now notify peers through VF device. */
1692
- call_netdevice_notifiers (NETDEV_NOTIFY_PEERS , ndev );
1693
- }
1694
- unlock :
1695
- rtnl_unlock ();
1667
+ /* Bump refcount when datapath is acvive - Why? */
1668
+ rndis_filter_open (netvsc_dev );
1669
+
1670
+ /* notify the host to switch the data path. */
1671
+ netvsc_switch_datapath (ndev , true);
1672
+ netdev_info (ndev , "Data path switched to VF: %s\n" , vf_netdev -> name );
1673
+
1674
+ return NOTIFY_OK ;
1696
1675
}
1697
1676
1698
- static int netvsc_vf_notify (struct net_device * vf_netdev )
1677
+ static int netvsc_vf_down (struct net_device * vf_netdev )
1699
1678
{
1700
1679
struct net_device_context * net_device_ctx ;
1680
+ struct netvsc_device * netvsc_dev ;
1701
1681
struct net_device * ndev ;
1702
1682
1703
1683
ndev = get_netvsc_byref (vf_netdev );
1704
1684
if (!ndev )
1705
1685
return NOTIFY_DONE ;
1706
1686
1707
1687
net_device_ctx = netdev_priv (ndev );
1708
- schedule_work (& net_device_ctx -> vf_notify );
1688
+ netvsc_dev = rtnl_dereference (net_device_ctx -> nvdev );
1689
+ if (!netvsc_dev )
1690
+ return NOTIFY_DONE ;
1691
+
1692
+ netvsc_switch_datapath (ndev , false);
1693
+ netdev_info (ndev , "Data path switched from VF: %s\n" , vf_netdev -> name );
1694
+ rndis_filter_close (netvsc_dev );
1709
1695
1710
1696
return NOTIFY_OK ;
1711
1697
}
@@ -1721,7 +1707,6 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev)
1721
1707
1722
1708
net_device_ctx = netdev_priv (ndev );
1723
1709
cancel_work_sync (& net_device_ctx -> vf_takeover );
1724
- cancel_work_sync (& net_device_ctx -> vf_notify );
1725
1710
1726
1711
netdev_info (ndev , "VF unregistering: %s\n" , vf_netdev -> name );
1727
1712
@@ -1764,7 +1749,6 @@ static int netvsc_probe(struct hv_device *dev,
1764
1749
spin_lock_init (& net_device_ctx -> lock );
1765
1750
INIT_LIST_HEAD (& net_device_ctx -> reconfig_events );
1766
1751
INIT_WORK (& net_device_ctx -> vf_takeover , netvsc_vf_setup );
1767
- INIT_WORK (& net_device_ctx -> vf_notify , netvsc_vf_update );
1768
1752
1769
1753
net_device_ctx -> vf_stats
1770
1754
= netdev_alloc_pcpu_stats (struct netvsc_vf_pcpu_stats );
@@ -1915,8 +1899,9 @@ static int netvsc_netdev_event(struct notifier_block *this,
1915
1899
case NETDEV_UNREGISTER :
1916
1900
return netvsc_unregister_vf (event_dev );
1917
1901
case NETDEV_UP :
1902
+ return netvsc_vf_up (event_dev );
1918
1903
case NETDEV_DOWN :
1919
- return netvsc_vf_notify (event_dev );
1904
+ return netvsc_vf_down (event_dev );
1920
1905
default :
1921
1906
return NOTIFY_DONE ;
1922
1907
}
0 commit comments