Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e308a5d8 authored by David S. Miller's avatar David S. Miller
Browse files

netdev: Add netdev->addr_list_lock protection.



Add netif_addr_{lock,unlock}{,_bh}() helpers.

Use them to protect operations that operate on or read
the network device unicast and multicast address lists.

Also use them in cases where the code simply wants to
block calls into the driver's ->set_rx_mode() and
->set_multicast_list() methods.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f1f28aa3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -775,6 +775,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)

	local_irq_save(flags);
	netif_tx_lock(dev);
	netif_addr_lock(dev);
	spin_lock(&priv->lock);

	/*
@@ -851,6 +852,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
	}

	spin_unlock(&priv->lock);
	netif_addr_unlock(dev);
	netif_tx_unlock(dev);
	local_irq_restore(flags);

+2 −0
Original line number Diff line number Diff line
@@ -1134,6 +1134,7 @@ static void wq_set_multicast_list (struct work_struct *work)
	dvb_net_feed_stop(dev);
	priv->rx_mode = RX_MODE_UNI;
	netif_tx_lock_bh(dev);
	netif_addr_lock(dev);

	if (dev->flags & IFF_PROMISC) {
		dprintk("%s: promiscuous mode\n", dev->name);
@@ -1158,6 +1159,7 @@ static void wq_set_multicast_list (struct work_struct *work)
		}
	}

	netif_addr_unlock(dev);
	netif_tx_unlock_bh(dev);
	dvb_net_feed_start(dev);
}
+8 −0
Original line number Diff line number Diff line
@@ -1568,10 +1568,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
		}

		netif_tx_lock_bh(bond_dev);
		netif_addr_lock(bond_dev);
		/* upload master's mc_list to new slave */
		for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
			dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
		}
		netif_addr_unlock(bond_dev);
		netif_tx_unlock_bh(bond_dev);
	}

@@ -1937,7 +1939,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)

		/* flush master's mc_list from slave */
		netif_tx_lock_bh(bond_dev);
		netif_addr_lock(bond_dev);
		bond_mc_list_flush(bond_dev, slave_dev);
		netif_addr_unlock(bond_dev);
		netif_tx_unlock_bh(bond_dev);
	}

@@ -2060,7 +2064,9 @@ static int bond_release_all(struct net_device *bond_dev)

			/* flush master's mc_list from slave */
			netif_tx_lock_bh(bond_dev);
			netif_addr_lock(bond_dev);
			bond_mc_list_flush(bond_dev, slave_dev);
			netif_addr_unlock(bond_dev);
			netif_tx_unlock_bh(bond_dev);
		}

@@ -4674,7 +4680,9 @@ static void bond_free_all(void)

		bond_work_cancel_all(bond);
		netif_tx_lock_bh(bond_dev);
		netif_addr_lock(bond_dev);
		bond_mc_list_destroy(bond);
		netif_addr_unlock(bond_dev);
		netif_tx_unlock_bh(bond_dev);
		/* Release the bonded slaves */
		bond_release_all(bond_dev);
+16 −0
Original line number Diff line number Diff line
@@ -2831,6 +2831,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
		 */
		nv_disable_irq(dev);
		netif_tx_lock_bh(dev);
		netif_addr_lock(dev);
		spin_lock(&np->lock);
		/* stop engines */
		nv_stop_rxtx(dev);
@@ -2855,6 +2856,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
		/* restart rx engine */
		nv_start_rxtx(dev);
		spin_unlock(&np->lock);
		netif_addr_unlock(dev);
		netif_tx_unlock_bh(dev);
		nv_enable_irq(dev);
	}
@@ -2891,6 +2893,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr)

	if (netif_running(dev)) {
		netif_tx_lock_bh(dev);
		netif_addr_lock(dev);
		spin_lock_irq(&np->lock);

		/* stop rx engine */
@@ -2902,6 +2905,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr)
		/* restart rx engine */
		nv_start_rx(dev);
		spin_unlock_irq(&np->lock);
		netif_addr_unlock(dev);
		netif_tx_unlock_bh(dev);
	} else {
		nv_copy_mac_to_hw(dev);
@@ -3971,6 +3975,7 @@ static void nv_do_nic_poll(unsigned long data)
		printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
		if (netif_running(dev)) {
			netif_tx_lock_bh(dev);
			netif_addr_lock(dev);
			spin_lock(&np->lock);
			/* stop engines */
			nv_stop_rxtx(dev);
@@ -3995,6 +4000,7 @@ static void nv_do_nic_poll(unsigned long data)
			/* restart rx engine */
			nv_start_rxtx(dev);
			spin_unlock(&np->lock);
			netif_addr_unlock(dev);
			netif_tx_unlock_bh(dev);
		}
	}
@@ -4202,6 +4208,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)

		nv_disable_irq(dev);
		netif_tx_lock_bh(dev);
		netif_addr_lock(dev);
		/* with plain spinlock lockdep complains */
		spin_lock_irqsave(&np->lock, flags);
		/* stop engines */
@@ -4215,6 +4222,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
		 */
		nv_stop_rxtx(dev);
		spin_unlock_irqrestore(&np->lock, flags);
		netif_addr_unlock(dev);
		netif_tx_unlock_bh(dev);
	}

@@ -4360,10 +4368,12 @@ static int nv_nway_reset(struct net_device *dev)
		if (netif_running(dev)) {
			nv_disable_irq(dev);
			netif_tx_lock_bh(dev);
			netif_addr_lock(dev);
			spin_lock(&np->lock);
			/* stop engines */
			nv_stop_rxtx(dev);
			spin_unlock(&np->lock);
			netif_addr_unlock(dev);
			netif_tx_unlock_bh(dev);
			printk(KERN_INFO "%s: link down.\n", dev->name);
		}
@@ -4471,6 +4481,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
	if (netif_running(dev)) {
		nv_disable_irq(dev);
		netif_tx_lock_bh(dev);
		netif_addr_lock(dev);
		spin_lock(&np->lock);
		/* stop engines */
		nv_stop_rxtx(dev);
@@ -4519,6 +4530,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
		/* restart engines */
		nv_start_rxtx(dev);
		spin_unlock(&np->lock);
		netif_addr_unlock(dev);
		netif_tx_unlock_bh(dev);
		nv_enable_irq(dev);
	}
@@ -4556,10 +4568,12 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam*
	if (netif_running(dev)) {
		nv_disable_irq(dev);
		netif_tx_lock_bh(dev);
		netif_addr_lock(dev);
		spin_lock(&np->lock);
		/* stop engines */
		nv_stop_rxtx(dev);
		spin_unlock(&np->lock);
		netif_addr_unlock(dev);
		netif_tx_unlock_bh(dev);
	}

@@ -4946,6 +4960,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
			napi_disable(&np->napi);
#endif
			netif_tx_lock_bh(dev);
			netif_addr_lock(dev);
			spin_lock_irq(&np->lock);
			nv_disable_hw_interrupts(dev, np->irqmask);
			if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
@@ -4959,6 +4974,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
			/* drain rx queue */
			nv_drain_rxtx(dev);
			spin_unlock_irq(&np->lock);
			netif_addr_unlock(dev);
			netif_tx_unlock_bh(dev);
		}

+2 −0
Original line number Diff line number Diff line
@@ -300,7 +300,9 @@ static int sp_set_mac_address(struct net_device *dev, void *addr)
	struct sockaddr_ax25 *sa = addr;

	netif_tx_lock_bh(dev);
	netif_addr_lock(dev);
	memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
	netif_addr_unlock(dev);
	netif_tx_unlock_bh(dev);

	return 0;
Loading