diff options
| -rw-r--r-- | drivers/net/bonding/bond_3ad.c | 54 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_alb.c | 34 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_main.c | 157 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_options.c | 2 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 4 | ||||
| -rw-r--r-- | drivers/net/bonding/bonding.h | 4 | ||||
| -rw-r--r-- | include/linux/netdevice.h | 1 | ||||
| -rw-r--r-- | net/core/dev.c | 21 |
8 files changed, 130 insertions, 147 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 187b1b7772ef..58c2249a3324 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
| @@ -147,11 +147,12 @@ static inline struct aggregator *__get_first_agg(struct port *port) | |||
| 147 | struct bonding *bond = __get_bond_by_port(port); | 147 | struct bonding *bond = __get_bond_by_port(port); |
| 148 | struct slave *first_slave; | 148 | struct slave *first_slave; |
| 149 | 149 | ||
| 150 | // If there's no bond for this port, or bond has no slaves | 150 | /* If there's no bond for this port, or bond has no slaves */ |
| 151 | if (bond == NULL) | 151 | if (bond == NULL) |
| 152 | return NULL; | 152 | return NULL; |
| 153 | first_slave = bond_first_slave(bond); | 153 | rcu_read_lock(); |
| 154 | 154 | first_slave = bond_first_slave_rcu(bond); | |
| 155 | rcu_read_unlock(); | ||
| 155 | return first_slave ? &(SLAVE_AD_INFO(first_slave).aggregator) : NULL; | 156 | return first_slave ? &(SLAVE_AD_INFO(first_slave).aggregator) : NULL; |
| 156 | } | 157 | } |
| 157 | 158 | ||
| @@ -702,9 +703,13 @@ static struct aggregator *__get_active_agg(struct aggregator *aggregator) | |||
| 702 | struct list_head *iter; | 703 | struct list_head *iter; |
| 703 | struct slave *slave; | 704 | struct slave *slave; |
| 704 | 705 | ||
| 705 | bond_for_each_slave(bond, slave, iter) | 706 | rcu_read_lock(); |
| 706 | if (SLAVE_AD_INFO(slave).aggregator.is_active) | 707 | bond_for_each_slave_rcu(bond, slave, iter) |
| 708 | if (SLAVE_AD_INFO(slave).aggregator.is_active) { | ||
| 709 | rcu_read_unlock(); | ||
| 707 | return &(SLAVE_AD_INFO(slave).aggregator); | 710 | return &(SLAVE_AD_INFO(slave).aggregator); |
| 711 | } | ||
| 712 | rcu_read_unlock(); | ||
| 708 | 713 | ||
| 709 | return NULL; | 714 | return NULL; |
| 710 | } | 715 | } |
| @@ -1471,7 +1476,8 @@ static void ad_agg_selection_logic(struct aggregator *agg) | |||
| 1471 | active = __get_active_agg(agg); | 1476 | active = __get_active_agg(agg); |
| 1472 | best = (active && agg_device_up(active)) ? active : NULL; | 1477 | best = (active && agg_device_up(active)) ? active : NULL; |
| 1473 | 1478 | ||
| 1474 | bond_for_each_slave(bond, slave, iter) { | 1479 | rcu_read_lock(); |
| 1480 | bond_for_each_slave_rcu(bond, slave, iter) { | ||
| 1475 | agg = &(SLAVE_AD_INFO(slave).aggregator); | 1481 | agg = &(SLAVE_AD_INFO(slave).aggregator); |
| 1476 | 1482 | ||
| 1477 | agg->is_active = 0; | 1483 | agg->is_active = 0; |
| @@ -1505,7 +1511,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) | |||
| 1505 | active->is_active = 1; | 1511 | active->is_active = 1; |
| 1506 | } | 1512 | } |
| 1507 | 1513 | ||
| 1508 | // if there is new best aggregator, activate it | 1514 | /* if there is new best aggregator, activate it */ |
| 1509 | if (best) { | 1515 | if (best) { |
| 1510 | pr_debug("best Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n", | 1516 | pr_debug("best Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n", |
| 1511 | best->aggregator_identifier, best->num_of_ports, | 1517 | best->aggregator_identifier, best->num_of_ports, |
| @@ -1516,7 +1522,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) | |||
| 1516 | best->lag_ports, best->slave, | 1522 | best->lag_ports, best->slave, |
| 1517 | best->slave ? best->slave->dev->name : "NULL"); | 1523 | best->slave ? best->slave->dev->name : "NULL"); |
| 1518 | 1524 | ||
| 1519 | bond_for_each_slave(bond, slave, iter) { | 1525 | bond_for_each_slave_rcu(bond, slave, iter) { |
| 1520 | agg = &(SLAVE_AD_INFO(slave).aggregator); | 1526 | agg = &(SLAVE_AD_INFO(slave).aggregator); |
| 1521 | 1527 | ||
| 1522 | pr_debug("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n", | 1528 | pr_debug("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n", |
| @@ -1526,10 +1532,11 @@ static void ad_agg_selection_logic(struct aggregator *agg) | |||
| 1526 | agg->is_individual, agg->is_active); | 1532 | agg->is_individual, agg->is_active); |
| 1527 | } | 1533 | } |
| 1528 | 1534 | ||
| 1529 | // check if any partner replys | 1535 | /* check if any partner replys */ |
| 1530 | if (best->is_individual) { | 1536 | if (best->is_individual) { |
| 1531 | pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", | 1537 | pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", |
| 1532 | best->slave ? best->slave->bond->dev->name : "NULL"); | 1538 | best->slave ? |
| 1539 | best->slave->bond->dev->name : "NULL"); | ||
| 1533 | } | 1540 | } |
| 1534 | 1541 | ||
| 1535 | best->is_active = 1; | 1542 | best->is_active = 1; |
| @@ -1541,7 +1548,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) | |||
| 1541 | best->partner_oper_aggregator_key, | 1548 | best->partner_oper_aggregator_key, |
| 1542 | best->is_individual, best->is_active); | 1549 | best->is_individual, best->is_active); |
| 1543 | 1550 | ||
| 1544 | // disable the ports that were related to the former active_aggregator | 1551 | /* disable the ports that were related to the former active_aggregator */ |
| 1545 | if (active) { | 1552 | if (active) { |
| 1546 | for (port = active->lag_ports; port; | 1553 | for (port = active->lag_ports; port; |
| 1547 | port = port->next_port_in_aggregator) { | 1554 | port = port->next_port_in_aggregator) { |
| @@ -1565,6 +1572,8 @@ static void ad_agg_selection_logic(struct aggregator *agg) | |||
| 1565 | } | 1572 | } |
| 1566 | } | 1573 | } |
| 1567 | 1574 | ||
| 1575 | rcu_read_unlock(); | ||
| 1576 | |||
| 1568 | bond_3ad_set_carrier(bond); | 1577 | bond_3ad_set_carrier(bond); |
| 1569 | } | 1578 | } |
| 1570 | 1579 | ||
| @@ -2069,17 +2078,18 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
| 2069 | struct port *port; | 2078 | struct port *port; |
| 2070 | 2079 | ||
| 2071 | read_lock(&bond->lock); | 2080 | read_lock(&bond->lock); |
| 2081 | rcu_read_lock(); | ||
| 2072 | 2082 | ||
| 2073 | //check if there are any slaves | 2083 | /* check if there are any slaves */ |
| 2074 | if (!bond_has_slaves(bond)) | 2084 | if (!bond_has_slaves(bond)) |
| 2075 | goto re_arm; | 2085 | goto re_arm; |
| 2076 | 2086 | ||
| 2077 | // check if agg_select_timer timer after initialize is timed out | 2087 | /* check if agg_select_timer timer after initialize is timed out */ |
| 2078 | if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) { | 2088 | if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) { |
| 2079 | slave = bond_first_slave(bond); | 2089 | slave = bond_first_slave_rcu(bond); |
| 2080 | port = slave ? &(SLAVE_AD_INFO(slave).port) : NULL; | 2090 | port = slave ? &(SLAVE_AD_INFO(slave).port) : NULL; |
| 2081 | 2091 | ||
| 2082 | // select the active aggregator for the bond | 2092 | /* select the active aggregator for the bond */ |
| 2083 | if (port) { | 2093 | if (port) { |
| 2084 | if (!port->slave) { | 2094 | if (!port->slave) { |
| 2085 | pr_warning("%s: Warning: bond's first port is uninitialized\n", | 2095 | pr_warning("%s: Warning: bond's first port is uninitialized\n", |
| @@ -2093,8 +2103,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
| 2093 | bond_3ad_set_carrier(bond); | 2103 | bond_3ad_set_carrier(bond); |
| 2094 | } | 2104 | } |
| 2095 | 2105 | ||
| 2096 | // for each port run the state machines | 2106 | /* for each port run the state machines */ |
| 2097 | bond_for_each_slave(bond, slave, iter) { | 2107 | bond_for_each_slave_rcu(bond, slave, iter) { |
| 2098 | port = &(SLAVE_AD_INFO(slave).port); | 2108 | port = &(SLAVE_AD_INFO(slave).port); |
| 2099 | if (!port->slave) { | 2109 | if (!port->slave) { |
| 2100 | pr_warning("%s: Warning: Found an uninitialized port\n", | 2110 | pr_warning("%s: Warning: Found an uninitialized port\n", |
| @@ -2114,7 +2124,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
| 2114 | ad_mux_machine(port); | 2124 | ad_mux_machine(port); |
| 2115 | ad_tx_machine(port); | 2125 | ad_tx_machine(port); |
| 2116 | 2126 | ||
| 2117 | // turn off the BEGIN bit, since we already handled it | 2127 | /* turn off the BEGIN bit, since we already handled it */ |
| 2118 | if (port->sm_vars & AD_PORT_BEGIN) | 2128 | if (port->sm_vars & AD_PORT_BEGIN) |
| 2119 | port->sm_vars &= ~AD_PORT_BEGIN; | 2129 | port->sm_vars &= ~AD_PORT_BEGIN; |
| 2120 | 2130 | ||
| @@ -2122,9 +2132,9 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
| 2122 | } | 2132 | } |
| 2123 | 2133 | ||
| 2124 | re_arm: | 2134 | re_arm: |
| 2125 | queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks); | 2135 | rcu_read_unlock(); |
| 2126 | |||
| 2127 | read_unlock(&bond->lock); | 2136 | read_unlock(&bond->lock); |
| 2137 | queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks); | ||
| 2128 | } | 2138 | } |
| 2129 | 2139 | ||
| 2130 | /** | 2140 | /** |
| @@ -2303,7 +2313,9 @@ int bond_3ad_set_carrier(struct bonding *bond) | |||
| 2303 | struct aggregator *active; | 2313 | struct aggregator *active; |
| 2304 | struct slave *first_slave; | 2314 | struct slave *first_slave; |
| 2305 | 2315 | ||
| 2306 | first_slave = bond_first_slave(bond); | 2316 | rcu_read_lock(); |
| 2317 | first_slave = bond_first_slave_rcu(bond); | ||
| 2318 | rcu_read_unlock(); | ||
| 2307 | if (!first_slave) | 2319 | if (!first_slave) |
| 2308 | return 0; | 2320 | return 0; |
| 2309 | active = __get_active_agg(&(SLAVE_AD_INFO(first_slave).aggregator)); | 2321 | active = __get_active_agg(&(SLAVE_AD_INFO(first_slave).aggregator)); |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 2250b063ab89..759ddeebe390 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
| @@ -469,7 +469,7 @@ static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[]) | |||
| 469 | 469 | ||
| 470 | /* slave being removed should not be active at this point | 470 | /* slave being removed should not be active at this point |
| 471 | * | 471 | * |
| 472 | * Caller must hold bond lock for read | 472 | * Caller must hold rtnl. |
| 473 | */ | 473 | */ |
| 474 | static void rlb_clear_slave(struct bonding *bond, struct slave *slave) | 474 | static void rlb_clear_slave(struct bonding *bond, struct slave *slave) |
| 475 | { | 475 | { |
| @@ -815,7 +815,7 @@ static void rlb_rebalance(struct bonding *bond) | |||
| 815 | for (; hash_index != RLB_NULL_INDEX; | 815 | for (; hash_index != RLB_NULL_INDEX; |
| 816 | hash_index = client_info->used_next) { | 816 | hash_index = client_info->used_next) { |
| 817 | client_info = &(bond_info->rx_hashtbl[hash_index]); | 817 | client_info = &(bond_info->rx_hashtbl[hash_index]); |
| 818 | assigned_slave = rlb_next_rx_slave(bond); | 818 | assigned_slave = __rlb_next_rx_slave(bond); |
| 819 | if (assigned_slave && (client_info->slave != assigned_slave)) { | 819 | if (assigned_slave && (client_info->slave != assigned_slave)) { |
| 820 | client_info->slave = assigned_slave; | 820 | client_info->slave = assigned_slave; |
| 821 | client_info->ntt = 1; | 821 | client_info->ntt = 1; |
| @@ -1494,14 +1494,14 @@ void bond_alb_monitor(struct work_struct *work) | |||
| 1494 | struct list_head *iter; | 1494 | struct list_head *iter; |
| 1495 | struct slave *slave; | 1495 | struct slave *slave; |
| 1496 | 1496 | ||
| 1497 | read_lock(&bond->lock); | ||
| 1498 | |||
| 1499 | if (!bond_has_slaves(bond)) { | 1497 | if (!bond_has_slaves(bond)) { |
| 1500 | bond_info->tx_rebalance_counter = 0; | 1498 | bond_info->tx_rebalance_counter = 0; |
| 1501 | bond_info->lp_counter = 0; | 1499 | bond_info->lp_counter = 0; |
| 1502 | goto re_arm; | 1500 | goto re_arm; |
| 1503 | } | 1501 | } |
| 1504 | 1502 | ||
| 1503 | rcu_read_lock(); | ||
| 1504 | |||
| 1505 | bond_info->tx_rebalance_counter++; | 1505 | bond_info->tx_rebalance_counter++; |
| 1506 | bond_info->lp_counter++; | 1506 | bond_info->lp_counter++; |
| 1507 | 1507 | ||
| @@ -1514,7 +1514,7 @@ void bond_alb_monitor(struct work_struct *work) | |||
| 1514 | */ | 1514 | */ |
| 1515 | read_lock(&bond->curr_slave_lock); | 1515 | read_lock(&bond->curr_slave_lock); |
| 1516 | 1516 | ||
| 1517 | bond_for_each_slave(bond, slave, iter) | 1517 | bond_for_each_slave_rcu(bond, slave, iter) |
| 1518 | alb_send_learning_packets(slave, slave->dev->dev_addr); | 1518 | alb_send_learning_packets(slave, slave->dev->dev_addr); |
| 1519 | 1519 | ||
| 1520 | read_unlock(&bond->curr_slave_lock); | 1520 | read_unlock(&bond->curr_slave_lock); |
| @@ -1527,7 +1527,7 @@ void bond_alb_monitor(struct work_struct *work) | |||
| 1527 | 1527 | ||
| 1528 | read_lock(&bond->curr_slave_lock); | 1528 | read_lock(&bond->curr_slave_lock); |
| 1529 | 1529 | ||
| 1530 | bond_for_each_slave(bond, slave, iter) { | 1530 | bond_for_each_slave_rcu(bond, slave, iter) { |
| 1531 | tlb_clear_slave(bond, slave, 1); | 1531 | tlb_clear_slave(bond, slave, 1); |
| 1532 | if (slave == bond->curr_active_slave) { | 1532 | if (slave == bond->curr_active_slave) { |
| 1533 | SLAVE_TLB_INFO(slave).load = | 1533 | SLAVE_TLB_INFO(slave).load = |
| @@ -1551,11 +1551,9 @@ void bond_alb_monitor(struct work_struct *work) | |||
| 1551 | * dev_set_promiscuity requires rtnl and | 1551 | * dev_set_promiscuity requires rtnl and |
| 1552 | * nothing else. Avoid race with bond_close. | 1552 | * nothing else. Avoid race with bond_close. |
| 1553 | */ | 1553 | */ |
| 1554 | read_unlock(&bond->lock); | 1554 | rcu_read_unlock(); |
| 1555 | if (!rtnl_trylock()) { | 1555 | if (!rtnl_trylock()) |
| 1556 | read_lock(&bond->lock); | ||
| 1557 | goto re_arm; | 1556 | goto re_arm; |
| 1558 | } | ||
| 1559 | 1557 | ||
| 1560 | bond_info->rlb_promisc_timeout_counter = 0; | 1558 | bond_info->rlb_promisc_timeout_counter = 0; |
| 1561 | 1559 | ||
| @@ -1567,7 +1565,7 @@ void bond_alb_monitor(struct work_struct *work) | |||
| 1567 | bond_info->primary_is_promisc = 0; | 1565 | bond_info->primary_is_promisc = 0; |
| 1568 | 1566 | ||
| 1569 | rtnl_unlock(); | 1567 | rtnl_unlock(); |
| 1570 | read_lock(&bond->lock); | 1568 | rcu_read_lock(); |
| 1571 | } | 1569 | } |
| 1572 | 1570 | ||
| 1573 | if (bond_info->rlb_rebalance) { | 1571 | if (bond_info->rlb_rebalance) { |
| @@ -1589,11 +1587,9 @@ void bond_alb_monitor(struct work_struct *work) | |||
| 1589 | } | 1587 | } |
| 1590 | } | 1588 | } |
| 1591 | } | 1589 | } |
| 1592 | 1590 | rcu_read_unlock(); | |
| 1593 | re_arm: | 1591 | re_arm: |
| 1594 | queue_delayed_work(bond->wq, &bond->alb_work, alb_delta_in_ticks); | 1592 | queue_delayed_work(bond->wq, &bond->alb_work, alb_delta_in_ticks); |
| 1595 | |||
| 1596 | read_unlock(&bond->lock); | ||
| 1597 | } | 1593 | } |
| 1598 | 1594 | ||
| 1599 | /* assumption: called before the slave is attached to the bond | 1595 | /* assumption: called before the slave is attached to the bond |
| @@ -1679,14 +1675,11 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char | |||
| 1679 | * If new_slave is NULL, caller must hold curr_slave_lock or | 1675 | * If new_slave is NULL, caller must hold curr_slave_lock or |
| 1680 | * bond->lock for write. | 1676 | * bond->lock for write. |
| 1681 | * | 1677 | * |
| 1682 | * If new_slave is not NULL, caller must hold RTNL, bond->lock for | 1678 | * If new_slave is not NULL, caller must hold RTNL, curr_slave_lock |
| 1683 | * read and curr_slave_lock for write. Processing here may sleep, so | 1679 | * for write. Processing here may sleep, so no other locks may be held. |
| 1684 | * no other locks may be held. | ||
| 1685 | */ | 1680 | */ |
| 1686 | void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave) | 1681 | void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave) |
| 1687 | __releases(&bond->curr_slave_lock) | 1682 | __releases(&bond->curr_slave_lock) |
| 1688 | __releases(&bond->lock) | ||
| 1689 | __acquires(&bond->lock) | ||
| 1690 | __acquires(&bond->curr_slave_lock) | 1683 | __acquires(&bond->curr_slave_lock) |
| 1691 | { | 1684 | { |
| 1692 | struct slave *swap_slave; | 1685 | struct slave *swap_slave; |
| @@ -1722,7 +1715,6 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave | |||
| 1722 | tlb_clear_slave(bond, new_slave, 1); | 1715 | tlb_clear_slave(bond, new_slave, 1); |
| 1723 | 1716 | ||
| 1724 | write_unlock_bh(&bond->curr_slave_lock); | 1717 | write_unlock_bh(&bond->curr_slave_lock); |
| 1725 | read_unlock(&bond->lock); | ||
| 1726 | 1718 | ||
| 1727 | ASSERT_RTNL(); | 1719 | ASSERT_RTNL(); |
| 1728 | 1720 | ||
| @@ -1748,11 +1740,9 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave | |||
| 1748 | /* swap mac address */ | 1740 | /* swap mac address */ |
| 1749 | alb_swap_mac_addr(swap_slave, new_slave); | 1741 | alb_swap_mac_addr(swap_slave, new_slave); |
| 1750 | alb_fasten_mac_swap(bond, swap_slave, new_slave); | 1742 | alb_fasten_mac_swap(bond, swap_slave, new_slave); |
| 1751 | read_lock(&bond->lock); | ||
| 1752 | } else { | 1743 | } else { |
| 1753 | /* set the new_slave to the bond mac address */ | 1744 | /* set the new_slave to the bond mac address */ |
| 1754 | alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr); | 1745 | alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr); |
| 1755 | read_lock(&bond->lock); | ||
| 1756 | alb_send_learning_packets(new_slave, bond->dev->dev_addr); | 1746 | alb_send_learning_packets(new_slave, bond->dev->dev_addr); |
| 1757 | } | 1747 | } |
| 1758 | 1748 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 398e299ee1bd..c0456cc86610 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -591,33 +591,22 @@ static int bond_set_allmulti(struct bonding *bond, int inc) | |||
| 591 | * device and retransmit an IGMP JOIN request to the current active | 591 | * device and retransmit an IGMP JOIN request to the current active |
| 592 | * slave. | 592 | * slave. |
| 593 | */ | 593 | */ |
| 594 | static void bond_resend_igmp_join_requests(struct bonding *bond) | 594 | static void bond_resend_igmp_join_requests_delayed(struct work_struct *work) |
| 595 | { | 595 | { |
| 596 | struct bonding *bond = container_of(work, struct bonding, | ||
| 597 | mcast_work.work); | ||
| 598 | |||
| 596 | if (!rtnl_trylock()) { | 599 | if (!rtnl_trylock()) { |
| 597 | queue_delayed_work(bond->wq, &bond->mcast_work, 1); | 600 | queue_delayed_work(bond->wq, &bond->mcast_work, 1); |
| 598 | return; | 601 | return; |
| 599 | } | 602 | } |
| 600 | call_netdevice_notifiers(NETDEV_RESEND_IGMP, bond->dev); | 603 | call_netdevice_notifiers(NETDEV_RESEND_IGMP, bond->dev); |
| 601 | rtnl_unlock(); | ||
| 602 | 604 | ||
| 603 | /* We use curr_slave_lock to protect against concurrent access to | ||
| 604 | * igmp_retrans from multiple running instances of this function and | ||
| 605 | * bond_change_active_slave | ||
| 606 | */ | ||
| 607 | write_lock_bh(&bond->curr_slave_lock); | ||
| 608 | if (bond->igmp_retrans > 1) { | 605 | if (bond->igmp_retrans > 1) { |
| 609 | bond->igmp_retrans--; | 606 | bond->igmp_retrans--; |
| 610 | queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); | 607 | queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); |
| 611 | } | 608 | } |
| 612 | write_unlock_bh(&bond->curr_slave_lock); | 609 | rtnl_unlock(); |
| 613 | } | ||
| 614 | |||
| 615 | static void bond_resend_igmp_join_requests_delayed(struct work_struct *work) | ||
| 616 | { | ||
| 617 | struct bonding *bond = container_of(work, struct bonding, | ||
| 618 | mcast_work.work); | ||
| 619 | |||
| 620 | bond_resend_igmp_join_requests(bond); | ||
| 621 | } | 610 | } |
| 622 | 611 | ||
| 623 | /* Flush bond's hardware addresses from slave | 612 | /* Flush bond's hardware addresses from slave |
| @@ -697,14 +686,12 @@ static void bond_set_dev_addr(struct net_device *bond_dev, | |||
| 697 | * | 686 | * |
| 698 | * Perform special MAC address swapping for fail_over_mac settings | 687 | * Perform special MAC address swapping for fail_over_mac settings |
| 699 | * | 688 | * |
| 700 | * Called with RTNL, bond->lock for read, curr_slave_lock for write_bh. | 689 | * Called with RTNL, curr_slave_lock for write_bh. |
| 701 | */ | 690 | */ |
| 702 | static void bond_do_fail_over_mac(struct bonding *bond, | 691 | static void bond_do_fail_over_mac(struct bonding *bond, |
| 703 | struct slave *new_active, | 692 | struct slave *new_active, |
| 704 | struct slave *old_active) | 693 | struct slave *old_active) |
| 705 | __releases(&bond->curr_slave_lock) | 694 | __releases(&bond->curr_slave_lock) |
| 706 | __releases(&bond->lock) | ||
| 707 | __acquires(&bond->lock) | ||
| 708 | __acquires(&bond->curr_slave_lock) | 695 | __acquires(&bond->curr_slave_lock) |
| 709 | { | 696 | { |
| 710 | u8 tmp_mac[ETH_ALEN]; | 697 | u8 tmp_mac[ETH_ALEN]; |
| @@ -715,9 +702,7 @@ static void bond_do_fail_over_mac(struct bonding *bond, | |||
| 715 | case BOND_FOM_ACTIVE: | 702 | case BOND_FOM_ACTIVE: |
| 716 | if (new_active) { | 703 | if (new_active) { |
| 717 | write_unlock_bh(&bond->curr_slave_lock); | 704 | write_unlock_bh(&bond->curr_slave_lock); |
| 718 | read_unlock(&bond->lock); | ||
| 719 | bond_set_dev_addr(bond->dev, new_active->dev); | 705 | bond_set_dev_addr(bond->dev, new_active->dev); |
| 720 | read_lock(&bond->lock); | ||
| 721 | write_lock_bh(&bond->curr_slave_lock); | 706 | write_lock_bh(&bond->curr_slave_lock); |
| 722 | } | 707 | } |
| 723 | break; | 708 | break; |
| @@ -731,7 +716,6 @@ static void bond_do_fail_over_mac(struct bonding *bond, | |||
| 731 | return; | 716 | return; |
| 732 | 717 | ||
| 733 | write_unlock_bh(&bond->curr_slave_lock); | 718 | write_unlock_bh(&bond->curr_slave_lock); |
| 734 | read_unlock(&bond->lock); | ||
| 735 | 719 | ||
| 736 | if (old_active) { | 720 | if (old_active) { |
| 737 | memcpy(tmp_mac, new_active->dev->dev_addr, ETH_ALEN); | 721 | memcpy(tmp_mac, new_active->dev->dev_addr, ETH_ALEN); |
| @@ -761,7 +745,6 @@ static void bond_do_fail_over_mac(struct bonding *bond, | |||
| 761 | pr_err("%s: Error %d setting MAC of slave %s\n", | 745 | pr_err("%s: Error %d setting MAC of slave %s\n", |
| 762 | bond->dev->name, -rv, new_active->dev->name); | 746 | bond->dev->name, -rv, new_active->dev->name); |
| 763 | out: | 747 | out: |
| 764 | read_lock(&bond->lock); | ||
| 765 | write_lock_bh(&bond->curr_slave_lock); | 748 | write_lock_bh(&bond->curr_slave_lock); |
| 766 | break; | 749 | break; |
| 767 | default: | 750 | default: |
| @@ -821,7 +804,11 @@ static struct slave *bond_find_best_slave(struct bonding *bond) | |||
| 821 | 804 | ||
| 822 | static bool bond_should_notify_peers(struct bonding *bond) | 805 | static bool bond_should_notify_peers(struct bonding *bond) |
| 823 | { | 806 | { |
| 824 | struct slave *slave = bond->curr_active_slave; | 807 | struct slave *slave; |
| 808 | |||
| 809 | rcu_read_lock(); | ||
| 810 | slave = rcu_dereference(bond->curr_active_slave); | ||
| 811 | rcu_read_unlock(); | ||
| 825 | 812 | ||
| 826 | pr_debug("bond_should_notify_peers: bond %s slave %s\n", | 813 | pr_debug("bond_should_notify_peers: bond %s slave %s\n", |
| 827 | bond->dev->name, slave ? slave->dev->name : "NULL"); | 814 | bond->dev->name, slave ? slave->dev->name : "NULL"); |
| @@ -846,8 +833,7 @@ static bool bond_should_notify_peers(struct bonding *bond) | |||
| 846 | * because it is apparently the best available slave we have, even though its | 833 | * because it is apparently the best available slave we have, even though its |
| 847 | * updelay hasn't timed out yet. | 834 | * updelay hasn't timed out yet. |
| 848 | * | 835 | * |
| 849 | * If new_active is not NULL, caller must hold bond->lock for read and | 836 | * If new_active is not NULL, caller must hold curr_slave_lock for write_bh. |
| 850 | * curr_slave_lock for write_bh. | ||
| 851 | */ | 837 | */ |
| 852 | void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | 838 | void bond_change_active_slave(struct bonding *bond, struct slave *new_active) |
| 853 | { | 839 | { |
| @@ -916,14 +902,12 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
| 916 | } | 902 | } |
| 917 | 903 | ||
| 918 | write_unlock_bh(&bond->curr_slave_lock); | 904 | write_unlock_bh(&bond->curr_slave_lock); |
| 919 | read_unlock(&bond->lock); | ||
| 920 | 905 | ||
| 921 | call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, bond->dev); | 906 | call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, bond->dev); |
| 922 | if (should_notify_peers) | 907 | if (should_notify_peers) |
| 923 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, | 908 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, |
| 924 | bond->dev); | 909 | bond->dev); |
| 925 | 910 | ||
| 926 | read_lock(&bond->lock); | ||
| 927 | write_lock_bh(&bond->curr_slave_lock); | 911 | write_lock_bh(&bond->curr_slave_lock); |
| 928 | } | 912 | } |
| 929 | } | 913 | } |
| @@ -949,7 +933,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
| 949 | * - The primary_slave has got its link back. | 933 | * - The primary_slave has got its link back. |
| 950 | * - A slave has got its link back and there's no old curr_active_slave. | 934 | * - A slave has got its link back and there's no old curr_active_slave. |
| 951 | * | 935 | * |
| 952 | * Caller must hold bond->lock for read and curr_slave_lock for write_bh. | 936 | * Caller must hold curr_slave_lock for write_bh. |
| 953 | */ | 937 | */ |
| 954 | void bond_select_active_slave(struct bonding *bond) | 938 | void bond_select_active_slave(struct bonding *bond) |
| 955 | { | 939 | { |
| @@ -1594,11 +1578,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1594 | bond_set_carrier(bond); | 1578 | bond_set_carrier(bond); |
| 1595 | 1579 | ||
| 1596 | if (USES_PRIMARY(bond->params.mode)) { | 1580 | if (USES_PRIMARY(bond->params.mode)) { |
| 1597 | read_lock(&bond->lock); | ||
| 1598 | write_lock_bh(&bond->curr_slave_lock); | 1581 | write_lock_bh(&bond->curr_slave_lock); |
| 1599 | bond_select_active_slave(bond); | 1582 | bond_select_active_slave(bond); |
| 1600 | write_unlock_bh(&bond->curr_slave_lock); | 1583 | write_unlock_bh(&bond->curr_slave_lock); |
| 1601 | read_unlock(&bond->lock); | ||
| 1602 | } | 1584 | } |
| 1603 | 1585 | ||
| 1604 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", | 1586 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", |
| @@ -1618,19 +1600,13 @@ err_detach: | |||
| 1618 | bond_hw_addr_flush(bond_dev, slave_dev); | 1600 | bond_hw_addr_flush(bond_dev, slave_dev); |
| 1619 | 1601 | ||
| 1620 | vlan_vids_del_by_dev(slave_dev, bond_dev); | 1602 | vlan_vids_del_by_dev(slave_dev, bond_dev); |
| 1621 | write_lock_bh(&bond->lock); | ||
| 1622 | if (bond->primary_slave == new_slave) | 1603 | if (bond->primary_slave == new_slave) |
| 1623 | bond->primary_slave = NULL; | 1604 | bond->primary_slave = NULL; |
| 1624 | if (bond->curr_active_slave == new_slave) { | 1605 | if (bond->curr_active_slave == new_slave) { |
| 1625 | bond_change_active_slave(bond, NULL); | ||
| 1626 | write_unlock_bh(&bond->lock); | ||
| 1627 | read_lock(&bond->lock); | ||
| 1628 | write_lock_bh(&bond->curr_slave_lock); | 1606 | write_lock_bh(&bond->curr_slave_lock); |
| 1607 | bond_change_active_slave(bond, NULL); | ||
| 1629 | bond_select_active_slave(bond); | 1608 | bond_select_active_slave(bond); |
| 1630 | write_unlock_bh(&bond->curr_slave_lock); | 1609 | write_unlock_bh(&bond->curr_slave_lock); |
| 1631 | read_unlock(&bond->lock); | ||
| 1632 | } else { | ||
| 1633 | write_unlock_bh(&bond->lock); | ||
| 1634 | } | 1610 | } |
| 1635 | slave_disable_netpoll(new_slave); | 1611 | slave_disable_netpoll(new_slave); |
| 1636 | 1612 | ||
| @@ -1695,20 +1671,16 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1695 | } | 1671 | } |
| 1696 | 1672 | ||
| 1697 | block_netpoll_tx(); | 1673 | block_netpoll_tx(); |
| 1698 | write_lock_bh(&bond->lock); | ||
| 1699 | 1674 | ||
| 1700 | slave = bond_get_slave_by_dev(bond, slave_dev); | 1675 | slave = bond_get_slave_by_dev(bond, slave_dev); |
| 1701 | if (!slave) { | 1676 | if (!slave) { |
| 1702 | /* not a slave of this bond */ | 1677 | /* not a slave of this bond */ |
| 1703 | pr_info("%s: %s not enslaved\n", | 1678 | pr_info("%s: %s not enslaved\n", |
| 1704 | bond_dev->name, slave_dev->name); | 1679 | bond_dev->name, slave_dev->name); |
| 1705 | write_unlock_bh(&bond->lock); | ||
| 1706 | unblock_netpoll_tx(); | 1680 | unblock_netpoll_tx(); |
| 1707 | return -EINVAL; | 1681 | return -EINVAL; |
| 1708 | } | 1682 | } |
| 1709 | 1683 | ||
| 1710 | write_unlock_bh(&bond->lock); | ||
| 1711 | |||
| 1712 | /* release the slave from its bond */ | 1684 | /* release the slave from its bond */ |
| 1713 | bond->slave_cnt--; | 1685 | bond->slave_cnt--; |
| 1714 | 1686 | ||
| @@ -1720,12 +1692,10 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1720 | write_lock_bh(&bond->lock); | 1692 | write_lock_bh(&bond->lock); |
| 1721 | 1693 | ||
| 1722 | /* Inform AD package of unbinding of slave. */ | 1694 | /* Inform AD package of unbinding of slave. */ |
| 1723 | if (bond->params.mode == BOND_MODE_8023AD) { | 1695 | if (bond->params.mode == BOND_MODE_8023AD) |
| 1724 | /* must be called before the slave is | ||
| 1725 | * detached from the list | ||
| 1726 | */ | ||
| 1727 | bond_3ad_unbind_slave(slave); | 1696 | bond_3ad_unbind_slave(slave); |
| 1728 | } | 1697 | |
| 1698 | write_unlock_bh(&bond->lock); | ||
| 1729 | 1699 | ||
| 1730 | pr_info("%s: releasing %s interface %s\n", | 1700 | pr_info("%s: releasing %s interface %s\n", |
| 1731 | bond_dev->name, | 1701 | bond_dev->name, |
| @@ -1748,8 +1718,11 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1748 | if (bond->primary_slave == slave) | 1718 | if (bond->primary_slave == slave) |
| 1749 | bond->primary_slave = NULL; | 1719 | bond->primary_slave = NULL; |
| 1750 | 1720 | ||
| 1751 | if (oldcurrent == slave) | 1721 | if (oldcurrent == slave) { |
| 1722 | write_lock_bh(&bond->curr_slave_lock); | ||
| 1752 | bond_change_active_slave(bond, NULL); | 1723 | bond_change_active_slave(bond, NULL); |
| 1724 | write_unlock_bh(&bond->curr_slave_lock); | ||
| 1725 | } | ||
| 1753 | 1726 | ||
| 1754 | if (bond_is_lb(bond)) { | 1727 | if (bond_is_lb(bond)) { |
| 1755 | /* Must be called only after the slave has been | 1728 | /* Must be called only after the slave has been |
| @@ -1757,9 +1730,7 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1757 | * has been cleared (if our_slave == old_current), | 1730 | * has been cleared (if our_slave == old_current), |
| 1758 | * but before a new active slave is selected. | 1731 | * but before a new active slave is selected. |
| 1759 | */ | 1732 | */ |
| 1760 | write_unlock_bh(&bond->lock); | ||
| 1761 | bond_alb_deinit_slave(bond, slave); | 1733 | bond_alb_deinit_slave(bond, slave); |
| 1762 | write_lock_bh(&bond->lock); | ||
| 1763 | } | 1734 | } |
| 1764 | 1735 | ||
| 1765 | if (all) { | 1736 | if (all) { |
| @@ -1770,15 +1741,11 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1770 | * is no concern that another slave add/remove event | 1741 | * is no concern that another slave add/remove event |
| 1771 | * will interfere. | 1742 | * will interfere. |
| 1772 | */ | 1743 | */ |
| 1773 | write_unlock_bh(&bond->lock); | ||
| 1774 | read_lock(&bond->lock); | ||
| 1775 | write_lock_bh(&bond->curr_slave_lock); | 1744 | write_lock_bh(&bond->curr_slave_lock); |
| 1776 | 1745 | ||
| 1777 | bond_select_active_slave(bond); | 1746 | bond_select_active_slave(bond); |
| 1778 | 1747 | ||
| 1779 | write_unlock_bh(&bond->curr_slave_lock); | 1748 | write_unlock_bh(&bond->curr_slave_lock); |
| 1780 | read_unlock(&bond->lock); | ||
| 1781 | write_lock_bh(&bond->lock); | ||
| 1782 | } | 1749 | } |
| 1783 | 1750 | ||
| 1784 | if (!bond_has_slaves(bond)) { | 1751 | if (!bond_has_slaves(bond)) { |
| @@ -1793,7 +1760,6 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
| 1793 | } | 1760 | } |
| 1794 | } | 1761 | } |
| 1795 | 1762 | ||
| 1796 | write_unlock_bh(&bond->lock); | ||
| 1797 | unblock_netpoll_tx(); | 1763 | unblock_netpoll_tx(); |
| 1798 | synchronize_rcu(); | 1764 | synchronize_rcu(); |
| 1799 | 1765 | ||
| @@ -1928,7 +1894,7 @@ static int bond_miimon_inspect(struct bonding *bond) | |||
| 1928 | 1894 | ||
| 1929 | ignore_updelay = !bond->curr_active_slave ? true : false; | 1895 | ignore_updelay = !bond->curr_active_slave ? true : false; |
| 1930 | 1896 | ||
| 1931 | bond_for_each_slave(bond, slave, iter) { | 1897 | bond_for_each_slave_rcu(bond, slave, iter) { |
| 1932 | slave->new_link = BOND_LINK_NOCHANGE; | 1898 | slave->new_link = BOND_LINK_NOCHANGE; |
| 1933 | 1899 | ||
| 1934 | link_state = bond_check_dev_link(bond, slave->dev, 0); | 1900 | link_state = bond_check_dev_link(bond, slave->dev, 0); |
| @@ -2126,41 +2092,35 @@ void bond_mii_monitor(struct work_struct *work) | |||
| 2126 | bool should_notify_peers = false; | 2092 | bool should_notify_peers = false; |
| 2127 | unsigned long delay; | 2093 | unsigned long delay; |
| 2128 | 2094 | ||
| 2129 | read_lock(&bond->lock); | ||
| 2130 | |||
| 2131 | delay = msecs_to_jiffies(bond->params.miimon); | 2095 | delay = msecs_to_jiffies(bond->params.miimon); |
| 2132 | 2096 | ||
| 2133 | if (!bond_has_slaves(bond)) | 2097 | if (!bond_has_slaves(bond)) |
| 2134 | goto re_arm; | 2098 | goto re_arm; |
| 2135 | 2099 | ||
| 2100 | rcu_read_lock(); | ||
| 2101 | |||
| 2136 | should_notify_peers = bond_should_notify_peers(bond); | 2102 | should_notify_peers = bond_should_notify_peers(bond); |
| 2137 | 2103 | ||
| 2138 | if (bond_miimon_inspect(bond)) { | 2104 | if (bond_miimon_inspect(bond)) { |
| 2139 | read_unlock(&bond->lock); | 2105 | rcu_read_unlock(); |
| 2140 | 2106 | ||
| 2141 | /* Race avoidance with bond_close cancel of workqueue */ | 2107 | /* Race avoidance with bond_close cancel of workqueue */ |
| 2142 | if (!rtnl_trylock()) { | 2108 | if (!rtnl_trylock()) { |
| 2143 | read_lock(&bond->lock); | ||
| 2144 | delay = 1; | 2109 | delay = 1; |
| 2145 | should_notify_peers = false; | 2110 | should_notify_peers = false; |
| 2146 | goto re_arm; | 2111 | goto re_arm; |
| 2147 | } | 2112 | } |
| 2148 | 2113 | ||
| 2149 | read_lock(&bond->lock); | ||
| 2150 | |||
| 2151 | bond_miimon_commit(bond); | 2114 | bond_miimon_commit(bond); |
| 2152 | 2115 | ||
| 2153 | read_unlock(&bond->lock); | ||
| 2154 | rtnl_unlock(); /* might sleep, hold no other locks */ | 2116 | rtnl_unlock(); /* might sleep, hold no other locks */ |
| 2155 | read_lock(&bond->lock); | 2117 | } else |
| 2156 | } | 2118 | rcu_read_unlock(); |
| 2157 | 2119 | ||
| 2158 | re_arm: | 2120 | re_arm: |
| 2159 | if (bond->params.miimon) | 2121 | if (bond->params.miimon) |
| 2160 | queue_delayed_work(bond->wq, &bond->mii_work, delay); | 2122 | queue_delayed_work(bond->wq, &bond->mii_work, delay); |
| 2161 | 2123 | ||
| 2162 | read_unlock(&bond->lock); | ||
| 2163 | |||
| 2164 | if (should_notify_peers) { | 2124 | if (should_notify_peers) { |
| 2165 | if (!rtnl_trylock()) | 2125 | if (!rtnl_trylock()) |
| 2166 | return; | 2126 | return; |
| @@ -2422,12 +2382,12 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
| 2422 | struct list_head *iter; | 2382 | struct list_head *iter; |
| 2423 | int do_failover = 0; | 2383 | int do_failover = 0; |
| 2424 | 2384 | ||
| 2425 | read_lock(&bond->lock); | ||
| 2426 | |||
| 2427 | if (!bond_has_slaves(bond)) | 2385 | if (!bond_has_slaves(bond)) |
| 2428 | goto re_arm; | 2386 | goto re_arm; |
| 2429 | 2387 | ||
| 2430 | oldcurrent = bond->curr_active_slave; | 2388 | rcu_read_lock(); |
| 2389 | |||
| 2390 | oldcurrent = ACCESS_ONCE(bond->curr_active_slave); | ||
| 2431 | /* see if any of the previous devices are up now (i.e. they have | 2391 | /* see if any of the previous devices are up now (i.e. they have |
| 2432 | * xmt and rcv traffic). the curr_active_slave does not come into | 2392 | * xmt and rcv traffic). the curr_active_slave does not come into |
| 2433 | * the picture unless it is null. also, slave->jiffies is not needed | 2393 | * the picture unless it is null. also, slave->jiffies is not needed |
| @@ -2436,7 +2396,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
| 2436 | * TODO: what about up/down delay in arp mode? it wasn't here before | 2396 | * TODO: what about up/down delay in arp mode? it wasn't here before |
| 2437 | * so it can wait | 2397 | * so it can wait |
| 2438 | */ | 2398 | */ |
| 2439 | bond_for_each_slave(bond, slave, iter) { | 2399 | bond_for_each_slave_rcu(bond, slave, iter) { |
| 2440 | unsigned long trans_start = dev_trans_start(slave->dev); | 2400 | unsigned long trans_start = dev_trans_start(slave->dev); |
| 2441 | 2401 | ||
| 2442 | if (slave->link != BOND_LINK_UP) { | 2402 | if (slave->link != BOND_LINK_UP) { |
| @@ -2498,7 +2458,14 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
| 2498 | bond_arp_send_all(bond, slave); | 2458 | bond_arp_send_all(bond, slave); |
| 2499 | } | 2459 | } |
| 2500 | 2460 | ||
| 2461 | rcu_read_unlock(); | ||
| 2462 | |||
| 2501 | if (do_failover) { | 2463 | if (do_failover) { |
| 2464 | /* the bond_select_active_slave must hold RTNL | ||
| 2465 | * and curr_slave_lock for write. | ||
| 2466 | */ | ||
| 2467 | if (!rtnl_trylock()) | ||
| 2468 | goto re_arm; | ||
| 2502 | block_netpoll_tx(); | 2469 | block_netpoll_tx(); |
| 2503 | write_lock_bh(&bond->curr_slave_lock); | 2470 | write_lock_bh(&bond->curr_slave_lock); |
| 2504 | 2471 | ||
| @@ -2506,14 +2473,13 @@ void bond_loadbalance_arp_mon(struct work_struct *work) | |||
| 2506 | 2473 | ||
| 2507 | write_unlock_bh(&bond->curr_slave_lock); | 2474 | write_unlock_bh(&bond->curr_slave_lock); |
| 2508 | unblock_netpoll_tx(); | 2475 | unblock_netpoll_tx(); |
| 2476 | rtnl_unlock(); | ||
| 2509 | } | 2477 | } |
| 2510 | 2478 | ||
| 2511 | re_arm: | 2479 | re_arm: |
| 2512 | if (bond->params.arp_interval) | 2480 | if (bond->params.arp_interval) |
| 2513 | queue_delayed_work(bond->wq, &bond->arp_work, | 2481 | queue_delayed_work(bond->wq, &bond->arp_work, |
| 2514 | msecs_to_jiffies(bond->params.arp_interval)); | 2482 | msecs_to_jiffies(bond->params.arp_interval)); |
| 2515 | |||
| 2516 | read_unlock(&bond->lock); | ||
| 2517 | } | 2483 | } |
| 2518 | 2484 | ||
| 2519 | /* | 2485 | /* |
| @@ -2522,7 +2488,7 @@ re_arm: | |||
| 2522 | * place for the slave. Returns 0 if no changes are found, >0 if changes | 2488 | * place for the slave. Returns 0 if no changes are found, >0 if changes |
| 2523 | * to link states must be committed. | 2489 | * to link states must be committed. |
| 2524 | * | 2490 | * |
| 2525 | * Called with bond->lock held for read. | 2491 | * Called with rcu_read_lock hold. |
| 2526 | */ | 2492 | */ |
| 2527 | static int bond_ab_arp_inspect(struct bonding *bond) | 2493 | static int bond_ab_arp_inspect(struct bonding *bond) |
| 2528 | { | 2494 | { |
| @@ -2531,7 +2497,7 @@ static int bond_ab_arp_inspect(struct bonding *bond) | |||
| 2531 | struct slave *slave; | 2497 | struct slave *slave; |
| 2532 | int commit = 0; | 2498 | int commit = 0; |
| 2533 | 2499 | ||
| 2534 | bond_for_each_slave(bond, slave, iter) { | 2500 | bond_for_each_slave_rcu(bond, slave, iter) { |
| 2535 | slave->new_link = BOND_LINK_NOCHANGE; | 2501 | slave->new_link = BOND_LINK_NOCHANGE; |
| 2536 | last_rx = slave_last_rx(bond, slave); | 2502 | last_rx = slave_last_rx(bond, slave); |
| 2537 | 2503 | ||
| @@ -2593,7 +2559,7 @@ static int bond_ab_arp_inspect(struct bonding *bond) | |||
| 2593 | * Called to commit link state changes noted by inspection step of | 2559 | * Called to commit link state changes noted by inspection step of |
| 2594 | * active-backup mode ARP monitor. | 2560 | * active-backup mode ARP monitor. |
| 2595 | * | 2561 | * |
| 2596 | * Called with RTNL and bond->lock for read. | 2562 | * Called with RTNL hold. |
| 2597 | */ | 2563 | */ |
| 2598 | static void bond_ab_arp_commit(struct bonding *bond) | 2564 | static void bond_ab_arp_commit(struct bonding *bond) |
| 2599 | { | 2565 | { |
| @@ -2668,19 +2634,20 @@ do_failover: | |||
| 2668 | /* | 2634 | /* |
| 2669 | * Send ARP probes for active-backup mode ARP monitor. | 2635 | * Send ARP probes for active-backup mode ARP monitor. |
| 2670 | * | 2636 | * |
| 2671 | * Called with bond->lock held for read. | 2637 | * Called with rcu_read_lock hold. |
| 2672 | */ | 2638 | */ |
| 2673 | static void bond_ab_arp_probe(struct bonding *bond) | 2639 | static void bond_ab_arp_probe(struct bonding *bond) |
| 2674 | { | 2640 | { |
| 2675 | struct slave *slave, *before = NULL, *new_slave = NULL; | 2641 | struct slave *slave, *before = NULL, *new_slave = NULL, |
| 2642 | *curr_arp_slave = rcu_dereference(bond->current_arp_slave); | ||
| 2676 | struct list_head *iter; | 2643 | struct list_head *iter; |
| 2677 | bool found = false; | 2644 | bool found = false; |
| 2678 | 2645 | ||
| 2679 | read_lock(&bond->curr_slave_lock); | 2646 | read_lock(&bond->curr_slave_lock); |
| 2680 | 2647 | ||
| 2681 | if (bond->current_arp_slave && bond->curr_active_slave) | 2648 | if (curr_arp_slave && bond->curr_active_slave) |
| 2682 | pr_info("PROBE: c_arp %s && cas %s BAD\n", | 2649 | pr_info("PROBE: c_arp %s && cas %s BAD\n", |
| 2683 | bond->current_arp_slave->dev->name, | 2650 | curr_arp_slave->dev->name, |
| 2684 | bond->curr_active_slave->dev->name); | 2651 | bond->curr_active_slave->dev->name); |
| 2685 | 2652 | ||
| 2686 | if (bond->curr_active_slave) { | 2653 | if (bond->curr_active_slave) { |
| @@ -2696,15 +2663,15 @@ static void bond_ab_arp_probe(struct bonding *bond) | |||
| 2696 | * for becoming the curr_active_slave | 2663 | * for becoming the curr_active_slave |
| 2697 | */ | 2664 | */ |
| 2698 | 2665 | ||
| 2699 | if (!bond->current_arp_slave) { | 2666 | if (!curr_arp_slave) { |
| 2700 | bond->current_arp_slave = bond_first_slave(bond); | 2667 | curr_arp_slave = bond_first_slave_rcu(bond); |
| 2701 | if (!bond->current_arp_slave) | 2668 | if (!curr_arp_slave) |
| 2702 | return; | 2669 | return; |
| 2703 | } | 2670 | } |
| 2704 | 2671 | ||
| 2705 | bond_set_slave_inactive_flags(bond->current_arp_slave); | 2672 | bond_set_slave_inactive_flags(curr_arp_slave); |
| 2706 | 2673 | ||
| 2707 | bond_for_each_slave(bond, slave, iter) { | 2674 | bond_for_each_slave_rcu(bond, slave, iter) { |
| 2708 | if (!found && !before && IS_UP(slave->dev)) | 2675 | if (!found && !before && IS_UP(slave->dev)) |
| 2709 | before = slave; | 2676 | before = slave; |
| 2710 | 2677 | ||
| @@ -2727,7 +2694,7 @@ static void bond_ab_arp_probe(struct bonding *bond) | |||
| 2727 | pr_info("%s: backup interface %s is now down.\n", | 2694 | pr_info("%s: backup interface %s is now down.\n", |
| 2728 | bond->dev->name, slave->dev->name); | 2695 | bond->dev->name, slave->dev->name); |
| 2729 | } | 2696 | } |
| 2730 | if (slave == bond->current_arp_slave) | 2697 | if (slave == curr_arp_slave) |
| 2731 | found = true; | 2698 | found = true; |
| 2732 | } | 2699 | } |
| 2733 | 2700 | ||
| @@ -2741,8 +2708,7 @@ static void bond_ab_arp_probe(struct bonding *bond) | |||
| 2741 | bond_set_slave_active_flags(new_slave); | 2708 | bond_set_slave_active_flags(new_slave); |
| 2742 | bond_arp_send_all(bond, new_slave); | 2709 | bond_arp_send_all(bond, new_slave); |
| 2743 | new_slave->jiffies = jiffies; | 2710 | new_slave->jiffies = jiffies; |
| 2744 | bond->current_arp_slave = new_slave; | 2711 | rcu_assign_pointer(bond->current_arp_slave, new_slave); |
| 2745 | |||
| 2746 | } | 2712 | } |
| 2747 | 2713 | ||
| 2748 | void bond_activebackup_arp_mon(struct work_struct *work) | 2714 | void bond_activebackup_arp_mon(struct work_struct *work) |
| @@ -2752,43 +2718,38 @@ void bond_activebackup_arp_mon(struct work_struct *work) | |||
| 2752 | bool should_notify_peers = false; | 2718 | bool should_notify_peers = false; |
| 2753 | int delta_in_ticks; | 2719 | int delta_in_ticks; |
| 2754 | 2720 | ||
| 2755 | read_lock(&bond->lock); | ||
| 2756 | |||
| 2757 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); | 2721 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); |
| 2758 | 2722 | ||
| 2759 | if (!bond_has_slaves(bond)) | 2723 | if (!bond_has_slaves(bond)) |
| 2760 | goto re_arm; | 2724 | goto re_arm; |
| 2761 | 2725 | ||
| 2726 | rcu_read_lock(); | ||
| 2727 | |||
| 2762 | should_notify_peers = bond_should_notify_peers(bond); | 2728 | should_notify_peers = bond_should_notify_peers(bond); |
| 2763 | 2729 | ||
| 2764 | if (bond_ab_arp_inspect(bond)) { | 2730 | if (bond_ab_arp_inspect(bond)) { |
| 2765 | read_unlock(&bond->lock); | 2731 | rcu_read_unlock(); |
| 2766 | 2732 | ||
| 2767 | /* Race avoidance with bond_close flush of workqueue */ | 2733 | /* Race avoidance with bond_close flush of workqueue */ |
| 2768 | if (!rtnl_trylock()) { | 2734 | if (!rtnl_trylock()) { |
| 2769 | read_lock(&bond->lock); | ||
| 2770 | delta_in_ticks = 1; | 2735 | delta_in_ticks = 1; |
| 2771 | should_notify_peers = false; | 2736 | should_notify_peers = false; |
| 2772 | goto re_arm; | 2737 | goto re_arm; |
| 2773 | } | 2738 | } |
| 2774 | 2739 | ||
| 2775 | read_lock(&bond->lock); | ||
| 2776 | |||
| 2777 | bond_ab_arp_commit(bond); | 2740 | bond_ab_arp_commit(bond); |
| 2778 | 2741 | ||
| 2779 | read_unlock(&bond->lock); | ||
| 2780 | rtnl_unlock(); | 2742 | rtnl_unlock(); |
| 2781 | read_lock(&bond->lock); | 2743 | rcu_read_lock(); |
| 2782 | } | 2744 | } |
| 2783 | 2745 | ||
| 2784 | bond_ab_arp_probe(bond); | 2746 | bond_ab_arp_probe(bond); |
| 2747 | rcu_read_unlock(); | ||
| 2785 | 2748 | ||
| 2786 | re_arm: | 2749 | re_arm: |
| 2787 | if (bond->params.arp_interval) | 2750 | if (bond->params.arp_interval) |
| 2788 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); | 2751 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); |
| 2789 | 2752 | ||
| 2790 | read_unlock(&bond->lock); | ||
| 2791 | |||
| 2792 | if (should_notify_peers) { | 2753 | if (should_notify_peers) { |
| 2793 | if (!rtnl_trylock()) | 2754 | if (!rtnl_trylock()) |
| 2794 | return; | 2755 | return; |
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index dfef673d53d1..600779e5904f 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c | |||
| @@ -107,7 +107,6 @@ int bond_option_active_slave_set(struct bonding *bond, | |||
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | block_netpoll_tx(); | 109 | block_netpoll_tx(); |
| 110 | read_lock(&bond->lock); | ||
| 111 | write_lock_bh(&bond->curr_slave_lock); | 110 | write_lock_bh(&bond->curr_slave_lock); |
| 112 | 111 | ||
| 113 | /* check to see if we are clearing active */ | 112 | /* check to see if we are clearing active */ |
| @@ -142,7 +141,6 @@ int bond_option_active_slave_set(struct bonding *bond, | |||
| 142 | } | 141 | } |
| 143 | 142 | ||
| 144 | write_unlock_bh(&bond->curr_slave_lock); | 143 | write_unlock_bh(&bond->curr_slave_lock); |
| 145 | read_unlock(&bond->lock); | ||
| 146 | unblock_netpoll_tx(); | 144 | unblock_netpoll_tx(); |
| 147 | return ret; | 145 | return ret; |
| 148 | } | 146 | } |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index dad9bea95122..6368d299d5a6 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
| @@ -878,7 +878,6 @@ static ssize_t bonding_store_primary(struct device *d, | |||
| 878 | if (!rtnl_trylock()) | 878 | if (!rtnl_trylock()) |
| 879 | return restart_syscall(); | 879 | return restart_syscall(); |
| 880 | block_netpoll_tx(); | 880 | block_netpoll_tx(); |
| 881 | read_lock(&bond->lock); | ||
| 882 | write_lock_bh(&bond->curr_slave_lock); | 881 | write_lock_bh(&bond->curr_slave_lock); |
| 883 | 882 | ||
| 884 | if (!USES_PRIMARY(bond->params.mode)) { | 883 | if (!USES_PRIMARY(bond->params.mode)) { |
| @@ -918,7 +917,6 @@ static ssize_t bonding_store_primary(struct device *d, | |||
| 918 | bond->dev->name, ifname, bond->dev->name); | 917 | bond->dev->name, ifname, bond->dev->name); |
| 919 | out: | 918 | out: |
| 920 | write_unlock_bh(&bond->curr_slave_lock); | 919 | write_unlock_bh(&bond->curr_slave_lock); |
| 921 | read_unlock(&bond->lock); | ||
| 922 | unblock_netpoll_tx(); | 920 | unblock_netpoll_tx(); |
| 923 | rtnl_unlock(); | 921 | rtnl_unlock(); |
| 924 | 922 | ||
| @@ -966,11 +964,9 @@ static ssize_t bonding_store_primary_reselect(struct device *d, | |||
| 966 | new_value); | 964 | new_value); |
| 967 | 965 | ||
| 968 | block_netpoll_tx(); | 966 | block_netpoll_tx(); |
| 969 | read_lock(&bond->lock); | ||
| 970 | write_lock_bh(&bond->curr_slave_lock); | 967 | write_lock_bh(&bond->curr_slave_lock); |
| 971 | bond_select_active_slave(bond); | 968 | bond_select_active_slave(bond); |
| 972 | write_unlock_bh(&bond->curr_slave_lock); | 969 | write_unlock_bh(&bond->curr_slave_lock); |
| 973 | read_unlock(&bond->lock); | ||
| 974 | unblock_netpoll_tx(); | 970 | unblock_netpoll_tx(); |
| 975 | out: | 971 | out: |
| 976 | rtnl_unlock(); | 972 | rtnl_unlock(); |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 8283cbdec50a..8f0d6d0c383b 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
| @@ -101,6 +101,10 @@ | |||
| 101 | netdev_adjacent_get_private(bond_slave_list(bond)->prev) : \ | 101 | netdev_adjacent_get_private(bond_slave_list(bond)->prev) : \ |
| 102 | NULL) | 102 | NULL) |
| 103 | 103 | ||
| 104 | /* Caller must have rcu_read_lock */ | ||
| 105 | #define bond_first_slave_rcu(bond) \ | ||
| 106 | netdev_lower_get_first_private_rcu(bond->dev) | ||
| 107 | |||
| 104 | #define bond_is_first_slave(bond, pos) (pos == bond_first_slave(bond)) | 108 | #define bond_is_first_slave(bond, pos) (pos == bond_first_slave(bond)) |
| 105 | #define bond_is_last_slave(bond, pos) (pos == bond_last_slave(bond)) | 109 | #define bond_is_last_slave(bond, pos) (pos == bond_last_slave(bond)) |
| 106 | 110 | ||
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 5260d2eae2e6..2c74d20dad34 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -2907,6 +2907,7 @@ void *netdev_lower_get_next_private_rcu(struct net_device *dev, | |||
| 2907 | priv = netdev_lower_get_next_private_rcu(dev, &(iter))) | 2907 | priv = netdev_lower_get_next_private_rcu(dev, &(iter))) |
| 2908 | 2908 | ||
| 2909 | void *netdev_adjacent_get_private(struct list_head *adj_list); | 2909 | void *netdev_adjacent_get_private(struct list_head *adj_list); |
| 2910 | void *netdev_lower_get_first_private_rcu(struct net_device *dev); | ||
| 2910 | struct net_device *netdev_master_upper_dev_get(struct net_device *dev); | 2911 | struct net_device *netdev_master_upper_dev_get(struct net_device *dev); |
| 2911 | struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev); | 2912 | struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev); |
| 2912 | int netdev_upper_dev_link(struct net_device *dev, struct net_device *upper_dev); | 2913 | int netdev_upper_dev_link(struct net_device *dev, struct net_device *upper_dev); |
diff --git a/net/core/dev.c b/net/core/dev.c index c95d664b2b42..9d4369ece679 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -4544,6 +4544,27 @@ void *netdev_lower_get_next_private_rcu(struct net_device *dev, | |||
| 4544 | EXPORT_SYMBOL(netdev_lower_get_next_private_rcu); | 4544 | EXPORT_SYMBOL(netdev_lower_get_next_private_rcu); |
| 4545 | 4545 | ||
| 4546 | /** | 4546 | /** |
| 4547 | * netdev_lower_get_first_private_rcu - Get the first ->private from the | ||
| 4548 | * lower neighbour list, RCU | ||
| 4549 | * variant | ||
| 4550 | * @dev: device | ||
| 4551 | * | ||
| 4552 | * Gets the first netdev_adjacent->private from the dev's lower neighbour | ||
| 4553 | * list. The caller must hold RCU read lock. | ||
| 4554 | */ | ||
| 4555 | void *netdev_lower_get_first_private_rcu(struct net_device *dev) | ||
| 4556 | { | ||
| 4557 | struct netdev_adjacent *lower; | ||
| 4558 | |||
| 4559 | lower = list_first_or_null_rcu(&dev->adj_list.lower, | ||
| 4560 | struct netdev_adjacent, list); | ||
| 4561 | if (lower) | ||
| 4562 | return lower->private; | ||
| 4563 | return NULL; | ||
| 4564 | } | ||
| 4565 | EXPORT_SYMBOL(netdev_lower_get_first_private_rcu); | ||
| 4566 | |||
| 4567 | /** | ||
| 4547 | * netdev_master_upper_dev_get_rcu - Get master upper device | 4568 | * netdev_master_upper_dev_get_rcu - Get master upper device |
| 4548 | * @dev: device | 4569 | * @dev: device |
| 4549 | * | 4570 | * |
