The subfacet rates (e.g. add rate, del rate) were computed by exponential moving averaging function in ofproto-dpif.c. This patch replaces that logic with coverage counters. And the rates can be checked by running "ovs-appctl coverage/show" command.
Signed-off-by: Alex Wang <al...@nicira.com> --- ofproto/ofproto-dpif.c | 90 +++++++----------------------------------------- ofproto/ofproto-dpif.h | 19 ---------- tests/ofproto-dpif.at | 4 --- tests/tunnel.at | 26 +++++++------- 4 files changed, 26 insertions(+), 113 deletions(-) diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 3bc8dd7..0c20ac6 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -69,6 +69,11 @@ COVERAGE_DEFINE(facet_changed_rule); COVERAGE_DEFINE(facet_revalidate); COVERAGE_DEFINE(facet_unexpected); COVERAGE_DEFINE(facet_suppress); +COVERAGE_DEFINE(facet_create); +COVERAGE_DEFINE(facet_remove); +COVERAGE_DEFINE(handle_flow_miss); +COVERAGE_DEFINE(subfacet_create); +COVERAGE_DEFINE(subfacet_destroy); struct flow_miss; struct facet; @@ -319,7 +324,6 @@ static struct shash all_dpif_backers = SHASH_INITIALIZER(&all_dpif_backers); 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 update_moving_averages(struct dpif_backer *backer); /* Defer flow mod completion until "ovs-appctl ofproto/unclog"? (Useful only * for debugging the asynchronous flow_mod implementation.) */ @@ -906,14 +910,6 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp) backer->max_n_subfacet = 0; backer->created = time_msec(); - backer->last_minute = backer->created; - memset(&backer->hourly, 0, sizeof backer->hourly); - memset(&backer->daily, 0, sizeof backer->daily); - memset(&backer->lifetime, 0, sizeof backer->lifetime); - backer->subfacet_add_count = 0; - backer->subfacet_del_count = 0; - backer->total_subfacet_add_count = 0; - backer->total_subfacet_del_count = 0; backer->avg_n_subfacet = 0; backer->avg_subfacet_life = 0; @@ -3385,6 +3381,8 @@ handle_flow_miss(struct flow_miss *miss, struct flow_miss_op *ops, struct facet *facet; long long int now; + COVERAGE_INC(handle_flow_miss); + now = time_msec(); memset(stats, 0, sizeof *stats); stats->used = now; @@ -4039,8 +4037,6 @@ update_stats(struct dpif_backer *backer) run_fast_rl(); } dpif_flow_dump_done(&dump); - - update_moving_averages(backer); } /* Calculates and returns the number of milliseconds of idle time after which @@ -4231,6 +4227,8 @@ facet_create(const struct flow_miss *miss, struct rule_dpif *rule, struct facet *facet; struct match match; + COVERAGE_INC(facet_create); + facet = xzalloc(sizeof *facet); facet->packet_count = facet->prev_packet_count = stats->n_packets; facet->byte_count = facet->prev_byte_count = stats->n_bytes; @@ -4298,6 +4296,7 @@ facet_remove(struct facet *facet) struct ofproto_dpif *ofproto = ofproto_dpif_cast(facet->rule->up.ofproto); struct subfacet *subfacet, *next_subfacet; + COVERAGE_INC(facet_remove); ovs_assert(!list_is_empty(&facet->subfacets)); /* First uninstall all of the subfacets to get final statistics. */ @@ -4812,6 +4811,8 @@ subfacet_create(struct facet *facet, struct flow_miss *miss, subfacet = xmalloc(sizeof *subfacet); } + COVERAGE_INC(subfacet_create); + hmap_insert(&backer->subfacets, &subfacet->hmap_node, key_hash); list_push_back(&facet->subfacets, &subfacet->list_node); subfacet->facet = facet; @@ -4825,7 +4826,6 @@ subfacet_create(struct facet *facet, struct flow_miss *miss, subfacet->path = SF_NOT_INSTALLED; subfacet->backer = backer; - backer->subfacet_add_count++; return subfacet; } @@ -4835,10 +4835,9 @@ static void subfacet_destroy__(struct subfacet *subfacet) { struct facet *facet = subfacet->facet; - struct ofproto_dpif *ofproto = ofproto_dpif_cast(facet->rule->up.ofproto); /* Update ofproto stats before uninstall the subfacet. */ - ofproto->backer->subfacet_del_count++; + COVERAGE_INC(subfacet_destroy); subfacet_uninstall(subfacet); hmap_remove(&subfacet->backer->subfacets, &subfacet->hmap_node); @@ -6032,21 +6031,12 @@ ofproto_unixctl_dpif_dump_dps(struct unixctl_conn *conn, int argc OVS_UNUSED, } static void -show_dp_rates(struct ds *ds, const char *heading, - const struct avg_subfacet_rates *rates) -{ - ds_put_format(ds, "%s add rate: %5.3f/min, del rate: %5.3f/min\n", - heading, rates->add_rate, rates->del_rate); -} - -static void dpif_show_backer(const struct dpif_backer *backer, struct ds *ds) { const struct shash_node **ofprotos; struct ofproto_dpif *ofproto; struct shash ofproto_shash; uint64_t n_hit, n_missed; - long long int minutes; size_t i; n_hit = n_missed = 0; @@ -6064,15 +6054,6 @@ dpif_show_backer(const struct dpif_backer *backer, struct ds *ds) backer->avg_n_subfacet, backer->max_n_subfacet, backer->avg_subfacet_life); - minutes = (time_msec() - backer->created) / (1000 * 60); - if (minutes >= 60) { - show_dp_rates(ds, "\thourly avg:", &backer->hourly); - } - if (minutes >= 60 * 24) { - show_dp_rates(ds, "\tdaily avg:", &backer->daily); - } - show_dp_rates(ds, "\toverall avg:", &backer->lifetime); - shash_init(&ofproto_shash); ofprotos = get_ofprotos(&ofproto_shash); for (i = 0; i < shash_count(&ofproto_shash); i++) { @@ -6534,51 +6515,6 @@ odp_port_to_ofp_port(const struct ofproto_dpif *ofproto, uint32_t odp_port) } } -/* Compute exponentially weighted moving average, adding 'new' as the newest, - * most heavily weighted element. 'base' designates the rate of decay: after - * 'base' further updates, 'new''s weight in the EWMA decays to about 1/e - * (about .37). */ -static void -exp_mavg(double *avg, int base, double new) -{ - *avg = (*avg * (base - 1) + new) / base; -} - -static void -update_moving_averages(struct dpif_backer *backer) -{ - const int min_ms = 60 * 1000; /* milliseconds in one minute. */ - long long int minutes = (time_msec() - backer->created) / min_ms; - - if (minutes > 0) { - backer->lifetime.add_rate = (double) backer->total_subfacet_add_count - / minutes; - backer->lifetime.del_rate = (double) backer->total_subfacet_del_count - / minutes; - } else { - backer->lifetime.add_rate = 0.0; - backer->lifetime.del_rate = 0.0; - } - - /* Update hourly averages on the minute boundaries. */ - if (time_msec() - backer->last_minute >= min_ms) { - exp_mavg(&backer->hourly.add_rate, 60, backer->subfacet_add_count); - exp_mavg(&backer->hourly.del_rate, 60, backer->subfacet_del_count); - - /* Update daily averages on the hour boundaries. */ - if ((backer->last_minute - backer->created) / min_ms % 60 == 59) { - exp_mavg(&backer->daily.add_rate, 24, backer->hourly.add_rate); - exp_mavg(&backer->daily.del_rate, 24, backer->hourly.del_rate); - } - - backer->total_subfacet_add_count += backer->subfacet_add_count; - backer->total_subfacet_del_count += backer->subfacet_del_count; - backer->subfacet_add_count = 0; - backer->subfacet_del_count = 0; - backer->last_minute += min_ms; - } -} - const struct ofproto_class ofproto_dpif_class = { init, enumerate_types, diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index 0c3252c..af82496 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -75,11 +75,6 @@ struct rule_dpif { struct list facets; /* List of "struct facet"s. */ }; -struct avg_subfacet_rates { - double add_rate; /* Moving average of new flows created per minute. */ - double del_rate; /* Moving average of flows deleted per minute. */ -}; - /* All datapaths of a given type share a single dpif backer instance. */ struct dpif_backer { char *type; @@ -111,20 +106,6 @@ struct dpif_backer { unsigned max_n_subfacet; /* Maximum number of flows */ unsigned avg_n_subfacet; /* Average number of flows. */ long long int avg_subfacet_life; /* Average life span of subfacets. */ - - /* The average number of subfacets... */ - struct avg_subfacet_rates hourly; /* ...over the last hour. */ - struct avg_subfacet_rates daily; /* ...over the last day. */ - struct avg_subfacet_rates lifetime; /* ...over the switch lifetime. */ - long long int last_minute; /* Last time 'hourly' was updated. */ - - /* Number of subfacets added or deleted since 'last_minute'. */ - unsigned subfacet_add_count; - unsigned subfacet_del_count; - - /* Number of subfacets added or deleted from 'created' to 'last_minute.' */ - unsigned long long int total_subfacet_add_count; - unsigned long long int total_subfacet_del_count; }; /* Extra information about a classifier table. diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index e8458d0..9231221 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -2031,7 +2031,6 @@ ADD_OF_PORTS([br1], [3]) AT_CHECK([ovs-appctl dpif/show], [0], [dnl dummy@ovs-dummy: hit:0 missed:0 flows: cur: 0, avg: 0, max: 0, life span: 0ms - overall avg: add rate: 0.000/min, del rate: 0.000/min br0: hit:0 missed:0 br0 65534/100: (dummy) p1 1/1: (dummy) @@ -2124,7 +2123,6 @@ warped AT_CHECK([ovs-appctl dpif/show], [0], [dnl dummy@ovs-dummy: hit:13 missed:2 flows: cur: 2, avg: 1, max: 2, life span: 1250ms - overall avg: add rate: 0.000/min, del rate: 0.000/min br0: hit:9 missed:1 br0 65534/100: (dummy) p2 2/2: (dummy) @@ -2176,8 +2174,6 @@ AT_CHECK([ovs-appctl time/warp 10000], [0], [warped AT_CHECK([ovs-appctl dpif/show | sed 's/ 10[[0-9]]\{3\}(ms)$/ 10000(ms)/'], [0], [dnl dummy@ovs-dummy: hit:0 missed:61 flows: cur: 0, avg: 0, max: 1, life span: 1666ms - hourly avg: add rate: 0.641/min, del rate: 0.641/min - overall avg: add rate: 1.000/min, del rate: 1.000/min br0: hit:0 missed:61 br0 65534/100: (dummy) p1 1/1: (dummy) diff --git a/tests/tunnel.at b/tests/tunnel.at index 697c217..982d22a 100644 --- a/tests/tunnel.at +++ b/tests/tunnel.at @@ -14,7 +14,7 @@ actions=IN_PORT AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/1: (gre: remote_ip=1.1.1.1) p2 2/1: (gre: local_ip=2.2.2.2, remote_ip=1.1.1.1) @@ -37,7 +37,7 @@ dnl reconfigure, local_ip, remote_ip AT_CHECK([ovs-vsctl set Interface p2 type=gre options:local_ip=2.2.2.3 \ options:df_default=false options:ttl=1 options:csum=true \ -- set Interface p3 type=gre64]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/1: (gre: remote_ip=1.1.1.1) p2 2/1: (gre: csum=true, df_default=false, local_ip=2.2.2.3, remote_ip=1.1.1.1, ttl=1) @@ -72,7 +72,7 @@ actions=2 AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/1: (gre: remote_ip=1.1.1.1) p2 2/2: (dummy) @@ -116,7 +116,7 @@ actions=output:1 AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/1: (gre: key=5, local_ip=2.2.2.2, remote_ip=1.1.1.1) p2 2/2: (dummy) @@ -148,7 +148,7 @@ actions=output:1 AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/1: (gre: remote_ip=1.1.1.1, tos=inherit, ttl=inherit) p2 2/2: (dummy) @@ -190,7 +190,7 @@ actions=set_tunnel:1,output:1,set_tunnel:2,output:2,set_tunnel:3,output:3,set_tu AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/1: (gre: key=flow, remote_ip=1.1.1.1) p2 2/1: (gre: key=flow, remote_ip=2.2.2.2) @@ -222,7 +222,7 @@ actions=IN_PORT,output:1,output:2,output:3 AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/1: (gre: key=1, remote_ip=1.1.1.1) p2 2/1: (gre: in_key=2, out_key=3, remote_ip=1.1.1.1) @@ -274,7 +274,7 @@ tun_id=4,actions=output:5 AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/1: (gre: key=flow, remote_ip=1.1.1.1) p2 2/1: (gre: key=3, remote_ip=3.3.3.3) @@ -310,7 +310,7 @@ AT_SETUP([tunnel - VXLAN]) OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=vxlan \ options:remote_ip=1.1.1.1 ofport_request=1]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/1: (vxlan: remote_ip=1.1.1.1) ]) @@ -322,7 +322,7 @@ AT_SETUP([tunnel - LISP]) OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=lisp \ options:remote_ip=1.1.1.1 ofport_request=1]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/1: (lisp: remote_ip=1.1.1.1) ]) @@ -334,7 +334,7 @@ AT_SETUP([tunnel - different VXLAN UDP port]) OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=vxlan \ options:remote_ip=1.1.1.1 ofport_request=1 options:dst_port=4341]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/1: (vxlan: dst_port=4341, remote_ip=1.1.1.1) ]) @@ -343,7 +343,7 @@ dnl change UDP port AT_CHECK([ovs-vsctl -- set Interface p1 options:dst_port=5000]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/2: (vxlan: dst_port=5000, remote_ip=1.1.1.1) ]) @@ -352,7 +352,7 @@ dnl change UDP port to default AT_CHECK([ovs-vsctl -- set Interface p1 options:dst_port=4789]) -AT_CHECK([ovs-appctl dpif/show | tail -n +5], [0], [dnl +AT_CHECK([ovs-appctl dpif/show | tail -n +4], [0], [dnl br0 65534/100: (dummy) p1 1/1: (vxlan: remote_ip=1.1.1.1) ]) -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev