From bc1b010c2b8bd17973287388da8c171332b70b3f Mon Sep 17 00:00:00 2001
From: Ethan Jackson
Date: Wed, 25 Jan 2012 17:41:44 -0800
Subject: [PATCH] bond: Allow users to disable rebalancing.
Bond rebalances come with a risk of packet reordering which some
users may find unacceptable.
Requested-by: Ben Basler
Signed-off-by: Ethan Jackson
---
AUTHORS | 1 +
NEWS | 2 ++
lib/bond.c | 20 +++++++++++++-------
lib/bond.h | 3 ++-
vswitchd/bridge.c | 2 +-
vswitchd/vswitch.xml | 12 +++++++-----
6 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index a24f9707..87bb7212 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -66,6 +66,7 @@ Alan Shieh ashieh@nicira.com
Alban Browaeys prahal@yahoo.com
Alex Yip alex@nicira.com
Alexey I. Froloff raorn@altlinux.org
+Ben Basler bbasler@nicira.com
Bob Ball bob.ball@citrix.com
Brad Hall brad@nicira.com
Brandon Heller brandonh@stanford.edu
diff --git a/NEWS b/NEWS
index e015739d..aa28eeb9 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,8 @@ post-v1.5.0
- The default bond_mode changed from SLB to active-backup, to protect
unsuspecting users from the significant risks of SLB bonds (which are
documented in vswitchd/INTERNALS).
+ - Load balancing can be disabled by setting the bond-rebalance-interval
+ to zero.
- Logging to console and file will have UTC timestamp as a default for all
the daemons. An example of the default format is 2012-01-27T16:35:17Z.
ovs-appctl can be used to change the default format as before.
diff --git a/lib/bond.c b/lib/bond.c
index 50a1d5d0..157e9889 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 9eb1b8fb..6d8161d8 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 06e9088e..a00d4cfa 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 b720f059..d04a3a2a 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -918,11 +918,13 @@
- 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 a 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 (carrier status changes still cause flows to move). If
+ less than 1000ms, the rebalance interval will be 1000ms.
--
2.30.2