diff options
| -rw-r--r-- | drivers/net/bonding/bond_main.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 19eb990d398c..317a49480475 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -689,40 +689,57 @@ out: | |||
| 689 | 689 | ||
| 690 | } | 690 | } |
| 691 | 691 | ||
| 692 | static bool bond_should_change_active(struct bonding *bond) | 692 | static struct slave *bond_choose_primary_or_current(struct bonding *bond) |
| 693 | { | 693 | { |
| 694 | struct slave *prim = rtnl_dereference(bond->primary_slave); | 694 | struct slave *prim = rtnl_dereference(bond->primary_slave); |
| 695 | struct slave *curr = rtnl_dereference(bond->curr_active_slave); | 695 | struct slave *curr = rtnl_dereference(bond->curr_active_slave); |
| 696 | 696 | ||
| 697 | if (!prim || !curr || curr->link != BOND_LINK_UP) | 697 | if (!prim || prim->link != BOND_LINK_UP) { |
| 698 | return true; | 698 | if (!curr || curr->link != BOND_LINK_UP) |
| 699 | return NULL; | ||
| 700 | return curr; | ||
| 701 | } | ||
| 702 | |||
| 699 | if (bond->force_primary) { | 703 | if (bond->force_primary) { |
| 700 | bond->force_primary = false; | 704 | bond->force_primary = false; |
| 701 | return true; | 705 | return prim; |
| 706 | } | ||
| 707 | |||
| 708 | if (!curr || curr->link != BOND_LINK_UP) | ||
| 709 | return prim; | ||
| 710 | |||
| 711 | /* At this point, prim and curr are both up */ | ||
| 712 | switch (bond->params.primary_reselect) { | ||
| 713 | case BOND_PRI_RESELECT_ALWAYS: | ||
| 714 | return prim; | ||
| 715 | case BOND_PRI_RESELECT_BETTER: | ||
| 716 | if (prim->speed < curr->speed) | ||
| 717 | return curr; | ||
| 718 | if (prim->speed == curr->speed && prim->duplex <= curr->duplex) | ||
| 719 | return curr; | ||
| 720 | return prim; | ||
| 721 | case BOND_PRI_RESELECT_FAILURE: | ||
| 722 | return curr; | ||
| 723 | default: | ||
| 724 | netdev_err(bond->dev, "impossible primary_reselect %d\n", | ||
| 725 | bond->params.primary_reselect); | ||
| 726 | return curr; | ||
| 702 | } | 727 | } |
| 703 | if (bond->params.primary_reselect == BOND_PRI_RESELECT_BETTER && | ||
| 704 | (prim->speed < curr->speed || | ||
| 705 | (prim->speed == curr->speed && prim->duplex <= curr->duplex))) | ||
| 706 | return false; | ||
| 707 | if (bond->params.primary_reselect == BOND_PRI_RESELECT_FAILURE) | ||
| 708 | return false; | ||
| 709 | return true; | ||
| 710 | } | 728 | } |
| 711 | 729 | ||
| 712 | /** | 730 | /** |
| 713 | * find_best_interface - select the best available slave to be the active one | 731 | * bond_find_best_slave - select the best available slave to be the active one |
| 714 | * @bond: our bonding struct | 732 | * @bond: our bonding struct |
| 715 | */ | 733 | */ |
| 716 | static struct slave *bond_find_best_slave(struct bonding *bond) | 734 | static struct slave *bond_find_best_slave(struct bonding *bond) |
| 717 | { | 735 | { |
| 718 | struct slave *slave, *bestslave = NULL, *primary; | 736 | struct slave *slave, *bestslave = NULL; |
| 719 | struct list_head *iter; | 737 | struct list_head *iter; |
| 720 | int mintime = bond->params.updelay; | 738 | int mintime = bond->params.updelay; |
| 721 | 739 | ||
| 722 | primary = rtnl_dereference(bond->primary_slave); | 740 | slave = bond_choose_primary_or_current(bond); |
| 723 | if (primary && primary->link == BOND_LINK_UP && | 741 | if (slave) |
| 724 | bond_should_change_active(bond)) | 742 | return slave; |
| 725 | return primary; | ||
| 726 | 743 | ||
| 727 | bond_for_each_slave(bond, slave, iter) { | 744 | bond_for_each_slave(bond, slave, iter) { |
| 728 | if (slave->link == BOND_LINK_UP) | 745 | if (slave->link == BOND_LINK_UP) |
