diff options
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 27 |
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 | ||