Implement the ndo_set_rx_mode_async callback and update the driver to use the snapshot/commit model for RX mode update.
Signed-off-by: I Viswanath <[email protected]> --- Call paths involving netif_set_rx_mode in vmxnet3 netif_set_rx_mode `-- vmxnet3_activate_dev |-- vmxnet3_open (ndo_open, takes lock) |-- vmxnet3_change_mtu (ndo_change_mtu, takes lock) |-- vmxnet3_reset_work (takes lock) |-- vmxnet3_resume (lock added) |-- vmxnet3_set_ringparam (ethtool callback, takes lock) `-- vmxnet3_xdp_set `-- vmxnet3_xdp (ndo_bpf, takes lock) drivers/net/vmxnet3/vmxnet3_drv.c | 46 +++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 40522afc0532..350e44286c00 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2775,18 +2775,18 @@ static u8 * vmxnet3_copy_mc(struct net_device *netdev) { u8 *buf = NULL; - u32 sz = netdev_mc_count(netdev) * ETH_ALEN; + u32 sz = netif_rx_mode_mc_count(netdev) * ETH_ALEN; + char *ha_addr; + int ni; /* struct Vmxnet3_RxFilterConf.mfTableLen is u16. */ if (sz <= 0xffff) { /* We may be called with BH disabled */ buf = kmalloc(sz, GFP_ATOMIC); if (buf) { - struct netdev_hw_addr *ha; int i = 0; - - netdev_for_each_mc_addr(ha, netdev) - memcpy(buf + i++ * ETH_ALEN, ha->addr, + netif_rx_mode_for_each_mc_addr(ha_addr, netdev, ni) + memcpy(buf + i++ * ETH_ALEN, ha_addr, ETH_ALEN); } } @@ -2796,8 +2796,23 @@ vmxnet3_copy_mc(struct net_device *netdev) static void vmxnet3_set_mc(struct net_device *netdev) +{ + bool allmulti = !!(netdev->flags & IFF_ALLMULTI); + bool promisc = !!(netdev->flags & IFF_PROMISC); + bool broadcast = !!(netdev->flags & IFF_BROADCAST); + + netif_set_rx_mode_flag(netdev, NETIF_RX_MODE_UC_SKIP, true); + netif_set_rx_mode_flag(netdev, NETIF_RX_MODE_MC_SKIP, allmulti); + + netif_set_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_ALLMULTI, allmulti); + netif_set_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_PROMISC, promisc); + netif_set_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_BROADCAST, broadcast); +} + +static void vmxnet3_set_mc_async(struct net_device *netdev) { struct vmxnet3_adapter *adapter = netdev_priv(netdev); + int mc_count = netif_rx_mode_mc_count(netdev); unsigned long flags; struct Vmxnet3_RxFilterConf *rxConf = &adapter->shared->devRead.rxFilterConf; @@ -2806,7 +2821,7 @@ vmxnet3_set_mc(struct net_device *netdev) bool new_table_pa_valid = false; u32 new_mode = VMXNET3_RXM_UCAST; - if (netdev->flags & IFF_PROMISC) { + if (netif_get_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_PROMISC)) { u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable; memset(vfTable, 0, VMXNET3_VFT_SIZE * sizeof(*vfTable)); @@ -2815,16 +2830,16 @@ vmxnet3_set_mc(struct net_device *netdev) vmxnet3_restore_vlan(adapter); } - if (netdev->flags & IFF_BROADCAST) + if (netif_get_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_BROADCAST)) new_mode |= VMXNET3_RXM_BCAST; - if (netdev->flags & IFF_ALLMULTI) + if (netif_get_rx_mode_cfg(netdev, NETIF_RX_MODE_CFG_ALLMULTI)) new_mode |= VMXNET3_RXM_ALL_MULTI; else - if (!netdev_mc_empty(netdev)) { + if (mc_count) { new_table = vmxnet3_copy_mc(netdev); if (new_table) { - size_t sz = netdev_mc_count(netdev) * ETH_ALEN; + size_t sz = mc_count * ETH_ALEN; rxConf->mfTableLen = cpu_to_le16(sz); new_table_pa = dma_map_single( @@ -3213,7 +3228,7 @@ vmxnet3_activate_dev(struct vmxnet3_adapter *adapter) } /* Apply the rx filter settins last. */ - vmxnet3_set_mc(adapter->netdev); + netif_set_rx_mode(adapter->netdev); /* * Check link state when first activating device. It will start the @@ -3977,6 +3992,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, .ndo_get_stats64 = vmxnet3_get_stats64, .ndo_tx_timeout = vmxnet3_tx_timeout, .ndo_set_rx_mode = vmxnet3_set_mc, + .ndo_set_rx_mode_async = vmxnet3_set_mc_async, .ndo_vlan_rx_add_vid = vmxnet3_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = vmxnet3_vlan_rx_kill_vid, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -4400,6 +4416,7 @@ static void vmxnet3_shutdown_device(struct pci_dev *pdev) vmxnet3_disable_all_intrs(adapter); clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state); + netif_disable_async_ops(netdev); } @@ -4518,6 +4535,7 @@ vmxnet3_suspend(struct device *device) pci_disable_device(pdev); pci_set_power_state(pdev, pci_choose_state(pdev, PMSG_SUSPEND)); + netif_disable_async_ops(netdev); return 0; } @@ -4531,6 +4549,8 @@ vmxnet3_resume(struct device *device) struct net_device *netdev = pci_get_drvdata(pdev); struct vmxnet3_adapter *adapter = netdev_priv(netdev); + netif_enable_async_ops(netdev); + if (!netif_running(netdev)) return 0; @@ -4559,7 +4579,11 @@ vmxnet3_resume(struct device *device) vmxnet3_rq_cleanup_all(adapter); vmxnet3_reset_dev(adapter); + + rtnl_lock(); err = vmxnet3_activate_dev(adapter); + rtnl_unlock(); + if (err != 0) { netdev_err(netdev, "failed to re-activate on resume, error: %d", err); -- 2.47.3

