Commit 023cae85 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'locked-version-of-netdev_notify_peers'

Lijun Pan says:

====================
add a locked version of netdev_notify_peers

This series introduce the lockless version of netdev_notify_peers
and then apply it to the relevant drivers.

In v1, a more appropriate name __netdev_notify_peers is used;
netdev_notify_peers is converted to call the new helper.
In v2, patch 3 calls the new helper where notify variable used
to be set true.
====================

Link: https://lore.kernel.org/r/20201214211930.80778-1-ljp@linux.ibm.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 322e53d1 935d8a0a
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -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)
+4 −7
Original line number Diff line number Diff line
@@ -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.
	 */
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+20 −2
Original line number Diff line number Diff line
@@ -1456,6 +1456,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);