aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_alb.c
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2008-01-17 19:24:59 -0500
committerJeff Garzik <jeff@garzik.org>2008-01-18 14:38:38 -0500
commit2543331d367c9fe54f4ba73300894bc21e0a08f4 (patch)
tree83c43c448b7f18541dbe70ca4ff80138f8e695d4 /drivers/net/bonding/bond_alb.c
parente0138a66e18c6755ee29ce13b3f1142af775dc5f (diff)
bonding: fix locking during alb failover and slave removal
alb_fasten_mac_swap (actually rlb_teach_disabled_mac_on_primary) requries RTNL and no other locks. This could cause dev_set_promiscuity and/or dev_set_mac_address to be called with improper locking. Changed callers to hold only RTNL during calls to alb_fasten_mac_swap or functions calling it. Updated header comments in affected functions to reflect proper reality of locking requirements. Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/bonding/bond_alb.c')
-rw-r--r--drivers/net/bonding/bond_alb.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 9b55a123c08f..b57bc9467dbe 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -979,7 +979,7 @@ static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct
979/* 979/*
980 * Send learning packets after MAC address swap. 980 * Send learning packets after MAC address swap.
981 * 981 *
982 * Called with RTNL and bond->lock held for read. 982 * Called with RTNL and no other locks
983 */ 983 */
984static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1, 984static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
985 struct slave *slave2) 985 struct slave *slave2)
@@ -987,6 +987,8 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
987 int slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2)); 987 int slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
988 struct slave *disabled_slave = NULL; 988 struct slave *disabled_slave = NULL;
989 989
990 ASSERT_RTNL();
991
990 /* fasten the change in the switch */ 992 /* fasten the change in the switch */
991 if (SLAVE_IS_OK(slave1)) { 993 if (SLAVE_IS_OK(slave1)) {
992 alb_send_learning_packets(slave1, slave1->dev->dev_addr); 994 alb_send_learning_packets(slave1, slave1->dev->dev_addr);
@@ -1031,7 +1033,7 @@ static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
1031 * a slave that has @slave's permanet address as its current address. 1033 * a slave that has @slave's permanet address as its current address.
1032 * We'll make sure that that slave no longer uses @slave's permanent address. 1034 * We'll make sure that that slave no longer uses @slave's permanent address.
1033 * 1035 *
1034 * Caller must hold bond lock 1036 * Caller must hold RTNL and no other locks
1035 */ 1037 */
1036static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave) 1038static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
1037{ 1039{
@@ -1542,7 +1544,12 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
1542 return 0; 1544 return 0;
1543} 1545}
1544 1546
1545/* Caller must hold bond lock for write */ 1547/*
1548 * Remove slave from tlb and rlb hash tables, and fix up MAC addresses
1549 * if necessary.
1550 *
1551 * Caller must hold RTNL and no other locks
1552 */
1546void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave) 1553void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
1547{ 1554{
1548 if (bond->slave_cnt > 1) { 1555 if (bond->slave_cnt > 1) {
@@ -1658,12 +1665,11 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
1658 bond->alb_info.rlb_enabled); 1665 bond->alb_info.rlb_enabled);
1659 } 1666 }
1660 1667
1661 read_lock(&bond->lock);
1662
1663 if (swap_slave) { 1668 if (swap_slave) {
1664 alb_fasten_mac_swap(bond, swap_slave, new_slave); 1669 alb_fasten_mac_swap(bond, swap_slave, new_slave);
1670 read_lock(&bond->lock);
1665 } else { 1671 } else {
1666 /* fasten bond mac on new current slave */ 1672 read_lock(&bond->lock);
1667 alb_send_learning_packets(new_slave, bond->dev->dev_addr); 1673 alb_send_learning_packets(new_slave, bond->dev->dev_addr);
1668 } 1674 }
1669 1675