summaryrefslogtreecommitdiff
path: root/vswitchd
diff options
context:
space:
mode:
authorJustin Pettit <jpettit@nicira.com>2014-04-28 14:25:06 -0700
committerJustin Pettit <jpettit@nicira.com>2014-07-25 12:05:20 -0700
commit816f3bca9f5d23a0cf3b2ec922382f72b7b1b0d6 (patch)
treed0c40aa9be6af9ab84fb2d0b93d8152787806861 /vswitchd
parentdf0e5f55763289e37f90d1f2464423f07478f372 (diff)
downloadopenvswitch-elephant.tar.gz
Initial check-in of kernel-based elephant flow detection.elephant
Areas to work on: - Doesn't populate "elephant-flows" field. - Doesn't properly handle tunnels. - Doesn't have clean way to query elephant table. - Double-check locking. - Should use names instead of number for mechanism. - When changing detection mechanism, should clear old table. - Breaks unit tests
Diffstat (limited to 'vswitchd')
-rw-r--r--vswitchd/bridge.c42
-rw-r--r--vswitchd/vswitch.ovsschema7
-rw-r--r--vswitchd/vswitch.xml69
3 files changed, 116 insertions, 2 deletions
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 6dcc2b878..f85f9b740 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -228,6 +228,7 @@ static void bridge_configure_mcast_snooping(struct bridge *);
static void bridge_configure_sflow(struct bridge *, int *sflow_bridge_number);
static void bridge_configure_ipfix(struct bridge *);
static void bridge_configure_stp(struct bridge *);
+static void bridge_configure_elephant(struct bridge *);
static void bridge_configure_tables(struct bridge *);
static void bridge_configure_dp_desc(struct bridge *);
static void bridge_configure_remotes(struct bridge *,
@@ -266,6 +267,8 @@ static void mirror_destroy(struct mirror *);
static bool mirror_configure(struct mirror *);
static void mirror_refresh_stats(struct mirror *);
+static void elephants_refresh_stats(struct bridge *);
+
static void iface_configure_lacp(struct iface *, struct lacp_slave_settings *);
static bool iface_create(struct bridge *, const struct ovsrec_interface *,
const struct ovsrec_port *);
@@ -378,6 +381,7 @@ bridge_init(const char *remote)
ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_datapath_id);
ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_status);
+ ovsdb_idl_omit_alert(idl, &ovsrec_bridge_col_elephant_flows);
ovsdb_idl_omit(idl, &ovsrec_bridge_col_external_ids);
ovsdb_idl_omit_alert(idl, &ovsrec_port_col_status);
@@ -622,6 +626,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
bridge_configure_sflow(br, &sflow_bridge_number);
bridge_configure_ipfix(br);
bridge_configure_stp(br);
+ bridge_configure_elephant(br);
bridge_configure_tables(br);
bridge_configure_dp_desc(br);
}
@@ -1383,6 +1388,29 @@ bridge_configure_stp(struct bridge *br)
}
}
+/* Set elephant flow detection configuration on 'br'. */
+static void
+bridge_configure_elephant(struct bridge *br)
+{
+ const char *config_str;
+ uint64_t mech, arg1, arg2;
+ int dscp;
+
+ config_str = smap_get(&br->cfg->other_config, "elephant-mech");
+ mech = config_str ? strtoul(config_str, NULL, 0) : 0;
+
+ config_str = smap_get(&br->cfg->other_config, "elephant-arg1");
+ arg1 = config_str ? strtoul(config_str, NULL, 0) : 0;
+
+ config_str = smap_get(&br->cfg->other_config, "elephant-arg2");
+ arg2 = config_str ? strtoul(config_str, NULL, 0) : 0;
+
+ config_str = smap_get(&br->cfg->other_config, "elephant-dscp");
+ dscp = config_str ? strtoul(config_str, NULL, 0) : -1;
+
+ ofproto_set_elephant(br->ofproto, mech, arg1, arg2, dscp);
+}
+
static bool
bridge_has_bond_fake_iface(const struct bridge *br, const char *name)
{
@@ -2459,6 +2487,8 @@ bridge_run(void)
mirror_refresh_stats(m);
}
+ /* xxx Find better place for this, but useful timer. */
+ elephants_refresh_stats(br);
}
refresh_controller_status();
ovsdb_idl_txn_commit(txn);
@@ -4337,3 +4367,15 @@ mirror_refresh_stats(struct mirror *m)
ovsrec_mirror_set_statistics(m->cfg, keys, values, stat_cnt);
}
+
+static void
+elephants_refresh_stats(struct bridge *br)
+{
+ struct smap elephants;
+
+ if (!ofproto_get_elephants(br->ofproto, &elephants)) {
+ ovsrec_bridge_set_elephant_flows(br->cfg, &elephants);
+ }
+
+ smap_destroy(&elephants);
+}
diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
index bc9ea73c6..717e61506 100644
--- a/vswitchd/vswitch.ovsschema
+++ b/vswitchd/vswitch.ovsschema
@@ -1,6 +1,6 @@
{"name": "Open_vSwitch",
- "version": "7.8.0",
- "cksum": "2676751133 20740",
+ "version": "7.78.0",
+ "cksum": "904547257 20882",
"tables": {
"Open_vSwitch": {
"columns": {
@@ -93,6 +93,9 @@
"type": {"key": {"type": "string",
"enum": ["set", ["standalone", "secure"]]},
"min": 0, "max": 1}},
+ "elephant_flows": {
+ "type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"},
+ "ephemeral": true},
"status": {
"type": {"key": "string", "value": "string", "min": 0, "max": "unlimited"},
"ephemeral": true},
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index d47fc1a6e..18cf7db35 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -480,6 +480,75 @@
</column>
</group>
+ <group title="Elephant Flow Detection">
+ <p>
+ The conventional wisdom is that majority of flows in the
+ datacenter are short (mice), yet the majority of packets belong to
+ a few long-lived flows (elephants). Mice are often associated
+ with bursty, latency sensitive apps whereas elephants tend to be
+ large transfers in which throughput is far more important than
+ latency.
+ </p>
+
+ <p>
+ Open vSwitch has the ability to distinguish elephant flows and
+ identify them through the database or mark them. Elephants are
+ identified by the combination of their duration and number of
+ bytes.
+ </p>
+
+ <column name="other_config" key="elephant-mech">
+ The mechanism used to detect elephants. It may be set to one of
+ the following:
+ <dl>
+ <dt><code>0</code></dt>
+ <dd>Disable elephant detection.</dd>
+
+ <dt><code>1</code></dt>
+ <dd>Bytes. A flow is declared an elephant based on a
+ threshold of the total number of bytes sent. <ref
+ column="other_config" key="elephant-arg1"/> specifies the
+ number of bytes. <ref column="other_config"
+ key="elephant-arg2"/> specifies the number of seconds that the
+ flow must exist before being declared an elephant; set to
+ <code>0</code> for immediate detection when the byte threshold
+ is crossed.</dd>
+
+ <dt><code>2</code></dt>
+ <dd>TSO. A flow is declared an elephant based on the segment
+ size. <ref column="other_config" key="elephant-arg1"/>
+ specifies the size of the segment. <ref column="other_config"
+ key="elephant-arg2"/> specifies the required number of
+ segments of the configured size that must be seen.
+ </dd>
+ </dl>
+ </column>
+
+ <column name="other_config" key="elephant-arg1">
+ First argument to elephant mechanism. The arguments are
+ described in <ref column="other_config" key="elephant-mech"/>.
+ </column>
+
+ <column name="other_config" key="elephant-arg2">
+ Second argument to elephant mechanism. The arguments are
+ described in <ref column="other_config" key="elephant-mech"/>.
+ </column>
+
+ <column name="other_config" key="elephant-dscp">
+ When an elephant flow is detected sets the DSCP value to use on
+ the wire for packets matching that flow. Not setting the key or
+ using a value of -1 will leave elephant flows unmarked.
+ </column>
+
+ <column name="elephant_flows">
+ <code>xxx Not currently supported xxx</code>
+ The <code>elephants</code> column contains key-value pairs that
+ report elephant flows. The key is a description of the flow,
+ and the value is size of the flow in bytes. These are updated
+ periodically (currently, every 5 seconds).
+ </column>
+ </group>
+
<group title="OpenFlow Configuration">
<column name="controller">
<p>