aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2007-10-17 20:37:49 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-23 20:32:00 -0400
commit059fe7a578fba5bbb0fdc0365bfcf6218fa25eb0 (patch)
tree02e508e0094f93a318ead711cf7fe6725e8bf7fe /drivers/net/bonding/bond_main.c
parent0b0eef66419e9abe6fd62bc958ab7cd0a18f858e (diff)
bonding: Convert locks to _bh, rework alb locking for new locking
Convert locking-related activity to new & improved system. Convert some lock acquisitions to _bh and rework parts of ALB mode, both to avoid deadlocks with workqueue activity. Signed-off-by: Andy Gospodarek <andy@greyhouse.net> Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c78
1 files changed, 54 insertions, 24 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a3577271b1b8..15c1f7ad222b 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1590,15 +1590,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1590 case BOND_MODE_TLB: 1590 case BOND_MODE_TLB:
1591 case BOND_MODE_ALB: 1591 case BOND_MODE_ALB:
1592 new_slave->state = BOND_STATE_ACTIVE; 1592 new_slave->state = BOND_STATE_ACTIVE;
1593 if ((!bond->curr_active_slave) && 1593 bond_set_slave_inactive_flags(new_slave);
1594 (new_slave->link != BOND_LINK_DOWN)) {
1595 /* first slave or no active slave yet, and this link
1596 * is OK, so make this interface the active one
1597 */
1598 bond_change_active_slave(bond, new_slave);
1599 } else {
1600 bond_set_slave_inactive_flags(new_slave);
1601 }
1602 break; 1594 break;
1603 default: 1595 default:
1604 dprintk("This slave is always active in trunk mode\n"); 1596 dprintk("This slave is always active in trunk mode\n");
@@ -1754,9 +1746,23 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1754 bond_alb_deinit_slave(bond, slave); 1746 bond_alb_deinit_slave(bond, slave);
1755 } 1747 }
1756 1748
1757 if (oldcurrent == slave) 1749 if (oldcurrent == slave) {
1750 /*
1751 * Note that we hold RTNL over this sequence, so there
1752 * is no concern that another slave add/remove event
1753 * will interfere.
1754 */
1755 write_unlock_bh(&bond->lock);
1756 read_lock(&bond->lock);
1757 write_lock_bh(&bond->curr_slave_lock);
1758
1758 bond_select_active_slave(bond); 1759 bond_select_active_slave(bond);
1759 1760
1761 write_unlock_bh(&bond->curr_slave_lock);
1762 read_unlock(&bond->lock);
1763 write_lock_bh(&bond->lock);
1764 }
1765
1760 if (bond->slave_cnt == 0) { 1766 if (bond->slave_cnt == 0) {
1761 bond_set_carrier(bond); 1767 bond_set_carrier(bond);
1762 1768
@@ -2012,16 +2018,19 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
2012 return -EINVAL; 2018 return -EINVAL;
2013 } 2019 }
2014 2020
2015 write_lock_bh(&bond->lock); 2021 read_lock(&bond->lock);
2016 2022
2023 read_lock(&bond->curr_slave_lock);
2017 old_active = bond->curr_active_slave; 2024 old_active = bond->curr_active_slave;
2025 read_unlock(&bond->curr_slave_lock);
2026
2018 new_active = bond_get_slave_by_dev(bond, slave_dev); 2027 new_active = bond_get_slave_by_dev(bond, slave_dev);
2019 2028
2020 /* 2029 /*
2021 * Changing to the current active: do nothing; return success. 2030 * Changing to the current active: do nothing; return success.
2022 */ 2031 */
2023 if (new_active && (new_active == old_active)) { 2032 if (new_active && (new_active == old_active)) {
2024 write_unlock_bh(&bond->lock); 2033 read_unlock(&bond->lock);
2025 return 0; 2034 return 0;
2026 } 2035 }
2027 2036
@@ -2029,12 +2038,14 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
2029 (old_active) && 2038 (old_active) &&
2030 (new_active->link == BOND_LINK_UP) && 2039 (new_active->link == BOND_LINK_UP) &&
2031 IS_UP(new_active->dev)) { 2040 IS_UP(new_active->dev)) {
2041 write_lock_bh(&bond->curr_slave_lock);
2032 bond_change_active_slave(bond, new_active); 2042 bond_change_active_slave(bond, new_active);
2043 write_unlock_bh(&bond->curr_slave_lock);
2033 } else { 2044 } else {
2034 res = -EINVAL; 2045 res = -EINVAL;
2035 } 2046 }
2036 2047
2037 write_unlock_bh(&bond->lock); 2048 read_unlock(&bond->lock);
2038 2049
2039 return res; 2050 return res;
2040} 2051}
@@ -2140,7 +2151,11 @@ static int __bond_mii_monitor(struct bonding *bond, int have_locks)
2140 switch (slave->link) { 2151 switch (slave->link) {
2141 case BOND_LINK_UP: /* the link was up */ 2152 case BOND_LINK_UP: /* the link was up */
2142 if (link_state == BMSR_LSTATUS) { 2153 if (link_state == BMSR_LSTATUS) {
2143 /* link stays up, nothing more to do */ 2154 if (!oldcurrent) {
2155 if (!have_locks)
2156 return 1;
2157 do_failover = 1;
2158 }
2144 break; 2159 break;
2145 } else { /* link going down */ 2160 } else { /* link going down */
2146 slave->link = BOND_LINK_FAIL; 2161 slave->link = BOND_LINK_FAIL;
@@ -2327,11 +2342,14 @@ static int __bond_mii_monitor(struct bonding *bond, int have_locks)
2327 } /* end of for */ 2342 } /* end of for */
2328 2343
2329 if (do_failover) { 2344 if (do_failover) {
2330 write_lock(&bond->curr_slave_lock); 2345 ASSERT_RTNL();
2346
2347 write_lock_bh(&bond->curr_slave_lock);
2331 2348
2332 bond_select_active_slave(bond); 2349 bond_select_active_slave(bond);
2333 2350
2334 write_unlock(&bond->curr_slave_lock); 2351 write_unlock_bh(&bond->curr_slave_lock);
2352
2335 } else 2353 } else
2336 bond_set_carrier(bond); 2354 bond_set_carrier(bond);
2337 2355
@@ -2770,11 +2788,14 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
2770 } 2788 }
2771 2789
2772 if (do_failover) { 2790 if (do_failover) {
2773 write_lock(&bond->curr_slave_lock); 2791 rtnl_lock();
2792 write_lock_bh(&bond->curr_slave_lock);
2774 2793
2775 bond_select_active_slave(bond); 2794 bond_select_active_slave(bond);
2776 2795
2777 write_unlock(&bond->curr_slave_lock); 2796 write_unlock_bh(&bond->curr_slave_lock);
2797 rtnl_unlock();
2798
2778 } 2799 }
2779 2800
2780re_arm: 2801re_arm:
@@ -2831,7 +2852,9 @@ void bond_activebackup_arp_mon(struct work_struct *work)
2831 2852
2832 slave->link = BOND_LINK_UP; 2853 slave->link = BOND_LINK_UP;
2833 2854
2834 write_lock(&bond->curr_slave_lock); 2855 rtnl_lock();
2856
2857 write_lock_bh(&bond->curr_slave_lock);
2835 2858
2836 if ((!bond->curr_active_slave) && 2859 if ((!bond->curr_active_slave) &&
2837 ((jiffies - slave->dev->trans_start) <= delta_in_ticks)) { 2860 ((jiffies - slave->dev->trans_start) <= delta_in_ticks)) {
@@ -2865,7 +2888,8 @@ void bond_activebackup_arp_mon(struct work_struct *work)
2865 slave->dev->name); 2888 slave->dev->name);
2866 } 2889 }
2867 2890
2868 write_unlock(&bond->curr_slave_lock); 2891 write_unlock_bh(&bond->curr_slave_lock);
2892 rtnl_unlock();
2869 } 2893 }
2870 } else { 2894 } else {
2871 read_lock(&bond->curr_slave_lock); 2895 read_lock(&bond->curr_slave_lock);
@@ -2935,12 +2959,15 @@ void bond_activebackup_arp_mon(struct work_struct *work)
2935 bond->dev->name, 2959 bond->dev->name,
2936 slave->dev->name); 2960 slave->dev->name);
2937 2961
2938 write_lock(&bond->curr_slave_lock); 2962 rtnl_lock();
2963 write_lock_bh(&bond->curr_slave_lock);
2939 2964
2940 bond_select_active_slave(bond); 2965 bond_select_active_slave(bond);
2941 slave = bond->curr_active_slave; 2966 slave = bond->curr_active_slave;
2942 2967
2943 write_unlock(&bond->curr_slave_lock); 2968 write_unlock_bh(&bond->curr_slave_lock);
2969
2970 rtnl_unlock();
2944 2971
2945 bond->current_arp_slave = slave; 2972 bond->current_arp_slave = slave;
2946 2973
@@ -2959,9 +2986,12 @@ void bond_activebackup_arp_mon(struct work_struct *work)
2959 bond->primary_slave->dev->name); 2986 bond->primary_slave->dev->name);
2960 2987
2961 /* primary is up so switch to it */ 2988 /* primary is up so switch to it */
2962 write_lock(&bond->curr_slave_lock); 2989 rtnl_lock();
2990 write_lock_bh(&bond->curr_slave_lock);
2963 bond_change_active_slave(bond, bond->primary_slave); 2991 bond_change_active_slave(bond, bond->primary_slave);
2964 write_unlock(&bond->curr_slave_lock); 2992 write_unlock_bh(&bond->curr_slave_lock);
2993
2994 rtnl_unlock();
2965 2995
2966 slave = bond->primary_slave; 2996 slave = bond->primary_slave;
2967 slave->jiffies = jiffies; 2997 slave->jiffies = jiffies;