aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2008-01-29 21:07:44 -0500
committerDavid S. Miller <davem@davemloft.net>2008-02-03 07:28:12 -0500
commit80ee5ad23150f1f3fe8d35728e860850ccea44da (patch)
tree4bab44a6762a87c59ba22ab688326f1a6fe075a1
parenta42e534f1b6be7f2f68f83d29588c3f2736b4d25 (diff)
bonding: fix set_multicast_list locking
This patch eliminates a problem (reported by lockdep) in the bond_set_multicast_list function. It first reduces the locking on bond->lock to a simple read_lock, and second, adds netif_tx locking around the bonding mc_list manipulations that occur outside of the set_multicast_list function. The original problem was related to IPv6 addrconf activity. Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bonding/bond_main.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2766855a5ae..65c7ebafaac 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1464,10 +1464,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1464 dev_set_allmulti(slave_dev, 1); 1464 dev_set_allmulti(slave_dev, 1);
1465 } 1465 }
1466 1466
1467 netif_tx_lock_bh(bond_dev);
1467 /* upload master's mc_list to new slave */ 1468 /* upload master's mc_list to new slave */
1468 for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) { 1469 for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
1469 dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); 1470 dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
1470 } 1471 }
1472 netif_tx_unlock_bh(bond_dev);
1471 } 1473 }
1472 1474
1473 if (bond->params.mode == BOND_MODE_8023AD) { 1475 if (bond->params.mode == BOND_MODE_8023AD) {
@@ -1821,7 +1823,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1821 } 1823 }
1822 1824
1823 /* flush master's mc_list from slave */ 1825 /* flush master's mc_list from slave */
1826 netif_tx_lock_bh(bond_dev);
1824 bond_mc_list_flush(bond_dev, slave_dev); 1827 bond_mc_list_flush(bond_dev, slave_dev);
1828 netif_tx_unlock_bh(bond_dev);
1825 } 1829 }
1826 1830
1827 netdev_set_master(slave_dev, NULL); 1831 netdev_set_master(slave_dev, NULL);
@@ -1942,7 +1946,9 @@ static int bond_release_all(struct net_device *bond_dev)
1942 } 1946 }
1943 1947
1944 /* flush master's mc_list from slave */ 1948 /* flush master's mc_list from slave */
1949 netif_tx_lock_bh(bond_dev);
1945 bond_mc_list_flush(bond_dev, slave_dev); 1950 bond_mc_list_flush(bond_dev, slave_dev);
1951 netif_tx_unlock_bh(bond_dev);
1946 } 1952 }
1947 1953
1948 netdev_set_master(slave_dev, NULL); 1954 netdev_set_master(slave_dev, NULL);
@@ -3937,8 +3943,6 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
3937 struct bonding *bond = bond_dev->priv; 3943 struct bonding *bond = bond_dev->priv;
3938 struct dev_mc_list *dmi; 3944 struct dev_mc_list *dmi;
3939 3945
3940 write_lock_bh(&bond->lock);
3941
3942 /* 3946 /*
3943 * Do promisc before checking multicast_mode 3947 * Do promisc before checking multicast_mode
3944 */ 3948 */
@@ -3959,6 +3963,8 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
3959 bond_set_allmulti(bond, -1); 3963 bond_set_allmulti(bond, -1);
3960 } 3964 }
3961 3965
3966 read_lock(&bond->lock);
3967
3962 bond->flags = bond_dev->flags; 3968 bond->flags = bond_dev->flags;
3963 3969
3964 /* looking for addresses to add to slaves' mc list */ 3970 /* looking for addresses to add to slaves' mc list */
@@ -3979,7 +3985,7 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
3979 bond_mc_list_destroy(bond); 3985 bond_mc_list_destroy(bond);
3980 bond_mc_list_copy(bond_dev->mc_list, bond, GFP_ATOMIC); 3986 bond_mc_list_copy(bond_dev->mc_list, bond, GFP_ATOMIC);
3981 3987
3982 write_unlock_bh(&bond->lock); 3988 read_unlock(&bond->lock);
3983} 3989}
3984 3990
3985/* 3991/*
@@ -4526,7 +4532,9 @@ static void bond_free_all(void)
4526 struct net_device *bond_dev = bond->dev; 4532 struct net_device *bond_dev = bond->dev;
4527 4533
4528 bond_work_cancel_all(bond); 4534 bond_work_cancel_all(bond);
4535 netif_tx_lock_bh(bond_dev);
4529 bond_mc_list_destroy(bond); 4536 bond_mc_list_destroy(bond);
4537 netif_tx_unlock_bh(bond_dev);
4530 /* Release the bonded slaves */ 4538 /* Release the bonded slaves */
4531 bond_release_all(bond_dev); 4539 bond_release_all(bond_dev);
4532 bond_deinit(bond_dev); 4540 bond_deinit(bond_dev);