diff options
author | David S. Miller <davem@davemloft.net> | 2008-07-15 03:13:44 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-15 03:13:44 -0400 |
commit | e308a5d806c852f56590ffdd3834d0df0cbed8d7 (patch) | |
tree | 294ff654e90950f5162737c26f4799b0b710b748 /drivers/net | |
parent | f1f28aa3510ddb84c966bac65611bb866c77a092 (diff) |
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: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 8 | ||||
-rw-r--r-- | drivers/net/forcedeth.c | 16 | ||||
-rw-r--r-- | drivers/net/hamradio/6pack.c | 2 | ||||
-rw-r--r-- | drivers/net/hamradio/mkiss.c | 2 | ||||
-rw-r--r-- | drivers/net/ibm_newemac/core.c | 4 | ||||
-rw-r--r-- | drivers/net/sfc/efx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/libertas/main.c | 2 |
7 files changed, 36 insertions, 0 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 8ae7ff313218..ea71abd6f728 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1568,10 +1568,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1568 | } | 1568 | } |
1569 | 1569 | ||
1570 | netif_tx_lock_bh(bond_dev); | 1570 | netif_tx_lock_bh(bond_dev); |
1571 | netif_addr_lock(bond_dev); | ||
1571 | /* upload master's mc_list to new slave */ | 1572 | /* upload master's mc_list to new slave */ |
1572 | for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) { | 1573 | for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) { |
1573 | dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); | 1574 | dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); |
1574 | } | 1575 | } |
1576 | netif_addr_unlock(bond_dev); | ||
1575 | netif_tx_unlock_bh(bond_dev); | 1577 | netif_tx_unlock_bh(bond_dev); |
1576 | } | 1578 | } |
1577 | 1579 | ||
@@ -1937,7 +1939,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1937 | 1939 | ||
1938 | /* flush master's mc_list from slave */ | 1940 | /* flush master's mc_list from slave */ |
1939 | netif_tx_lock_bh(bond_dev); | 1941 | netif_tx_lock_bh(bond_dev); |
1942 | netif_addr_lock(bond_dev); | ||
1940 | bond_mc_list_flush(bond_dev, slave_dev); | 1943 | bond_mc_list_flush(bond_dev, slave_dev); |
1944 | netif_addr_unlock(bond_dev); | ||
1941 | netif_tx_unlock_bh(bond_dev); | 1945 | netif_tx_unlock_bh(bond_dev); |
1942 | } | 1946 | } |
1943 | 1947 | ||
@@ -2060,7 +2064,9 @@ static int bond_release_all(struct net_device *bond_dev) | |||
2060 | 2064 | ||
2061 | /* flush master's mc_list from slave */ | 2065 | /* flush master's mc_list from slave */ |
2062 | netif_tx_lock_bh(bond_dev); | 2066 | netif_tx_lock_bh(bond_dev); |
2067 | netif_addr_lock(bond_dev); | ||
2063 | bond_mc_list_flush(bond_dev, slave_dev); | 2068 | bond_mc_list_flush(bond_dev, slave_dev); |
2069 | netif_addr_unlock(bond_dev); | ||
2064 | netif_tx_unlock_bh(bond_dev); | 2070 | netif_tx_unlock_bh(bond_dev); |
2065 | } | 2071 | } |
2066 | 2072 | ||
@@ -4674,7 +4680,9 @@ static void bond_free_all(void) | |||
4674 | 4680 | ||
4675 | bond_work_cancel_all(bond); | 4681 | bond_work_cancel_all(bond); |
4676 | netif_tx_lock_bh(bond_dev); | 4682 | netif_tx_lock_bh(bond_dev); |
4683 | netif_addr_lock(bond_dev); | ||
4677 | bond_mc_list_destroy(bond); | 4684 | bond_mc_list_destroy(bond); |
4685 | netif_addr_unlock(bond_dev); | ||
4678 | netif_tx_unlock_bh(bond_dev); | 4686 | netif_tx_unlock_bh(bond_dev); |
4679 | /* Release the bonded slaves */ | 4687 | /* Release the bonded slaves */ |
4680 | bond_release_all(bond_dev); | 4688 | bond_release_all(bond_dev); |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 786d668c612e..4ed89fa9ae46 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -2831,6 +2831,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) | |||
2831 | */ | 2831 | */ |
2832 | nv_disable_irq(dev); | 2832 | nv_disable_irq(dev); |
2833 | netif_tx_lock_bh(dev); | 2833 | netif_tx_lock_bh(dev); |
2834 | netif_addr_lock(dev); | ||
2834 | spin_lock(&np->lock); | 2835 | spin_lock(&np->lock); |
2835 | /* stop engines */ | 2836 | /* stop engines */ |
2836 | nv_stop_rxtx(dev); | 2837 | nv_stop_rxtx(dev); |
@@ -2855,6 +2856,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu) | |||
2855 | /* restart rx engine */ | 2856 | /* restart rx engine */ |
2856 | nv_start_rxtx(dev); | 2857 | nv_start_rxtx(dev); |
2857 | spin_unlock(&np->lock); | 2858 | spin_unlock(&np->lock); |
2859 | netif_addr_unlock(dev); | ||
2858 | netif_tx_unlock_bh(dev); | 2860 | netif_tx_unlock_bh(dev); |
2859 | nv_enable_irq(dev); | 2861 | nv_enable_irq(dev); |
2860 | } | 2862 | } |
@@ -2891,6 +2893,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) | |||
2891 | 2893 | ||
2892 | if (netif_running(dev)) { | 2894 | if (netif_running(dev)) { |
2893 | netif_tx_lock_bh(dev); | 2895 | netif_tx_lock_bh(dev); |
2896 | netif_addr_lock(dev); | ||
2894 | spin_lock_irq(&np->lock); | 2897 | spin_lock_irq(&np->lock); |
2895 | 2898 | ||
2896 | /* stop rx engine */ | 2899 | /* stop rx engine */ |
@@ -2902,6 +2905,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr) | |||
2902 | /* restart rx engine */ | 2905 | /* restart rx engine */ |
2903 | nv_start_rx(dev); | 2906 | nv_start_rx(dev); |
2904 | spin_unlock_irq(&np->lock); | 2907 | spin_unlock_irq(&np->lock); |
2908 | netif_addr_unlock(dev); | ||
2905 | netif_tx_unlock_bh(dev); | 2909 | netif_tx_unlock_bh(dev); |
2906 | } else { | 2910 | } else { |
2907 | nv_copy_mac_to_hw(dev); | 2911 | nv_copy_mac_to_hw(dev); |
@@ -3971,6 +3975,7 @@ static void nv_do_nic_poll(unsigned long data) | |||
3971 | printk(KERN_INFO "forcedeth: MAC in recoverable error state\n"); | 3975 | printk(KERN_INFO "forcedeth: MAC in recoverable error state\n"); |
3972 | if (netif_running(dev)) { | 3976 | if (netif_running(dev)) { |
3973 | netif_tx_lock_bh(dev); | 3977 | netif_tx_lock_bh(dev); |
3978 | netif_addr_lock(dev); | ||
3974 | spin_lock(&np->lock); | 3979 | spin_lock(&np->lock); |
3975 | /* stop engines */ | 3980 | /* stop engines */ |
3976 | nv_stop_rxtx(dev); | 3981 | nv_stop_rxtx(dev); |
@@ -3995,6 +4000,7 @@ static void nv_do_nic_poll(unsigned long data) | |||
3995 | /* restart rx engine */ | 4000 | /* restart rx engine */ |
3996 | nv_start_rxtx(dev); | 4001 | nv_start_rxtx(dev); |
3997 | spin_unlock(&np->lock); | 4002 | spin_unlock(&np->lock); |
4003 | netif_addr_unlock(dev); | ||
3998 | netif_tx_unlock_bh(dev); | 4004 | netif_tx_unlock_bh(dev); |
3999 | } | 4005 | } |
4000 | } | 4006 | } |
@@ -4202,6 +4208,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
4202 | 4208 | ||
4203 | nv_disable_irq(dev); | 4209 | nv_disable_irq(dev); |
4204 | netif_tx_lock_bh(dev); | 4210 | netif_tx_lock_bh(dev); |
4211 | netif_addr_lock(dev); | ||
4205 | /* with plain spinlock lockdep complains */ | 4212 | /* with plain spinlock lockdep complains */ |
4206 | spin_lock_irqsave(&np->lock, flags); | 4213 | spin_lock_irqsave(&np->lock, flags); |
4207 | /* stop engines */ | 4214 | /* stop engines */ |
@@ -4215,6 +4222,7 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
4215 | */ | 4222 | */ |
4216 | nv_stop_rxtx(dev); | 4223 | nv_stop_rxtx(dev); |
4217 | spin_unlock_irqrestore(&np->lock, flags); | 4224 | spin_unlock_irqrestore(&np->lock, flags); |
4225 | netif_addr_unlock(dev); | ||
4218 | netif_tx_unlock_bh(dev); | 4226 | netif_tx_unlock_bh(dev); |
4219 | } | 4227 | } |
4220 | 4228 | ||
@@ -4360,10 +4368,12 @@ static int nv_nway_reset(struct net_device *dev) | |||
4360 | if (netif_running(dev)) { | 4368 | if (netif_running(dev)) { |
4361 | nv_disable_irq(dev); | 4369 | nv_disable_irq(dev); |
4362 | netif_tx_lock_bh(dev); | 4370 | netif_tx_lock_bh(dev); |
4371 | netif_addr_lock(dev); | ||
4363 | spin_lock(&np->lock); | 4372 | spin_lock(&np->lock); |
4364 | /* stop engines */ | 4373 | /* stop engines */ |
4365 | nv_stop_rxtx(dev); | 4374 | nv_stop_rxtx(dev); |
4366 | spin_unlock(&np->lock); | 4375 | spin_unlock(&np->lock); |
4376 | netif_addr_unlock(dev); | ||
4367 | netif_tx_unlock_bh(dev); | 4377 | netif_tx_unlock_bh(dev); |
4368 | printk(KERN_INFO "%s: link down.\n", dev->name); | 4378 | printk(KERN_INFO "%s: link down.\n", dev->name); |
4369 | } | 4379 | } |
@@ -4471,6 +4481,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri | |||
4471 | if (netif_running(dev)) { | 4481 | if (netif_running(dev)) { |
4472 | nv_disable_irq(dev); | 4482 | nv_disable_irq(dev); |
4473 | netif_tx_lock_bh(dev); | 4483 | netif_tx_lock_bh(dev); |
4484 | netif_addr_lock(dev); | ||
4474 | spin_lock(&np->lock); | 4485 | spin_lock(&np->lock); |
4475 | /* stop engines */ | 4486 | /* stop engines */ |
4476 | nv_stop_rxtx(dev); | 4487 | nv_stop_rxtx(dev); |
@@ -4519,6 +4530,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri | |||
4519 | /* restart engines */ | 4530 | /* restart engines */ |
4520 | nv_start_rxtx(dev); | 4531 | nv_start_rxtx(dev); |
4521 | spin_unlock(&np->lock); | 4532 | spin_unlock(&np->lock); |
4533 | netif_addr_unlock(dev); | ||
4522 | netif_tx_unlock_bh(dev); | 4534 | netif_tx_unlock_bh(dev); |
4523 | nv_enable_irq(dev); | 4535 | nv_enable_irq(dev); |
4524 | } | 4536 | } |
@@ -4556,10 +4568,12 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* | |||
4556 | if (netif_running(dev)) { | 4568 | if (netif_running(dev)) { |
4557 | nv_disable_irq(dev); | 4569 | nv_disable_irq(dev); |
4558 | netif_tx_lock_bh(dev); | 4570 | netif_tx_lock_bh(dev); |
4571 | netif_addr_lock(dev); | ||
4559 | spin_lock(&np->lock); | 4572 | spin_lock(&np->lock); |
4560 | /* stop engines */ | 4573 | /* stop engines */ |
4561 | nv_stop_rxtx(dev); | 4574 | nv_stop_rxtx(dev); |
4562 | spin_unlock(&np->lock); | 4575 | spin_unlock(&np->lock); |
4576 | netif_addr_unlock(dev); | ||
4563 | netif_tx_unlock_bh(dev); | 4577 | netif_tx_unlock_bh(dev); |
4564 | } | 4578 | } |
4565 | 4579 | ||
@@ -4946,6 +4960,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 | |||
4946 | napi_disable(&np->napi); | 4960 | napi_disable(&np->napi); |
4947 | #endif | 4961 | #endif |
4948 | netif_tx_lock_bh(dev); | 4962 | netif_tx_lock_bh(dev); |
4963 | netif_addr_lock(dev); | ||
4949 | spin_lock_irq(&np->lock); | 4964 | spin_lock_irq(&np->lock); |
4950 | nv_disable_hw_interrupts(dev, np->irqmask); | 4965 | nv_disable_hw_interrupts(dev, np->irqmask); |
4951 | if (!(np->msi_flags & NV_MSI_X_ENABLED)) { | 4966 | 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 | |||
4959 | /* drain rx queue */ | 4974 | /* drain rx queue */ |
4960 | nv_drain_rxtx(dev); | 4975 | nv_drain_rxtx(dev); |
4961 | spin_unlock_irq(&np->lock); | 4976 | spin_unlock_irq(&np->lock); |
4977 | netif_addr_unlock(dev); | ||
4962 | netif_tx_unlock_bh(dev); | 4978 | netif_tx_unlock_bh(dev); |
4963 | } | 4979 | } |
4964 | 4980 | ||
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 06ad9f302b5a..ffc937f5d15d 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -300,7 +300,9 @@ static int sp_set_mac_address(struct net_device *dev, void *addr) | |||
300 | struct sockaddr_ax25 *sa = addr; | 300 | struct sockaddr_ax25 *sa = addr; |
301 | 301 | ||
302 | netif_tx_lock_bh(dev); | 302 | netif_tx_lock_bh(dev); |
303 | netif_addr_lock(dev); | ||
303 | memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); | 304 | memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); |
305 | netif_addr_unlock(dev); | ||
304 | netif_tx_unlock_bh(dev); | 306 | netif_tx_unlock_bh(dev); |
305 | 307 | ||
306 | return 0; | 308 | return 0; |
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 65166035aca0..b8740e6a5cec 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -356,7 +356,9 @@ static int ax_set_mac_address(struct net_device *dev, void *addr) | |||
356 | struct sockaddr_ax25 *sa = addr; | 356 | struct sockaddr_ax25 *sa = addr; |
357 | 357 | ||
358 | netif_tx_lock_bh(dev); | 358 | netif_tx_lock_bh(dev); |
359 | netif_addr_lock(dev); | ||
359 | memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); | 360 | memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); |
361 | netif_addr_unlock(dev); | ||
360 | netif_tx_unlock_bh(dev); | 362 | netif_tx_unlock_bh(dev); |
361 | 363 | ||
362 | return 0; | 364 | return 0; |
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index babc79ad490b..9ca57d365599 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c | |||
@@ -295,7 +295,9 @@ static void emac_rx_disable(struct emac_instance *dev) | |||
295 | static inline void emac_netif_stop(struct emac_instance *dev) | 295 | static inline void emac_netif_stop(struct emac_instance *dev) |
296 | { | 296 | { |
297 | netif_tx_lock_bh(dev->ndev); | 297 | netif_tx_lock_bh(dev->ndev); |
298 | netif_addr_lock(dev->ndev); | ||
298 | dev->no_mcast = 1; | 299 | dev->no_mcast = 1; |
300 | netif_addr_unlock(dev->ndev); | ||
299 | netif_tx_unlock_bh(dev->ndev); | 301 | netif_tx_unlock_bh(dev->ndev); |
300 | dev->ndev->trans_start = jiffies; /* prevent tx timeout */ | 302 | dev->ndev->trans_start = jiffies; /* prevent tx timeout */ |
301 | mal_poll_disable(dev->mal, &dev->commac); | 303 | mal_poll_disable(dev->mal, &dev->commac); |
@@ -305,9 +307,11 @@ static inline void emac_netif_stop(struct emac_instance *dev) | |||
305 | static inline void emac_netif_start(struct emac_instance *dev) | 307 | static inline void emac_netif_start(struct emac_instance *dev) |
306 | { | 308 | { |
307 | netif_tx_lock_bh(dev->ndev); | 309 | netif_tx_lock_bh(dev->ndev); |
310 | netif_addr_lock(dev->ndev); | ||
308 | dev->no_mcast = 0; | 311 | dev->no_mcast = 0; |
309 | if (dev->mcast_pending && netif_running(dev->ndev)) | 312 | if (dev->mcast_pending && netif_running(dev->ndev)) |
310 | __emac_set_multicast_list(dev); | 313 | __emac_set_multicast_list(dev); |
314 | netif_addr_unlock(dev->ndev); | ||
311 | netif_tx_unlock_bh(dev->ndev); | 315 | netif_tx_unlock_bh(dev->ndev); |
312 | 316 | ||
313 | netif_wake_queue(dev->ndev); | 317 | netif_wake_queue(dev->ndev); |
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 74265d8553b8..e1257e556e48 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -697,6 +697,8 @@ static void efx_stop_port(struct efx_nic *efx) | |||
697 | /* Serialise against efx_set_multicast_list() */ | 697 | /* Serialise against efx_set_multicast_list() */ |
698 | if (efx_dev_registered(efx)) { | 698 | if (efx_dev_registered(efx)) { |
699 | netif_tx_lock_bh(efx->net_dev); | 699 | netif_tx_lock_bh(efx->net_dev); |
700 | netif_addr_lock(efx->net_dev); | ||
701 | netif_addr_unlock(efx->net_dev); | ||
700 | netif_tx_unlock_bh(efx->net_dev); | 702 | netif_tx_unlock_bh(efx->net_dev); |
701 | } | 703 | } |
702 | } | 704 | } |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index abd6d9ed8f4b..42e9b2771eab 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -594,6 +594,7 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd, | |||
594 | return nr_addrs; | 594 | return nr_addrs; |
595 | 595 | ||
596 | netif_tx_lock_bh(dev); | 596 | netif_tx_lock_bh(dev); |
597 | netif_addr_lock(dev); | ||
597 | for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) { | 598 | for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) { |
598 | if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) { | 599 | if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) { |
599 | lbs_deb_net("mcast address %s:%s skipped\n", dev->name, | 600 | lbs_deb_net("mcast address %s:%s skipped\n", dev->name, |
@@ -608,6 +609,7 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd, | |||
608 | print_mac(mac, mc_list->dmi_addr)); | 609 | print_mac(mac, mc_list->dmi_addr)); |
609 | i++; | 610 | i++; |
610 | } | 611 | } |
612 | netif_addr_unlock(dev); | ||
611 | netif_tx_unlock_bh(dev); | 613 | netif_tx_unlock_bh(dev); |
612 | if (mc_list) | 614 | if (mc_list) |
613 | return -EOVERFLOW; | 615 | return -EOVERFLOW; |