diff options
author | Veaceslav Falico <vfalico@redhat.com> | 2013-10-21 05:48:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-22 19:22:09 -0400 |
commit | 5378c2e6ea236de847a39bdb6f3aa83137120d26 (patch) | |
tree | 3fea10f4900112c624ff9474ef9453ecea8766d1 | |
parent | 666d10085924d9dd4bcab7653f5d4971d8ea2498 (diff) |
bonding: move bond-specific init after enslave happens
As Jiri noted, currently we first do all bonding-specific initialization
(specifically - bond_select_active_slave(bond)) before we actually attach
the slave (so that it becomes visible through bond_for_each_slave() and
friends). This might result in bond_select_active_slave() not seeing the
first/new slave and, thus, not actually selecting an active slave.
Fix this by moving all the bond-related init part after we've actually
completely initialized and linked (via bond_master_upper_dev_link()) the
new slave.
Also, remove the bond_(de/a)ttach_slave(), it's useless to have functions
to ++/-- one int.
After this we have all the initialization of the new slave *before*
linking, and all the stuff that needs to be done on bonding *after* it. It
has also a bonus effect - we can remove the locking on the new slave init
completely, and only use it for bond_select_active_slave().
Reported-by: Jiri Pirko <jiri@resnulli.us>
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
Acked-by: Ding Tianhong@huawei.com
Reviewed-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/bonding/bond_main.c | 65 |
1 files changed, 14 insertions, 51 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d90734fca918..2daa066c6cdd 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -967,33 +967,6 @@ void bond_select_active_slave(struct bonding *bond) | |||
967 | } | 967 | } |
968 | } | 968 | } |
969 | 969 | ||
970 | /*--------------------------- slave list handling ---------------------------*/ | ||
971 | |||
972 | /* | ||
973 | * This function attaches the slave to the end of list. | ||
974 | * | ||
975 | * bond->lock held for writing by caller. | ||
976 | */ | ||
977 | static void bond_attach_slave(struct bonding *bond, struct slave *new_slave) | ||
978 | { | ||
979 | bond->slave_cnt++; | ||
980 | } | ||
981 | |||
982 | /* | ||
983 | * This function detaches the slave from the list. | ||
984 | * WARNING: no check is made to verify if the slave effectively | ||
985 | * belongs to <bond>. | ||
986 | * Nothing is freed on return, structures are just unchained. | ||
987 | * If any slave pointer in bond was pointing to <slave>, | ||
988 | * it should be changed by the calling function. | ||
989 | * | ||
990 | * bond->lock held for writing by caller. | ||
991 | */ | ||
992 | static void bond_detach_slave(struct bonding *bond, struct slave *slave) | ||
993 | { | ||
994 | bond->slave_cnt--; | ||
995 | } | ||
996 | |||
997 | #ifdef CONFIG_NET_POLL_CONTROLLER | 970 | #ifdef CONFIG_NET_POLL_CONTROLLER |
998 | static inline int slave_enable_netpoll(struct slave *slave) | 971 | static inline int slave_enable_netpoll(struct slave *slave) |
999 | { | 972 | { |
@@ -1471,22 +1444,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1471 | goto err_close; | 1444 | goto err_close; |
1472 | } | 1445 | } |
1473 | 1446 | ||
1474 | write_lock_bh(&bond->lock); | ||
1475 | |||
1476 | prev_slave = bond_last_slave(bond); | 1447 | prev_slave = bond_last_slave(bond); |
1477 | bond_attach_slave(bond, new_slave); | ||
1478 | 1448 | ||
1479 | new_slave->delay = 0; | 1449 | new_slave->delay = 0; |
1480 | new_slave->link_failure_count = 0; | 1450 | new_slave->link_failure_count = 0; |
1481 | 1451 | ||
1482 | write_unlock_bh(&bond->lock); | ||
1483 | |||
1484 | bond_compute_features(bond); | ||
1485 | |||
1486 | bond_update_speed_duplex(new_slave); | 1452 | bond_update_speed_duplex(new_slave); |
1487 | 1453 | ||
1488 | read_lock(&bond->lock); | ||
1489 | |||
1490 | new_slave->last_arp_rx = jiffies - | 1454 | new_slave->last_arp_rx = jiffies - |
1491 | (msecs_to_jiffies(bond->params.arp_interval) + 1); | 1455 | (msecs_to_jiffies(bond->params.arp_interval) + 1); |
1492 | for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) | 1456 | for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) |
@@ -1547,12 +1511,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1547 | } | 1511 | } |
1548 | } | 1512 | } |
1549 | 1513 | ||
1550 | write_lock_bh(&bond->curr_slave_lock); | ||
1551 | |||
1552 | switch (bond->params.mode) { | 1514 | switch (bond->params.mode) { |
1553 | case BOND_MODE_ACTIVEBACKUP: | 1515 | case BOND_MODE_ACTIVEBACKUP: |
1554 | bond_set_slave_inactive_flags(new_slave); | 1516 | bond_set_slave_inactive_flags(new_slave); |
1555 | bond_select_active_slave(bond); | ||
1556 | break; | 1517 | break; |
1557 | case BOND_MODE_8023AD: | 1518 | case BOND_MODE_8023AD: |
1558 | /* in 802.3ad mode, the internal mechanism | 1519 | /* in 802.3ad mode, the internal mechanism |
@@ -1578,7 +1539,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1578 | case BOND_MODE_ALB: | 1539 | case BOND_MODE_ALB: |
1579 | bond_set_active_slave(new_slave); | 1540 | bond_set_active_slave(new_slave); |
1580 | bond_set_slave_inactive_flags(new_slave); | 1541 | bond_set_slave_inactive_flags(new_slave); |
1581 | bond_select_active_slave(bond); | ||
1582 | break; | 1542 | break; |
1583 | default: | 1543 | default: |
1584 | pr_debug("This slave is always active in trunk mode\n"); | 1544 | pr_debug("This slave is always active in trunk mode\n"); |
@@ -1596,10 +1556,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1596 | break; | 1556 | break; |
1597 | } /* switch(bond_mode) */ | 1557 | } /* switch(bond_mode) */ |
1598 | 1558 | ||
1599 | write_unlock_bh(&bond->curr_slave_lock); | ||
1600 | |||
1601 | bond_set_carrier(bond); | ||
1602 | |||
1603 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1559 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1604 | slave_dev->npinfo = bond->dev->npinfo; | 1560 | slave_dev->npinfo = bond->dev->npinfo; |
1605 | if (slave_dev->npinfo) { | 1561 | if (slave_dev->npinfo) { |
@@ -1614,8 +1570,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1614 | } | 1570 | } |
1615 | #endif | 1571 | #endif |
1616 | 1572 | ||
1617 | read_unlock(&bond->lock); | ||
1618 | |||
1619 | res = netdev_rx_handler_register(slave_dev, bond_handle_frame, | 1573 | res = netdev_rx_handler_register(slave_dev, bond_handle_frame, |
1620 | new_slave); | 1574 | new_slave); |
1621 | if (res) { | 1575 | if (res) { |
@@ -1629,6 +1583,17 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1629 | goto err_unregister; | 1583 | goto err_unregister; |
1630 | } | 1584 | } |
1631 | 1585 | ||
1586 | bond->slave_cnt++; | ||
1587 | bond_compute_features(bond); | ||
1588 | bond_set_carrier(bond); | ||
1589 | |||
1590 | if (USES_PRIMARY(bond->params.mode)) { | ||
1591 | read_lock(&bond->lock); | ||
1592 | write_lock_bh(&bond->curr_slave_lock); | ||
1593 | bond_select_active_slave(bond); | ||
1594 | write_unlock_bh(&bond->curr_slave_lock); | ||
1595 | read_unlock(&bond->lock); | ||
1596 | } | ||
1632 | 1597 | ||
1633 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", | 1598 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", |
1634 | bond_dev->name, slave_dev->name, | 1599 | bond_dev->name, slave_dev->name, |
@@ -1648,7 +1613,6 @@ err_detach: | |||
1648 | 1613 | ||
1649 | vlan_vids_del_by_dev(slave_dev, bond_dev); | 1614 | vlan_vids_del_by_dev(slave_dev, bond_dev); |
1650 | write_lock_bh(&bond->lock); | 1615 | write_lock_bh(&bond->lock); |
1651 | bond_detach_slave(bond, new_slave); | ||
1652 | if (bond->primary_slave == new_slave) | 1616 | if (bond->primary_slave == new_slave) |
1653 | bond->primary_slave = NULL; | 1617 | bond->primary_slave = NULL; |
1654 | if (bond->curr_active_slave == new_slave) { | 1618 | if (bond->curr_active_slave == new_slave) { |
@@ -1686,7 +1650,6 @@ err_free: | |||
1686 | kfree(new_slave); | 1650 | kfree(new_slave); |
1687 | 1651 | ||
1688 | err_undo_flags: | 1652 | err_undo_flags: |
1689 | bond_compute_features(bond); | ||
1690 | /* Enslave of first slave has failed and we need to fix master's mac */ | 1653 | /* Enslave of first slave has failed and we need to fix master's mac */ |
1691 | if (!bond_has_slaves(bond) && | 1654 | if (!bond_has_slaves(bond) && |
1692 | ether_addr_equal(bond_dev->dev_addr, slave_dev->dev_addr)) | 1655 | ether_addr_equal(bond_dev->dev_addr, slave_dev->dev_addr)) |
@@ -1740,6 +1703,9 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
1740 | 1703 | ||
1741 | write_unlock_bh(&bond->lock); | 1704 | write_unlock_bh(&bond->lock); |
1742 | 1705 | ||
1706 | /* release the slave from its bond */ | ||
1707 | bond->slave_cnt--; | ||
1708 | |||
1743 | bond_upper_dev_unlink(bond_dev, slave_dev); | 1709 | bond_upper_dev_unlink(bond_dev, slave_dev); |
1744 | /* unregister rx_handler early so bond_handle_frame wouldn't be called | 1710 | /* unregister rx_handler early so bond_handle_frame wouldn't be called |
1745 | * for this slave anymore. | 1711 | * for this slave anymore. |
@@ -1764,9 +1730,6 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
1764 | 1730 | ||
1765 | bond->current_arp_slave = NULL; | 1731 | bond->current_arp_slave = NULL; |
1766 | 1732 | ||
1767 | /* release the slave from its bond */ | ||
1768 | bond_detach_slave(bond, slave); | ||
1769 | |||
1770 | if (!all && !bond->params.fail_over_mac) { | 1733 | if (!all && !bond->params.fail_over_mac) { |
1771 | if (ether_addr_equal(bond_dev->dev_addr, slave->perm_hwaddr) && | 1734 | if (ether_addr_equal(bond_dev->dev_addr, slave->perm_hwaddr) && |
1772 | bond_has_slaves(bond)) | 1735 | bond_has_slaves(bond)) |