aboutsummaryrefslogtreecommitdiff
path: root/vswitchd
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2010-04-05 14:21:38 -0700
committerBen Pfaff <blp@nicira.com>2010-04-05 16:41:50 -0700
commitc8143c8879228e6d70345a0ef5cae5f416ff330d (patch)
tree66ce1aece1b16fc5ccd8c8de389b41297776cf87 /vswitchd
parent18b239f5833014524bc89f06bd54a0da518cdf78 (diff)
vswitchd: Make the bond rebalancing interval user-configurable.
This may make some bond debugging problems easier. It also seems reasonable to expose this parameter to the user. Related to bug #2366.
Diffstat (limited to 'vswitchd')
-rw-r--r--vswitchd/bridge.c58
-rw-r--r--vswitchd/vswitch.xml7
2 files changed, 50 insertions, 15 deletions
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 130e0949..79861680 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -137,6 +137,8 @@ struct port {
int updelay, downdelay; /* Delay before iface goes up/down, in ms. */
bool bond_compat_is_stale; /* Need to call port_update_bond_compat()? */
bool bond_fake_iface; /* Fake a bond interface for legacy compat? */
+ int bond_rebalance_interval; /* Interval between rebalances, in ms. */
+ long long int bond_next_rebalance; /* Next rebalancing time. */
/* Port mirroring info. */
mirror_mask_t src_mirrors; /* Mirrors triggered when packet received. */
@@ -180,7 +182,6 @@ struct bridge {
/* Bonding. */
bool has_bonded_ports;
- long long int bond_next_rebalance;
/* Flow tracking. */
bool flush;
@@ -807,18 +808,27 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
}
static const char *
-bridge_get_other_config(const struct ovsrec_bridge *br_cfg, const char *key)
+get_ovsrec_key_value(const char *key, char **keys, char **values, size_t n)
{
size_t i;
- for (i = 0; i < br_cfg->n_other_config; i++) {
- if (!strcmp(br_cfg->key_other_config[i], key)) {
- return br_cfg->value_other_config[i];
+ for (i = 0; i < n; i++) {
+ if (!strcmp(keys[i], key)) {
+ return values[i];
}
}
return NULL;
}
+static const char *
+bridge_get_other_config(const struct ovsrec_bridge *br_cfg, const char *key)
+{
+ return get_ovsrec_key_value(key,
+ br_cfg->key_other_config,
+ br_cfg->value_other_config,
+ br_cfg->n_other_config);
+}
+
static void
bridge_pick_local_hw_addr(struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
struct iface **hw_addr_iface)
@@ -1145,7 +1155,6 @@ bridge_create(const struct ovsrec_bridge *br_cfg)
port_array_init(&br->ifaces);
br->flush = false;
- br->bond_next_rebalance = time_msec() + 10000;
list_push_back(&all_bridges, &br->node);
@@ -2365,22 +2374,18 @@ static void
bridge_account_checkpoint_ofhook_cb(void *br_)
{
struct bridge *br = br_;
+ long long int now;
size_t i;
if (!br->has_bonded_ports) {
return;
}
- /* The current ofproto implementation calls this callback at least once a
- * second, so this timer implementation is sufficient. */
- if (time_msec() < br->bond_next_rebalance) {
- return;
- }
- br->bond_next_rebalance = time_msec() + 10000;
-
+ now = time_msec();
for (i = 0; i < br->n_ports; i++) {
struct port *port = br->ports[i];
- if (port->n_ifaces > 1) {
+ if (port->n_ifaces > 1 && now >= port->bond_next_rebalance) {
+ port->bond_next_rebalance = now + port->bond_rebalance_interval;
bond_rebalance_port(port);
}
}
@@ -2827,7 +2832,7 @@ bond_unixctl_show(struct unixctl_conn *conn,
ds_put_format(&ds, "updelay: %d ms\n", port->updelay);
ds_put_format(&ds, "downdelay: %d ms\n", port->downdelay);
ds_put_format(&ds, "next rebalance: %lld ms\n",
- port->bridge->bond_next_rebalance - time_msec());
+ port->bond_next_rebalance - time_msec());
for (j = 0; j < port->n_ifaces; j++) {
const struct iface *iface = port->ifaces[j];
struct bond_entry *be;
@@ -3090,10 +3095,22 @@ port_create(struct bridge *br, const char *name)
return port;
}
+static const char *
+get_port_other_config(const struct ovsrec_port *port, const char *key,
+ const char *default_value)
+{
+ const char *value = get_ovsrec_key_value(key,
+ port->key_other_config,
+ port->value_other_config,
+ port->n_other_config);
+ return value ? value : default_value;
+}
+
static void
port_reconfigure(struct port *port, const struct ovsrec_port *cfg)
{
struct shash old_ifaces, new_ifaces;
+ long long int next_rebalance;
struct shash_node *node;
unsigned long *trunks;
int vlan;
@@ -3122,6 +3139,15 @@ port_reconfigure(struct port *port, const struct ovsrec_port *cfg)
if (port->downdelay < 0) {
port->downdelay = 0;
}
+ port->bond_rebalance_interval = atoi(
+ get_port_other_config(cfg, "bond-rebalance-interval", "10000"));
+ if (port->bond_rebalance_interval < 1000) {
+ port->bond_rebalance_interval = 1000;
+ }
+ next_rebalance = time_msec() + port->bond_rebalance_interval;
+ if (port->bond_next_rebalance > next_rebalance) {
+ port->bond_next_rebalance = next_rebalance;
+ }
/* Get rid of deleted interfaces and add new interfaces. */
SHASH_FOR_EACH (node, &old_ifaces) {
@@ -3299,6 +3325,8 @@ port_update_bonding(struct port *port)
}
port->no_ifaces_tag = tag_create_random();
bond_choose_active_iface(port);
+ port->bond_next_rebalance
+ = time_msec() + port->bond_rebalance_interval;
}
port->bond_compat_is_stale = true;
port->bond_fake_iface = port->cfg->bond_fake_iface;
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index e6ad3872..e0f7d828 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -278,6 +278,13 @@
<dt><code>hwaddr</code></dt>
<dd>An Ethernet address in the form
<code><var>xx</var>:<var>xx</var>:<var>xx</var>:<var>xx</var>:<var>xx</var>:<var>xx</var></code>.</dd>
+ <dt><code>bond-rebalance-interval</code></dt>
+ <dd>For a 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. The default is 10000 (10
+ seconds), and the minimum is 1000 (1 second).</dd>
</dl>
</column>
</group>