Bond rebalances come with a risk of packet reordering which some users may find unacceptable.
Requested-by: Ben Basler <bbas...@nicira.com> Signed-off-by: Ethan Jackson <et...@nicira.com> --- AUTHORS | 1 + lib/bond.c | 20 +++++++++++++------- lib/bond.h | 3 ++- vswitchd/bridge.c | 2 +- vswitchd/vswitch.xml | 12 +++++++----- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/AUTHORS b/AUTHORS index 4479aeb..e81f563 100644 --- a/AUTHORS +++ b/AUTHORS @@ -65,6 +65,7 @@ Ahmed Bilal numan...@gmail.com Alban Browaeys pra...@yahoo.com Alex Yip a...@nicira.com Alexey I. Froloff ra...@altlinux.org +Ben Basler bbas...@nicira.com Bob Ball bob.b...@citrix.com Brad Hall b...@nicira.com Brandon Heller brand...@stanford.edu diff --git a/lib/bond.c b/lib/bond.c index 50a1d5d..157e988 100644 --- a/lib/bond.c +++ b/lib/bond.c @@ -246,7 +246,11 @@ bond_reconfigure(struct bond *bond, const struct bond_settings *s) bond->updelay = s->up_delay; bond->downdelay = s->down_delay; - bond->rebalance_interval = s->rebalance_interval; + + if (bond->rebalance_interval != s->rebalance_interval) { + bond->rebalance_interval = s->rebalance_interval; + revalidate = true; + } if (bond->balance != s->balance) { bond->balance = s->balance; @@ -648,7 +652,8 @@ bond_choose_output_slave(struct bond *bond, const struct flow *flow, static bool bond_is_balanced(const struct bond *bond) { - return bond->balance == BM_SLB || bond->balance == BM_TCP; + return bond->rebalance_interval + && (bond->balance == BM_SLB || bond->balance == BM_TCP); } /* Notifies 'bond' that 'n_bytes' bytes were sent in 'flow' within 'vlan'. */ @@ -1376,15 +1381,13 @@ lookup_bond_entry(const struct bond *bond, const struct flow *flow, * more complex implementations and require the use of memory. This may need * to be reimplemented if it becomes a performance bottleneck. */ static struct bond_slave * -choose_stb_slave(const struct bond *bond, const struct flow *flow, - uint16_t vlan) +choose_stb_slave(const struct bond *bond, uint32_t flow_hash) { struct bond_slave *best, *slave; - uint32_t best_hash, flow_hash; + uint32_t best_hash; best = NULL; best_hash = 0; - flow_hash = bond_hash_tcp(flow, vlan, bond->basis); HMAP_FOR_EACH (slave, hmap_node, &bond->slaves) { if (slave->enabled) { uint32_t hash; @@ -1417,7 +1420,7 @@ choose_output_slave(const struct bond *bond, const struct flow *flow, return bond->active_slave; case BM_STABLE: - return choose_stb_slave(bond, flow, vlan); + return choose_stb_slave(bond, bond_hash_tcp(flow, vlan, bond->basis)); case BM_TCP: if (bond->lacp_status != LACP_NEGOTIATED) { @@ -1426,6 +1429,9 @@ choose_output_slave(const struct bond *bond, const struct flow *flow, } /* Fall Through. */ case BM_SLB: + if (!bond_is_balanced(bond)) { + return choose_stb_slave(bond, bond_hash(bond, flow, vlan)); + } e = lookup_bond_entry(bond, flow, vlan); if (!e->slave || !e->slave->enabled) { e->slave = CONTAINER_OF(hmap_random_node(&bond->slaves), diff --git a/lib/bond.h b/lib/bond.h index 9eb1b8f..6d8161d 100644 --- a/lib/bond.h +++ b/lib/bond.h @@ -46,7 +46,8 @@ struct bond_settings { /* Balancing configuration. */ enum bond_mode balance; - int rebalance_interval; /* Milliseconds between rebalances. */ + int rebalance_interval; /* Milliseconds between rebalances. + Zero to disable rebalancing. */ /* Link status detection. */ int up_delay; /* ms before enabling an up slave. */ diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 06e9088..a00d4cf 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -2790,7 +2790,7 @@ port_configure_bond(struct port *port, struct bond_settings *s, s->basis = atoi(get_port_other_config(port->cfg, "bond-hash-basis", "0")); s->rebalance_interval = atoi( get_port_other_config(port->cfg, "bond-rebalance-interval", "10000")); - if (s->rebalance_interval < 1000) { + if (s->rebalance_interval && s->rebalance_interval < 1000) { s->rebalance_interval = 1000; } diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index b720f05..71fee39 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -918,11 +918,13 @@ </p> <column name="other_config" key="bond-rebalance-interval" - type='{"type": "integer", "minInteger": 1000, "maxInteger": 10000}'> - For an SLB bonded port, the number of milliseconds between successive - attempts to rebalance the bond, that is, to move source MACs and - their flows from one interface on the bond to another in an attempt - to keep usage of each interface roughly equal. + type='{"type": "integer", "minInteger": 0, "maxInteger": 10000}'> + For an load balanced bonded port, the number of milliseconds between + successive attempts to rebalance the bond, that is, to move flows + from one interface on the bond to another in an attempt to keep usage + of each interface roughly equal. If zero, load balancing is disabled + on the bond. If less than 1000ms, the rebalance interval will be + 1000ms. </column> </group> -- 1.7.8.3 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev