summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Zhou <azhou@nicira.com>2013-10-21 14:37:34 -0700
committerJesse Gross <jesse@nicira.com>2013-10-22 10:23:22 -0700
commit847108dc297d15becbde436174d1a4bb348e64d1 (patch)
tree9ef5acf252423fe43efa2ffa02ded2a49ee31446
parent4fa72a95722f74ebee61254f06bb171e9207f9c1 (diff)
downloadopenvswitch-847108dc297d15becbde436174d1a4bb348e64d1.tar.gz
dpif-linux: collect and display mega flow mask stats
Signed-off-by: Andy Zhou <azhou@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com> Signed-off-by: Jesse Gross <jesse@nicira.com>
-rw-r--r--NEWS2
-rw-r--r--lib/dpif-linux.c18
-rw-r--r--lib/dpif-netdev.c2
-rw-r--r--lib/dpif.h3
-rw-r--r--utilities/ovs-dpctl.8.in19
-rw-r--r--utilities/ovs-dpctl.c8
6 files changed, 51 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index f6e2dafdf..50f20ad28 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@ Post-v2.0.0
- ovs-vswitchd.conf.db.5 man page will contain graphviz/dot
diagram only if graphviz package was installed at the build time.
- Support for Linux kernels up to 3.11
+ - ovs-dpctl:
+ The "show" command also displays mega flow mask stats.
v2.0.0 - 15 Oct 2013
diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c
index 6f75f57e8..42958d3fc 100644
--- a/lib/dpif-linux.c
+++ b/lib/dpif-linux.c
@@ -74,6 +74,8 @@ struct dpif_linux_dp {
const char *name; /* OVS_DP_ATTR_NAME. */
const uint32_t *upcall_pid; /* OVS_DP_UPCALL_PID. */
struct ovs_dp_stats stats; /* OVS_DP_ATTR_STATS. */
+ struct ovs_dp_megaflow_stats megaflow_stats;
+ /* OVS_DP_ATTR_MEGAFLOW_STATS.*/
};
static void dpif_linux_dp_init(struct dpif_linux_dp *);
@@ -411,6 +413,8 @@ dpif_linux_get_stats(const struct dpif *dpif_, struct dpif_dp_stats *stats)
stats->n_missed = dp.stats.n_missed;
stats->n_lost = dp.stats.n_lost;
stats->n_flows = dp.stats.n_flows;
+ stats->n_masks = dp.megaflow_stats.n_masks;
+ stats->n_mask_hit = dp.megaflow_stats.n_mask_hit;
ofpbuf_delete(buf);
}
return error;
@@ -1770,6 +1774,9 @@ dpif_linux_dp_from_ofpbuf(struct dpif_linux_dp *dp, const struct ofpbuf *buf)
[OVS_DP_ATTR_NAME] = { .type = NL_A_STRING, .max_len = IFNAMSIZ },
[OVS_DP_ATTR_STATS] = { NL_POLICY_FOR(struct ovs_dp_stats),
.optional = true },
+ [OVS_DP_ATTR_MEGAFLOW_STATS] = {
+ NL_POLICY_FOR(struct ovs_dp_megaflow_stats),
+ .optional = true },
};
struct nlattr *a[ARRAY_SIZE(ovs_datapath_policy)];
@@ -1801,6 +1808,13 @@ dpif_linux_dp_from_ofpbuf(struct dpif_linux_dp *dp, const struct ofpbuf *buf)
sizeof dp->stats);
}
+ if (a[OVS_DP_ATTR_MEGAFLOW_STATS]) {
+ /* Can't use structure assignment because Netlink doesn't ensure
+ * sufficient alignment for 64-bit members. */
+ memcpy(&dp->megaflow_stats, nl_attr_get(a[OVS_DP_ATTR_MEGAFLOW_STATS]),
+ sizeof dp->megaflow_stats);
+ }
+
return 0;
}
@@ -1833,6 +1847,8 @@ static void
dpif_linux_dp_init(struct dpif_linux_dp *dp)
{
memset(dp, 0, sizeof *dp);
+ dp->megaflow_stats.n_masks = UINT32_MAX;
+ dp->megaflow_stats.n_mask_hit = UINT64_MAX;
}
static void
@@ -1871,11 +1887,11 @@ dpif_linux_dp_transact(const struct dpif_linux_dp *request,
ofpbuf_delete(request_buf);
if (reply) {
+ dpif_linux_dp_init(reply);
if (!error) {
error = dpif_linux_dp_from_ofpbuf(reply, *bufp);
}
if (error) {
- dpif_linux_dp_init(reply);
ofpbuf_delete(*bufp);
*bufp = NULL;
}
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 0f6a71c74..370691ebd 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -394,6 +394,8 @@ dpif_netdev_get_stats(const struct dpif *dpif, struct dpif_dp_stats *stats)
stats->n_hit = dp->n_hit;
stats->n_missed = dp->n_missed;
stats->n_lost = dp->n_lost;
+ stats->n_masks = UINT64_MAX;
+ stats->n_mask_hit = UINT64_MAX;
ovs_mutex_unlock(&dp_netdev_mutex);
return 0;
diff --git a/lib/dpif.h b/lib/dpif.h
index 8996c0a6a..ab69c1ce6 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -387,6 +387,9 @@ struct dpif_dp_stats {
uint64_t n_missed; /* Number of flow table misses. */
uint64_t n_lost; /* Number of misses not sent to userspace. */
uint64_t n_flows; /* Number of flows present. */
+ uint64_t n_masks; /* Number of mega flow masks. */
+ uint64_t n_mask_hit; /* Number of mega flow masks visited for
+ flow table matches. */
};
int dpif_get_dp_stats(const struct dpif *, struct dpif_dp_stats *);
diff --git a/utilities/ovs-dpctl.8.in b/utilities/ovs-dpctl.8.in
index 35d1be590..5a0dd7064 100644
--- a/utilities/ovs-dpctl.8.in
+++ b/utilities/ovs-dpctl.8.in
@@ -101,6 +101,25 @@ port is identified as port 0.) If \fB\-s\fR or \fB\-\-statistics\fR
is specified, then packet and byte counters are also printed for each
port.
.IP
+The datapath numbers consists of flow stats and mega flow mask stats.
+.IP
+The "lookups" row displays three stats related to flow lookup triggered
+by processing incoming packets in the datapath. "hit" displays number
+of packets matches existing flows. "missed" displays the number of
+packets not matching any existing flow and require user space processing.
+"lost" displays number of packets destined for user space process but
+subsequently dropped before reaching userspace. The sum of "hit" and "miss"
+equals to the total number of packets datapath processed.
+.IP
+The "flows" row displays the number of flows in datapath.
+.IP
+The "masks" row displays the mega flow mask stats. This row is omitted
+for datapath not implementing mega flow. "hit" displays the total number
+of masks visited for matching incoming packets. "total" displays number of
+masks in the datapath. "hit/pkt" displays the average number of masks
+visited per packet; the ratio between "hit" and total number of
+packets processed by the datapath".
+.IP
If one or more datapaths are specified, information on only those
datapaths are displayed. Otherwise, \fBovs\-dpctl\fR displays information
about all configured datapaths.
diff --git a/utilities/ovs-dpctl.c b/utilities/ovs-dpctl.c
index e11e102e3..78475e70c 100644
--- a/utilities/ovs-dpctl.c
+++ b/utilities/ovs-dpctl.c
@@ -563,7 +563,15 @@ show_dpif(struct dpif *dpif)
printf("\tlookups: hit:%"PRIu64" missed:%"PRIu64" lost:%"PRIu64"\n"
"\tflows: %"PRIu64"\n",
stats.n_hit, stats.n_missed, stats.n_lost, stats.n_flows);
+ if (stats.n_masks != UINT64_MAX) {
+ uint64_t n_pkts = stats.n_hit + stats.n_missed;
+ double avg = n_pkts ? (double) stats.n_mask_hit / n_pkts : 0.0;
+
+ printf("\tmasks: hit:%"PRIu64" total:%"PRIu64" hit/pkt:%.2f\n",
+ stats.n_mask_hit, stats.n_masks, avg);
+ }
}
+
DPIF_PORT_FOR_EACH (&dpif_port, &dump, dpif) {
printf("\tport %u: %s", dpif_port.port_no, dpif_port.name);