aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c27
1 files changed, 6 insertions, 21 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index bad1bf949546..1b1dd01fbf72 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1589,11 +1589,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1589 bond_set_carrier(bond); 1589 bond_set_carrier(bond);
1590 1590
1591 if (USES_PRIMARY(bond->params.mode)) { 1591 if (USES_PRIMARY(bond->params.mode)) {
1592 read_lock(&bond->lock);
1593 write_lock_bh(&bond->curr_slave_lock); 1592 write_lock_bh(&bond->curr_slave_lock);
1594 bond_select_active_slave(bond); 1593 bond_select_active_slave(bond);
1595 write_unlock_bh(&bond->curr_slave_lock); 1594 write_unlock_bh(&bond->curr_slave_lock);
1596 read_unlock(&bond->lock);
1597 } 1595 }
1598 1596
1599 pr_info("%s: enslaving %s as a%s interface with a%s link.\n", 1597 pr_info("%s: enslaving %s as a%s interface with a%s link.\n",
@@ -1613,19 +1611,13 @@ err_detach:
1613 bond_hw_addr_flush(bond_dev, slave_dev); 1611 bond_hw_addr_flush(bond_dev, slave_dev);
1614 1612
1615 vlan_vids_del_by_dev(slave_dev, bond_dev); 1613 vlan_vids_del_by_dev(slave_dev, bond_dev);
1616 write_lock_bh(&bond->lock);
1617 if (bond->primary_slave == new_slave) 1614 if (bond->primary_slave == new_slave)
1618 bond->primary_slave = NULL; 1615 bond->primary_slave = NULL;
1619 if (bond->curr_active_slave == new_slave) { 1616 if (bond->curr_active_slave == new_slave) {
1620 bond_change_active_slave(bond, NULL);
1621 write_unlock_bh(&bond->lock);
1622 read_lock(&bond->lock);
1623 write_lock_bh(&bond->curr_slave_lock); 1617 write_lock_bh(&bond->curr_slave_lock);
1618 bond_change_active_slave(bond, NULL);
1624 bond_select_active_slave(bond); 1619 bond_select_active_slave(bond);
1625 write_unlock_bh(&bond->curr_slave_lock); 1620 write_unlock_bh(&bond->curr_slave_lock);
1626 read_unlock(&bond->lock);
1627 } else {
1628 write_unlock_bh(&bond->lock);
1629 } 1621 }
1630 slave_disable_netpoll(new_slave); 1622 slave_disable_netpoll(new_slave);
1631 1623
@@ -1690,20 +1682,16 @@ static int __bond_release_one(struct net_device *bond_dev,
1690 } 1682 }
1691 1683
1692 block_netpoll_tx(); 1684 block_netpoll_tx();
1693 write_lock_bh(&bond->lock);
1694 1685
1695 slave = bond_get_slave_by_dev(bond, slave_dev); 1686 slave = bond_get_slave_by_dev(bond, slave_dev);
1696 if (!slave) { 1687 if (!slave) {
1697 /* not a slave of this bond */ 1688 /* not a slave of this bond */
1698 pr_info("%s: %s not enslaved\n", 1689 pr_info("%s: %s not enslaved\n",
1699 bond_dev->name, slave_dev->name); 1690 bond_dev->name, slave_dev->name);
1700 write_unlock_bh(&bond->lock);
1701 unblock_netpoll_tx(); 1691 unblock_netpoll_tx();
1702 return -EINVAL; 1692 return -EINVAL;
1703 } 1693 }
1704 1694
1705 write_unlock_bh(&bond->lock);
1706
1707 /* release the slave from its bond */ 1695 /* release the slave from its bond */
1708 bond->slave_cnt--; 1696 bond->slave_cnt--;
1709 1697
@@ -1721,6 +1709,7 @@ static int __bond_release_one(struct net_device *bond_dev,
1721 */ 1709 */
1722 bond_3ad_unbind_slave(slave); 1710 bond_3ad_unbind_slave(slave);
1723 } 1711 }
1712 write_unlock_bh(&bond->lock);
1724 1713
1725 pr_info("%s: releasing %s interface %s\n", 1714 pr_info("%s: releasing %s interface %s\n",
1726 bond_dev->name, 1715 bond_dev->name,
@@ -1743,8 +1732,11 @@ static int __bond_release_one(struct net_device *bond_dev,
1743 if (bond->primary_slave == slave) 1732 if (bond->primary_slave == slave)
1744 bond->primary_slave = NULL; 1733 bond->primary_slave = NULL;
1745 1734
1746 if (oldcurrent == slave) 1735 if (oldcurrent == slave) {
1736 write_lock_bh(&bond->curr_slave_lock);
1747 bond_change_active_slave(bond, NULL); 1737 bond_change_active_slave(bond, NULL);
1738 write_unlock_bh(&bond->curr_slave_lock);
1739 }
1748 1740
1749 if (bond_is_lb(bond)) { 1741 if (bond_is_lb(bond)) {
1750 /* Must be called only after the slave has been 1742 /* Must be called only after the slave has been
@@ -1752,9 +1744,7 @@ static int __bond_release_one(struct net_device *bond_dev,
1752 * has been cleared (if our_slave == old_current), 1744 * has been cleared (if our_slave == old_current),
1753 * but before a new active slave is selected. 1745 * but before a new active slave is selected.
1754 */ 1746 */
1755 write_unlock_bh(&bond->lock);
1756 bond_alb_deinit_slave(bond, slave); 1747 bond_alb_deinit_slave(bond, slave);
1757 write_lock_bh(&bond->lock);
1758 } 1748 }
1759 1749
1760 if (all) { 1750 if (all) {
@@ -1765,15 +1755,11 @@ static int __bond_release_one(struct net_device *bond_dev,
1765 * is no concern that another slave add/remove event 1755 * is no concern that another slave add/remove event
1766 * will interfere. 1756 * will interfere.
1767 */ 1757 */
1768 write_unlock_bh(&bond->lock);
1769 read_lock(&bond->lock);
1770 write_lock_bh(&bond->curr_slave_lock); 1758 write_lock_bh(&bond->curr_slave_lock);
1771 1759
1772 bond_select_active_slave(bond); 1760 bond_select_active_slave(bond);
1773 1761
1774 write_unlock_bh(&bond->curr_slave_lock); 1762 write_unlock_bh(&bond->curr_slave_lock);
1775 read_unlock(&bond->lock);
1776 write_lock_bh(&bond->lock);
1777 } 1763 }
1778 1764
1779 if (!bond_has_slaves(bond)) { 1765 if (!bond_has_slaves(bond)) {
@@ -1788,7 +1774,6 @@ static int __bond_release_one(struct net_device *bond_dev,
1788 } 1774 }
1789 } 1775 }
1790 1776
1791 write_unlock_bh(&bond->lock);
1792 unblock_netpoll_tx(); 1777 unblock_netpoll_tx();
1793 synchronize_rcu(); 1778 synchronize_rcu();
1794 1779