aboutsummaryrefslogtreecommitdiff
path: root/ofproto
diff options
context:
space:
mode:
authorAndy Zhou <azhou@nicira.com>2013-03-12 14:19:18 -0700
committerBen Pfaff <blp@nicira.com>2013-04-01 13:30:57 -0700
commitc2c5cca2aff3d4324a3d84b24107675b9be6301d (patch)
tree3575a273e488d8b417869ccbc74dee8502494450 /ofproto
parent37419873b42963ff9da99b7f47cbde39f20f6184 (diff)
ovs-appctl: dpif/show display per bridge stats
This is to fix the fallout of single datapath change. ovs-appctl dpif/show displays per bridge miss, hit and flow counts on the screen, but the backend is obtaining those information from the datapath. With a single datapath, all bridges of the same datapath would all display the same (global) counters maintained by the datapath, obviously not correct. This patch fixes the bug by maintaining per ofproto_dpif miss and hit counts, which are used for display output. The number of flows count is obtained by counting the number facets per ofproto. ovs-dpctl show still displays the counters maintain by the datapath, as before. Bug #15369 Signed-off-by: Andy Zhou <azhou@nicira.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'ofproto')
-rw-r--r--ofproto/ofproto-dpif.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 62c7f316..df18244f 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -661,6 +661,9 @@ static void drop_key_clear(struct dpif_backer *);
static struct ofport_dpif *
odp_port_to_ofport(const struct dpif_backer *, uint32_t odp_port);
+static void dpif_stats_update_hit_count(struct ofproto_dpif *ofproto,
+ uint64_t delta);
+
struct ofproto_dpif {
struct hmap_node all_ofproto_dpifs_node; /* In 'all_ofproto_dpifs'. */
struct ofproto up;
@@ -711,6 +714,10 @@ struct ofproto_dpif {
struct sset ghost_ports; /* Ports with no datapath port. */
struct sset port_poll_set; /* Queued names for port_poll() reply. */
int port_poll_errno; /* Last errno for port_poll() reply. */
+
+ /* Per ofproto's dpif stats. */
+ uint64_t n_hit;
+ uint64_t n_missed;
};
/* Defer flow mod completion until "ovs-appctl ofproto/unclog"? (Useful only
@@ -1289,6 +1296,9 @@ construct(struct ofproto *ofproto_)
error = add_internal_flows(ofproto);
ofproto->up.tables[TBL_INTERNAL].flags = OFTABLE_HIDDEN | OFTABLE_READONLY;
+ ofproto->n_hit = 0;
+ ofproto->n_missed = 0;
+
return error;
}
@@ -3847,6 +3857,8 @@ handle_miss_upcalls(struct dpif_backer *backer, struct dpif_upcall *upcalls,
if (error) {
continue;
}
+
+ ofproto->n_missed++;
flow_extract(upcall->packet, flow.skb_priority, flow.skb_mark,
&flow.tunnel, flow.in_port, &miss->flow);
@@ -4124,6 +4136,11 @@ delete_unexpected_flow(struct ofproto_dpif *ofproto,
* avoided by calling update_stats() whenever rules are created or
* deleted. However, the performance impact of making so many calls to the
* datapath do not justify the benefit of having perfectly accurate statistics.
+ *
+ * In addition, this function maintains per ofproto flow hit counts. The patch
+ * port is not treated specially. e.g. A packet ingress from br0 patched into
+ * br1 will increase the hit count of br0 by 1, however, does not affect
+ * the hit or miss counts of br1.
*/
static void
update_stats(struct dpif_backer *backer)
@@ -4155,6 +4172,12 @@ update_stats(struct dpif_backer *backer)
subfacet = subfacet_find(ofproto, key, key_len, key_hash);
switch (subfacet ? subfacet->path : SF_NOT_INSTALLED) {
case SF_FAST_PATH:
+ /* Update ofproto_dpif's hit count. */
+ if (stats->n_packets > subfacet->dp_packet_count) {
+ uint64_t delta = stats->n_packets - subfacet->dp_packet_count;
+ dpif_stats_update_hit_count(ofproto, delta);
+ }
+
update_subfacet_stats(subfacet, stats);
break;
@@ -7942,19 +7965,14 @@ ofproto_unixctl_dpif_dump_dps(struct unixctl_conn *conn, int argc OVS_UNUSED,
static void
show_dp_format(const struct ofproto_dpif *ofproto, struct ds *ds)
{
- struct dpif_dp_stats s;
const struct shash_node **ports;
int i;
- dpif_get_dp_stats(ofproto->backer->dpif, &s);
-
ds_put_format(ds, "%s (%s):\n", ofproto->up.name,
dpif_name(ofproto->backer->dpif));
- /* xxx It would be better to show bridge-specific stats instead
- * xxx of dp ones. */
ds_put_format(ds,
- "\tlookups: hit:%"PRIu64" missed:%"PRIu64" lost:%"PRIu64"\n",
- s.n_hit, s.n_missed, s.n_lost);
+ "\tlookups: hit:%"PRIu64" missed:%"PRIu64"\n",
+ ofproto->n_hit, ofproto->n_missed);
ds_put_format(ds, "\tflows: %zu\n",
hmap_count(&ofproto->subfacets));
@@ -8374,6 +8392,12 @@ odp_port_to_ofp_port(const struct ofproto_dpif *ofproto, uint32_t odp_port)
}
}
+static void
+dpif_stats_update_hit_count(struct ofproto_dpif *ofproto, uint64_t delta)
+{
+ ofproto->n_hit += delta;
+}
+
const struct ofproto_class ofproto_dpif_class = {
init,
enumerate_types,