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>

authored by Jay Vosburgh and committed by Jeff Garzik 059fe7a5 0b0eef66

+117 -30
+63 -6
drivers/net/bonding/bond_alb.c
··· 959 return 0; 960 } 961 962 - /* Caller must hold bond lock for write or curr_slave_lock for write*/ 963 static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct slave *slave2) 964 { 965 - struct slave *disabled_slave = NULL; 966 u8 tmp_mac_addr[ETH_ALEN]; 967 - int slaves_state_differ; 968 - 969 - slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2)); 970 971 memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN); 972 alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled); 973 alb_set_slave_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled); 974 975 /* fasten the change in the switch */ 976 if (SLAVE_IS_OK(slave1)) { ··· 1059 } 1060 1061 if (found) { 1062 alb_swap_mac_addr(bond, slave, tmp_slave); 1063 } 1064 } 1065 } ··· 1588 * Set the bond->curr_active_slave to @new_slave and handle 1589 * mac address swapping and promiscuity changes as needed. 1590 * 1591 - * Caller must hold bond curr_slave_lock for write (or bond lock for write) 1592 */ 1593 void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave) 1594 { 1595 struct slave *swap_slave; 1596 int i; 1597 1598 if (bond->curr_active_slave == new_slave) { 1599 return; ··· 1635 } 1636 } 1637 1638 /* curr_active_slave must be set before calling alb_swap_mac_addr */ 1639 if (swap_slave) { 1640 /* swap mac address */ ··· 1656 /* set the new_slave to the bond mac address */ 1657 alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr, 1658 bond->alb_info.rlb_enabled); 1659 /* fasten bond mac on new current slave */ 1660 alb_send_learning_packets(new_slave, bond->dev->dev_addr); 1661 } 1662 } 1663 1664 int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) 1665 { 1666 struct bonding *bond = bond_dev->priv; ··· 1709 } 1710 } 1711 1712 if (swap_slave) { 1713 alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave); 1714 } else { 1715 alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr, 1716 bond->alb_info.rlb_enabled); ··· 1725 rlb_req_update_slave_clients(bond, bond->curr_active_slave); 1726 } 1727 } 1728 1729 return 0; 1730 }
··· 959 return 0; 960 } 961 962 + /* 963 + * Swap MAC addresses between two slaves. 964 + * 965 + * Called with RTNL held, and no other locks. 966 + * 967 + */ 968 + 969 static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct slave *slave2) 970 { 971 u8 tmp_mac_addr[ETH_ALEN]; 972 973 memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN); 974 alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled); 975 alb_set_slave_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled); 976 + 977 + } 978 + 979 + /* 980 + * Send learning packets after MAC address swap. 981 + * 982 + * Called with RTNL and bond->lock held for read. 983 + */ 984 + static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1, 985 + struct slave *slave2) 986 + { 987 + int slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2)); 988 + struct slave *disabled_slave = NULL; 989 990 /* fasten the change in the switch */ 991 if (SLAVE_IS_OK(slave1)) { ··· 1044 } 1045 1046 if (found) { 1047 + /* locking: needs RTNL and nothing else */ 1048 alb_swap_mac_addr(bond, slave, tmp_slave); 1049 + alb_fasten_mac_swap(bond, slave, tmp_slave); 1050 } 1051 } 1052 } ··· 1571 * Set the bond->curr_active_slave to @new_slave and handle 1572 * mac address swapping and promiscuity changes as needed. 1573 * 1574 + * If new_slave is NULL, caller must hold curr_slave_lock or 1575 + * bond->lock for write. 1576 + * 1577 + * If new_slave is not NULL, caller must hold RTNL, bond->lock for 1578 + * read and curr_slave_lock for write. Processing here may sleep, so 1579 + * no other locks may be held. 1580 */ 1581 void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave) 1582 { 1583 struct slave *swap_slave; 1584 int i; 1585 + 1586 + if (new_slave) 1587 + ASSERT_RTNL(); 1588 1589 if (bond->curr_active_slave == new_slave) { 1590 return; ··· 1610 } 1611 } 1612 1613 + /* 1614 + * Arrange for swap_slave and new_slave to temporarily be 1615 + * ignored so we can mess with their MAC addresses without 1616 + * fear of interference from transmit activity. 1617 + */ 1618 + if (swap_slave) { 1619 + tlb_clear_slave(bond, swap_slave, 1); 1620 + } 1621 + tlb_clear_slave(bond, new_slave, 1); 1622 + 1623 + write_unlock_bh(&bond->curr_slave_lock); 1624 + read_unlock(&bond->lock); 1625 + 1626 /* curr_active_slave must be set before calling alb_swap_mac_addr */ 1627 if (swap_slave) { 1628 /* swap mac address */ ··· 1618 /* set the new_slave to the bond mac address */ 1619 alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr, 1620 bond->alb_info.rlb_enabled); 1621 + } 1622 + 1623 + read_lock(&bond->lock); 1624 + 1625 + if (swap_slave) { 1626 + alb_fasten_mac_swap(bond, swap_slave, new_slave); 1627 + } else { 1628 /* fasten bond mac on new current slave */ 1629 alb_send_learning_packets(new_slave, bond->dev->dev_addr); 1630 } 1631 + 1632 + write_lock_bh(&bond->curr_slave_lock); 1633 } 1634 1635 + /* 1636 + * Called with RTNL 1637 + */ 1638 int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) 1639 { 1640 struct bonding *bond = bond_dev->priv; ··· 1659 } 1660 } 1661 1662 + write_unlock_bh(&bond->curr_slave_lock); 1663 + read_unlock(&bond->lock); 1664 + 1665 if (swap_slave) { 1666 alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave); 1667 + alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave); 1668 } else { 1669 alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr, 1670 bond->alb_info.rlb_enabled); ··· 1671 rlb_req_update_slave_clients(bond, bond->curr_active_slave); 1672 } 1673 } 1674 + 1675 + read_lock(&bond->lock); 1676 + write_lock_bh(&bond->curr_slave_lock); 1677 1678 return 0; 1679 }
+54 -24
drivers/net/bonding/bond_main.c
··· 1590 case BOND_MODE_TLB: 1591 case BOND_MODE_ALB: 1592 new_slave->state = BOND_STATE_ACTIVE; 1593 - if ((!bond->curr_active_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; 1603 default: 1604 dprintk("This slave is always active in trunk mode\n"); ··· 1746 bond_alb_deinit_slave(bond, slave); 1747 } 1748 1749 - if (oldcurrent == slave) 1750 bond_select_active_slave(bond); 1751 1752 if (bond->slave_cnt == 0) { 1753 bond_set_carrier(bond); ··· 2018 return -EINVAL; 2019 } 2020 2021 - write_lock_bh(&bond->lock); 2022 2023 old_active = bond->curr_active_slave; 2024 new_active = bond_get_slave_by_dev(bond, slave_dev); 2025 2026 /* 2027 * Changing to the current active: do nothing; return success. 2028 */ 2029 if (new_active && (new_active == old_active)) { 2030 - write_unlock_bh(&bond->lock); 2031 return 0; 2032 } 2033 ··· 2038 (old_active) && 2039 (new_active->link == BOND_LINK_UP) && 2040 IS_UP(new_active->dev)) { 2041 bond_change_active_slave(bond, new_active); 2042 } else { 2043 res = -EINVAL; 2044 } 2045 2046 - write_unlock_bh(&bond->lock); 2047 2048 return res; 2049 } ··· 2151 switch (slave->link) { 2152 case BOND_LINK_UP: /* the link was up */ 2153 if (link_state == BMSR_LSTATUS) { 2154 - /* link stays up, nothing more to do */ 2155 break; 2156 } else { /* link going down */ 2157 slave->link = BOND_LINK_FAIL; ··· 2342 } /* end of for */ 2343 2344 if (do_failover) { 2345 - write_lock(&bond->curr_slave_lock); 2346 2347 bond_select_active_slave(bond); 2348 2349 - write_unlock(&bond->curr_slave_lock); 2350 } else 2351 bond_set_carrier(bond); 2352 ··· 2788 } 2789 2790 if (do_failover) { 2791 - write_lock(&bond->curr_slave_lock); 2792 2793 bond_select_active_slave(bond); 2794 2795 - write_unlock(&bond->curr_slave_lock); 2796 } 2797 2798 re_arm: ··· 2852 2853 slave->link = BOND_LINK_UP; 2854 2855 - write_lock(&bond->curr_slave_lock); 2856 2857 if ((!bond->curr_active_slave) && 2858 ((jiffies - slave->dev->trans_start) <= delta_in_ticks)) { ··· 2888 slave->dev->name); 2889 } 2890 2891 - write_unlock(&bond->curr_slave_lock); 2892 } 2893 } else { 2894 read_lock(&bond->curr_slave_lock); ··· 2959 bond->dev->name, 2960 slave->dev->name); 2961 2962 - write_lock(&bond->curr_slave_lock); 2963 2964 bond_select_active_slave(bond); 2965 slave = bond->curr_active_slave; 2966 2967 - write_unlock(&bond->curr_slave_lock); 2968 2969 bond->current_arp_slave = slave; 2970 ··· 2986 bond->primary_slave->dev->name); 2987 2988 /* primary is up so switch to it */ 2989 - write_lock(&bond->curr_slave_lock); 2990 bond_change_active_slave(bond, bond->primary_slave); 2991 - write_unlock(&bond->curr_slave_lock); 2992 2993 slave = bond->primary_slave; 2994 slave->jiffies = jiffies;
··· 1590 case BOND_MODE_TLB: 1591 case BOND_MODE_ALB: 1592 new_slave->state = BOND_STATE_ACTIVE; 1593 + bond_set_slave_inactive_flags(new_slave); 1594 break; 1595 default: 1596 dprintk("This slave is always active in trunk mode\n"); ··· 1754 bond_alb_deinit_slave(bond, slave); 1755 } 1756 1757 + if (oldcurrent == slave) { 1758 + /* 1759 + * Note that we hold RTNL over this sequence, so there 1760 + * is no concern that another slave add/remove event 1761 + * will interfere. 1762 + */ 1763 + write_unlock_bh(&bond->lock); 1764 + read_lock(&bond->lock); 1765 + write_lock_bh(&bond->curr_slave_lock); 1766 + 1767 bond_select_active_slave(bond); 1768 + 1769 + write_unlock_bh(&bond->curr_slave_lock); 1770 + read_unlock(&bond->lock); 1771 + write_lock_bh(&bond->lock); 1772 + } 1773 1774 if (bond->slave_cnt == 0) { 1775 bond_set_carrier(bond); ··· 2012 return -EINVAL; 2013 } 2014 2015 + read_lock(&bond->lock); 2016 2017 + read_lock(&bond->curr_slave_lock); 2018 old_active = bond->curr_active_slave; 2019 + read_unlock(&bond->curr_slave_lock); 2020 + 2021 new_active = bond_get_slave_by_dev(bond, slave_dev); 2022 2023 /* 2024 * Changing to the current active: do nothing; return success. 2025 */ 2026 if (new_active && (new_active == old_active)) { 2027 + read_unlock(&bond->lock); 2028 return 0; 2029 } 2030 ··· 2029 (old_active) && 2030 (new_active->link == BOND_LINK_UP) && 2031 IS_UP(new_active->dev)) { 2032 + write_lock_bh(&bond->curr_slave_lock); 2033 bond_change_active_slave(bond, new_active); 2034 + write_unlock_bh(&bond->curr_slave_lock); 2035 } else { 2036 res = -EINVAL; 2037 } 2038 2039 + read_unlock(&bond->lock); 2040 2041 return res; 2042 } ··· 2140 switch (slave->link) { 2141 case BOND_LINK_UP: /* the link was up */ 2142 if (link_state == BMSR_LSTATUS) { 2143 + if (!oldcurrent) { 2144 + if (!have_locks) 2145 + return 1; 2146 + do_failover = 1; 2147 + } 2148 break; 2149 } else { /* link going down */ 2150 slave->link = BOND_LINK_FAIL; ··· 2327 } /* end of for */ 2328 2329 if (do_failover) { 2330 + ASSERT_RTNL(); 2331 + 2332 + write_lock_bh(&bond->curr_slave_lock); 2333 2334 bond_select_active_slave(bond); 2335 2336 + write_unlock_bh(&bond->curr_slave_lock); 2337 + 2338 } else 2339 bond_set_carrier(bond); 2340 ··· 2770 } 2771 2772 if (do_failover) { 2773 + rtnl_lock(); 2774 + write_lock_bh(&bond->curr_slave_lock); 2775 2776 bond_select_active_slave(bond); 2777 2778 + write_unlock_bh(&bond->curr_slave_lock); 2779 + rtnl_unlock(); 2780 + 2781 } 2782 2783 re_arm: ··· 2831 2832 slave->link = BOND_LINK_UP; 2833 2834 + rtnl_lock(); 2835 + 2836 + write_lock_bh(&bond->curr_slave_lock); 2837 2838 if ((!bond->curr_active_slave) && 2839 ((jiffies - slave->dev->trans_start) <= delta_in_ticks)) { ··· 2865 slave->dev->name); 2866 } 2867 2868 + write_unlock_bh(&bond->curr_slave_lock); 2869 + rtnl_unlock(); 2870 } 2871 } else { 2872 read_lock(&bond->curr_slave_lock); ··· 2935 bond->dev->name, 2936 slave->dev->name); 2937 2938 + rtnl_lock(); 2939 + write_lock_bh(&bond->curr_slave_lock); 2940 2941 bond_select_active_slave(bond); 2942 slave = bond->curr_active_slave; 2943 2944 + write_unlock_bh(&bond->curr_slave_lock); 2945 + 2946 + rtnl_unlock(); 2947 2948 bond->current_arp_slave = slave; 2949 ··· 2959 bond->primary_slave->dev->name); 2960 2961 /* primary is up so switch to it */ 2962 + rtnl_lock(); 2963 + write_lock_bh(&bond->curr_slave_lock); 2964 bond_change_active_slave(bond, bond->primary_slave); 2965 + write_unlock_bh(&bond->curr_slave_lock); 2966 + 2967 + rtnl_unlock(); 2968 2969 slave = bond->primary_slave; 2970 slave->jiffies = jiffies;