aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2009-09-24 23:28:09 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-07 04:07:39 -0400
commita549952ad323d68daf5b50bf716db895479af84c (patch)
treec819e8c33701696115c3d60b12ca95a0cd792291 /drivers/net/bonding/bond_main.c
parent2d37a186cedc51502dbee71c16ae0fbd9114d62c (diff)
bonding: introduce primary_reselect option
In some cases there is not desirable to switch back to primary interface when it's link recovers and rather stay with currently active one. We need to avoid packetloss as much as we can in some cases. This is solved by introducing primary_reselect option. Note that enslaved primary slave is set as current active no matter what. Patch modified by Jay Vosburgh as follows: fixed bug in action after change of option setting via sysfs, revised the documentation update, and bumped the bonding version number. Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c66
1 files changed, 61 insertions, 5 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 69c5b15e22da..19d57d537ec1 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -94,6 +94,7 @@ static int downdelay;
94static int use_carrier = 1; 94static int use_carrier = 1;
95static char *mode; 95static char *mode;
96static char *primary; 96static char *primary;
97static char *primary_reselect;
97static char *lacp_rate; 98static char *lacp_rate;
98static char *ad_select; 99static char *ad_select;
99static char *xmit_hash_policy; 100static char *xmit_hash_policy;
@@ -126,6 +127,14 @@ MODULE_PARM_DESC(mode, "Mode of operation : 0 for balance-rr, "
126 "6 for balance-alb"); 127 "6 for balance-alb");
127module_param(primary, charp, 0); 128module_param(primary, charp, 0);
128MODULE_PARM_DESC(primary, "Primary network device to use"); 129MODULE_PARM_DESC(primary, "Primary network device to use");
130module_param(primary_reselect, charp, 0);
131MODULE_PARM_DESC(primary_reselect, "Reselect primary slave "
132 "once it comes up; "
133 "0 for always (default), "
134 "1 for only if speed of primary is "
135 "better, "
136 "2 for only on active slave "
137 "failure");
129module_param(lacp_rate, charp, 0); 138module_param(lacp_rate, charp, 0);
130MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner " 139MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
131 "(slow/fast)"); 140 "(slow/fast)");
@@ -200,6 +209,13 @@ const struct bond_parm_tbl fail_over_mac_tbl[] = {
200{ NULL, -1}, 209{ NULL, -1},
201}; 210};
202 211
212const struct bond_parm_tbl pri_reselect_tbl[] = {
213{ "always", BOND_PRI_RESELECT_ALWAYS},
214{ "better", BOND_PRI_RESELECT_BETTER},
215{ "failure", BOND_PRI_RESELECT_FAILURE},
216{ NULL, -1},
217};
218
203struct bond_parm_tbl ad_select_tbl[] = { 219struct bond_parm_tbl ad_select_tbl[] = {
204{ "stable", BOND_AD_STABLE}, 220{ "stable", BOND_AD_STABLE},
205{ "bandwidth", BOND_AD_BANDWIDTH}, 221{ "bandwidth", BOND_AD_BANDWIDTH},
@@ -1070,6 +1086,25 @@ out:
1070 1086
1071} 1087}
1072 1088
1089static bool bond_should_change_active(struct bonding *bond)
1090{
1091 struct slave *prim = bond->primary_slave;
1092 struct slave *curr = bond->curr_active_slave;
1093
1094 if (!prim || !curr || curr->link != BOND_LINK_UP)
1095 return true;
1096 if (bond->force_primary) {
1097 bond->force_primary = false;
1098 return true;
1099 }
1100 if (bond->params.primary_reselect == BOND_PRI_RESELECT_BETTER &&
1101 (prim->speed < curr->speed ||
1102 (prim->speed == curr->speed && prim->duplex <= curr->duplex)))
1103 return false;
1104 if (bond->params.primary_reselect == BOND_PRI_RESELECT_FAILURE)
1105 return false;
1106 return true;
1107}
1073 1108
1074/** 1109/**
1075 * find_best_interface - select the best available slave to be the active one 1110 * find_best_interface - select the best available slave to be the active one
@@ -1094,7 +1129,8 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
1094 } 1129 }
1095 1130
1096 if ((bond->primary_slave) && 1131 if ((bond->primary_slave) &&
1097 bond->primary_slave->link == BOND_LINK_UP) { 1132 bond->primary_slave->link == BOND_LINK_UP &&
1133 bond_should_change_active(bond)) {
1098 new_active = bond->primary_slave; 1134 new_active = bond->primary_slave;
1099 } 1135 }
1100 1136
@@ -1678,8 +1714,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1678 1714
1679 if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) { 1715 if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
1680 /* if there is a primary slave, remember it */ 1716 /* if there is a primary slave, remember it */
1681 if (strcmp(bond->params.primary, new_slave->dev->name) == 0) 1717 if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
1682 bond->primary_slave = new_slave; 1718 bond->primary_slave = new_slave;
1719 bond->force_primary = true;
1720 }
1683 } 1721 }
1684 1722
1685 write_lock_bh(&bond->curr_slave_lock); 1723 write_lock_bh(&bond->curr_slave_lock);
@@ -3201,11 +3239,14 @@ static void bond_info_show_master(struct seq_file *seq)
3201 } 3239 }
3202 3240
3203 if (USES_PRIMARY(bond->params.mode)) { 3241 if (USES_PRIMARY(bond->params.mode)) {
3204 seq_printf(seq, "Primary Slave: %s\n", 3242 seq_printf(seq, "Primary Slave: %s",
3205 (bond->primary_slave) ? 3243 (bond->primary_slave) ?
3206 bond->primary_slave->dev->name : "None"); 3244 bond->primary_slave->dev->name : "None");
3245 if (bond->primary_slave)
3246 seq_printf(seq, " (primary_reselect %s)",
3247 pri_reselect_tbl[bond->params.primary_reselect].modename);
3207 3248
3208 seq_printf(seq, "Currently Active Slave: %s\n", 3249 seq_printf(seq, "\nCurrently Active Slave: %s\n",
3209 (curr) ? curr->dev->name : "None"); 3250 (curr) ? curr->dev->name : "None");
3210 } 3251 }
3211 3252
@@ -4646,7 +4687,7 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
4646 4687
4647static int bond_check_params(struct bond_params *params) 4688static int bond_check_params(struct bond_params *params)
4648{ 4689{
4649 int arp_validate_value, fail_over_mac_value; 4690 int arp_validate_value, fail_over_mac_value, primary_reselect_value;
4650 4691
4651 /* 4692 /*
4652 * Convert string parameters. 4693 * Convert string parameters.
@@ -4945,6 +4986,20 @@ static int bond_check_params(struct bond_params *params)
4945 primary = NULL; 4986 primary = NULL;
4946 } 4987 }
4947 4988
4989 if (primary && primary_reselect) {
4990 primary_reselect_value = bond_parse_parm(primary_reselect,
4991 pri_reselect_tbl);
4992 if (primary_reselect_value == -1) {
4993 pr_err(DRV_NAME
4994 ": Error: Invalid primary_reselect \"%s\"\n",
4995 primary_reselect ==
4996 NULL ? "NULL" : primary_reselect);
4997 return -EINVAL;
4998 }
4999 } else {
5000 primary_reselect_value = BOND_PRI_RESELECT_ALWAYS;
5001 }
5002
4948 if (fail_over_mac) { 5003 if (fail_over_mac) {
4949 fail_over_mac_value = bond_parse_parm(fail_over_mac, 5004 fail_over_mac_value = bond_parse_parm(fail_over_mac,
4950 fail_over_mac_tbl); 5005 fail_over_mac_tbl);
@@ -4976,6 +5031,7 @@ static int bond_check_params(struct bond_params *params)
4976 params->use_carrier = use_carrier; 5031 params->use_carrier = use_carrier;
4977 params->lacp_fast = lacp_fast; 5032 params->lacp_fast = lacp_fast;
4978 params->primary[0] = 0; 5033 params->primary[0] = 0;
5034 params->primary_reselect = primary_reselect_value;
4979 params->fail_over_mac = fail_over_mac_value; 5035 params->fail_over_mac = fail_over_mac_value;
4980 5036
4981 if (primary) { 5037 if (primary) {