diff options
-rw-r--r-- | drivers/net/ethernet/ibm/ibmvnic.c | 9 | ||||
-rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 11 | ||||
-rw-r--r-- | include/linux/netdevice.h | 1 | ||||
-rw-r--r-- | net/core/dev.c | 22 |
4 files changed, 28 insertions, 15 deletions
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index a2191392ca4f2..f302504faa8a5 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -2171,10 +2171,8 @@ static int do_reset(struct ibmvnic_adapter *adapter, napi_schedule(&adapter->napi[i]); if (adapter->reset_reason == VNIC_RESET_FAILOVER || - adapter->reset_reason == VNIC_RESET_MOBILITY) { - call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, netdev); - call_netdevice_notifiers(NETDEV_RESEND_IGMP, netdev); - } + adapter->reset_reason == VNIC_RESET_MOBILITY) + __netdev_notify_peers(netdev); rc = 0; @@ -2249,8 +2247,7 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter, goto out; } - call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, netdev); - call_netdevice_notifiers(NETDEV_RESEND_IGMP, netdev); + __netdev_notify_peers(netdev); out: /* restore adapter state if reset failed */ if (rc) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index d17bbc75f5e7f..f32f28311d573 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -2050,11 +2050,11 @@ static void netvsc_link_change(struct work_struct *w) container_of(w, struct net_device_context, dwork.work); struct hv_device *device_obj = ndev_ctx->device_ctx; struct net_device *net = hv_get_drvdata(device_obj); + unsigned long flags, next_reconfig, delay; + struct netvsc_reconfig *event = NULL; struct netvsc_device *net_device; struct rndis_device *rdev; - struct netvsc_reconfig *event = NULL; - bool notify = false, reschedule = false; - unsigned long flags, next_reconfig, delay; + bool reschedule = false; /* if changes are happening, comeback later */ if (!rtnl_trylock()) { @@ -2103,7 +2103,7 @@ static void netvsc_link_change(struct work_struct *w) netif_carrier_on(net); netvsc_tx_enable(net_device, net); } else { - notify = true; + __netdev_notify_peers(net); } kfree(event); break; @@ -2132,9 +2132,6 @@ static void netvsc_link_change(struct work_struct *w) rtnl_unlock(); - if (notify) - netdev_notify_peers(net); - /* link_watch only sends one notification with current state per * second, handle next reconfig event in 2 seconds. */ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 7bf167993c05b..259be67644e35 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -4547,6 +4547,7 @@ void __dev_set_rx_mode(struct net_device *dev); int dev_set_promiscuity(struct net_device *dev, int inc); int dev_set_allmulti(struct net_device *dev, int inc); void netdev_state_change(struct net_device *dev); +void __netdev_notify_peers(struct net_device *dev); void netdev_notify_peers(struct net_device *dev); void netdev_features_change(struct net_device *dev); /* Load a device via the kmod */ diff --git a/net/core/dev.c b/net/core/dev.c index a46334906c94d..8fa739259041a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1457,6 +1457,25 @@ void netdev_state_change(struct net_device *dev) EXPORT_SYMBOL(netdev_state_change); /** + * __netdev_notify_peers - notify network peers about existence of @dev, + * to be called when rtnl lock is already held. + * @dev: network device + * + * Generate traffic such that interested network peers are aware of + * @dev, such as by generating a gratuitous ARP. This may be used when + * a device wants to inform the rest of the network about some sort of + * reconfiguration such as a failover event or virtual machine + * migration. + */ +void __netdev_notify_peers(struct net_device *dev) +{ + ASSERT_RTNL(); + call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, dev); + call_netdevice_notifiers(NETDEV_RESEND_IGMP, dev); +} +EXPORT_SYMBOL(__netdev_notify_peers); + +/** * netdev_notify_peers - notify network peers about existence of @dev * @dev: network device * @@ -1469,8 +1488,7 @@ EXPORT_SYMBOL(netdev_state_change); void netdev_notify_peers(struct net_device *dev) { rtnl_lock(); - call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, dev); - call_netdevice_notifiers(NETDEV_RESEND_IGMP, dev); + __netdev_notify_peers(dev); rtnl_unlock(); } EXPORT_SYMBOL(netdev_notify_peers); |