Oops, this patch ends up deleteing, xlate_actions_for_side_effects(), but then I need it again in the xlate series. I think instead of basing this on master, I'll base it on the xlate series once it's merged. May as well hold off reviewing it until then.
Ethan On Wed, May 29, 2013 at 2:38 PM, Ethan Jackson <et...@nicira.com> wrote: > The logic for updating statistics at the facet level had been > spread through ofproto-dpif in a rather confusing manner. This > patch consolidates as much of this logic as is reasonable into > facet_push_stats(). > > On a side note, I'd expect this patch to have a marginal positive > performance impact when using learning (though I haven't bothered > to measure it). It combines facet_learn() and facet_push_stats() > into one step allowing us to avoid a redundant xlate_actions(). > > Signed-off-by: Ethan Jackson <et...@nicira.com> > --- > ofproto/ofproto-dpif.c | 148 > ++++++++++++++++-------------------------------- > 1 file changed, 50 insertions(+), 98 deletions(-) > > diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c > index ae59eda..881b29f 100644 > --- a/ofproto/ofproto-dpif.c > +++ b/ofproto/ofproto-dpif.c > @@ -121,7 +121,6 @@ static struct rule_dpif *rule_dpif_miss_rule(struct > ofproto_dpif *ofproto, > > static void rule_credit_stats(struct rule_dpif *, > const struct dpif_flow_stats *); > -static void flow_push_stats(struct facet *, const struct dpif_flow_stats *); > static tag_type rule_calculate_tag(const struct flow *, > const struct minimask *, uint32_t basis); > static void rule_invalidate(const struct rule_dpif *); > @@ -325,9 +324,6 @@ static void action_xlate_ctx_init(struct action_xlate_ctx > *, > static void xlate_actions(struct action_xlate_ctx *, > const struct ofpact *ofpacts, size_t ofpacts_len, > struct ofpbuf *odp_actions); > -static void xlate_actions_for_side_effects(struct action_xlate_ctx *, > - const struct ofpact *ofpacts, > - size_t ofpacts_len); > static void xlate_table_action(struct action_xlate_ctx *, uint16_t in_port, > uint8_t table_id, bool may_packet_in); > > @@ -419,7 +415,6 @@ static void subfacet_destroy_batch(struct ofproto_dpif *, > struct subfacet **, int n); > static void subfacet_reset_dp_stats(struct subfacet *, > struct dpif_flow_stats *); > -static void subfacet_update_time(struct subfacet *, long long int used); > static void subfacet_update_stats(struct subfacet *, > const struct dpif_flow_stats *); > static void subfacet_make_actions(struct subfacet *, > @@ -520,9 +515,8 @@ static bool facet_check_consistency(struct facet *); > > static void facet_flush_stats(struct facet *); > > -static void facet_update_time(struct facet *, long long int used); > static void facet_reset_counters(struct facet *); > -static void facet_push_stats(struct facet *); > +static void facet_push_stats(struct facet *, bool may_learn); > static void facet_learn(struct facet *); > static void facet_account(struct facet *); > static void push_all_stats(void); > @@ -4331,26 +4325,29 @@ update_subfacet_stats(struct subfacet *subfacet, > const struct dpif_flow_stats *stats) > { > struct facet *facet = subfacet->facet; > + struct dpif_flow_stats diff; > + > + diff.tcp_flags = stats->tcp_flags; > + diff.used = stats->used; > > if (stats->n_packets >= subfacet->dp_packet_count) { > - uint64_t extra = stats->n_packets - subfacet->dp_packet_count; > - facet->packet_count += extra; > + diff.n_packets = stats->n_packets - subfacet->dp_packet_count; > } else { > VLOG_WARN_RL(&rl, "unexpected packet count from the datapath"); > + diff.n_packets = 0; > } > > if (stats->n_bytes >= subfacet->dp_byte_count) { > - facet->byte_count += stats->n_bytes - subfacet->dp_byte_count; > + diff.n_bytes = stats->n_bytes - subfacet->dp_byte_count; > } else { > VLOG_WARN_RL(&rl, "unexpected byte count from datapath"); > + diff.n_bytes = 0; > } > > subfacet->dp_packet_count = stats->n_packets; > subfacet->dp_byte_count = stats->n_bytes; > + subfacet_update_stats(subfacet, &diff); > > - facet->tcp_flags |= stats->tcp_flags; > - > - subfacet_update_time(subfacet, stats->used); > if (facet->accounted_bytes < facet->byte_count) { > facet_learn(facet); > facet_account(facet); > @@ -4406,7 +4403,6 @@ update_stats(struct dpif_backer *backer) > while (dpif_flow_dump_next(&dump, &key, &key_len, NULL, NULL, &stats)) { > struct flow flow; > struct subfacet *subfacet; > - struct ofport_dpif *ofport; > uint32_t key_hash; > > if (ofproto_receive(backer, NULL, key, key_len, &flow, NULL, > &ofproto, > @@ -4417,11 +4413,6 @@ update_stats(struct dpif_backer *backer) > ofproto->total_subfacet_count += hmap_count(&ofproto->subfacets); > ofproto->n_update_stats++; > > - ofport = get_ofp_port(ofproto, flow.in_port); > - if (ofport && ofport->tnl_port) { > - netdev_vport_inc_rx(ofport->up.netdev, stats); > - } > - > key_hash = odp_flow_key_hash(key, key_len); > subfacet = subfacet_find(ofproto, key, key_len, key_hash); > switch (subfacet ? subfacet->path : SF_NOT_INSTALLED) { > @@ -4721,11 +4712,7 @@ facet_remove(struct facet *facet) > static void > facet_learn(struct facet *facet) > { > - struct ofproto_dpif *ofproto = > ofproto_dpif_cast(facet->rule->up.ofproto); > - struct subfacet *subfacet= CONTAINER_OF(list_front(&facet->subfacets), > - struct subfacet, list_node); > long long int now = time_msec(); > - struct action_xlate_ctx ctx; > > if (!facet->has_fin_timeout && now < facet->learn_rl) { > return; > @@ -4740,12 +4727,7 @@ facet_learn(struct facet *facet) > return; > } > > - action_xlate_ctx_init(&ctx, ofproto, &facet->flow, > - &subfacet->initial_vals, > - facet->rule, facet->tcp_flags, NULL); > - ctx.may_learn = true; > - xlate_actions_for_side_effects(&ctx, facet->rule->up.ofpacts, > - facet->rule->up.ofpacts_len); > + facet_push_stats(facet, true); > } > > static void > @@ -4833,7 +4815,7 @@ facet_flush_stats(struct facet *facet) > ovs_assert(!subfacet->dp_packet_count); > } > > - facet_push_stats(facet); > + facet_push_stats(facet, false); > if (facet->accounted_bytes < facet->byte_count) { > facet_account(facet); > facet->accounted_bytes = facet->byte_count; > @@ -5187,19 +5169,6 @@ facet_revalidate(struct facet *facet) > } > } > > -/* Updates 'facet''s used time. Caller is responsible for calling > - * facet_push_stats() to update the flows which 'facet' resubmits into. */ > -static void > -facet_update_time(struct facet *facet, long long int used) > -{ > - struct ofproto_dpif *ofproto = > ofproto_dpif_cast(facet->rule->up.ofproto); > - if (used > facet->used) { > - facet->used = used; > - ofproto_rule_update_used(&facet->rule->up, used); > - netflow_flow_update_time(ofproto->netflow, &facet->nf_flow, used); > - } > -} > - > static void > facet_reset_counters(struct facet *facet) > { > @@ -5211,7 +5180,7 @@ facet_reset_counters(struct facet *facet) > } > > static void > -facet_push_stats(struct facet *facet) > +facet_push_stats(struct facet *facet, bool may_learn) > { > struct dpif_flow_stats stats; > > @@ -5222,18 +5191,45 @@ facet_push_stats(struct facet *facet) > stats.n_packets = facet->packet_count - facet->prev_packet_count; > stats.n_bytes = facet->byte_count - facet->prev_byte_count; > stats.used = facet->used; > - stats.tcp_flags = 0; > + stats.tcp_flags = facet->tcp_flags; > + > + if (may_learn || stats.n_packets || stats.n_bytes > + || facet->used > facet->prev_used) { > + struct subfacet *subfacet = facet_get_subfacet(facet); > + struct ofproto_dpif *ofproto = > + ofproto_dpif_cast(facet->rule->up.ofproto); > + > + uint64_t odp_actions_stub[1024 / 8]; > + struct ofpbuf odp_actions; > + struct ofport_dpif *in_port; > + struct action_xlate_ctx ctx; > > - if (stats.n_packets || stats.n_bytes || facet->used > facet->prev_used) { > facet->prev_packet_count = facet->packet_count; > facet->prev_byte_count = facet->byte_count; > facet->prev_used = facet->used; > > - rule_credit_stats(facet->rule, &stats); > - flow_push_stats(facet, &stats); > + in_port = get_ofp_port(ofproto, facet->flow.in_port); > + if (in_port && in_port->tnl_port) { > + netdev_vport_inc_rx(in_port->up.netdev, &stats); > + } > > - update_mirror_stats(ofproto_dpif_cast(facet->rule->up.ofproto), > - facet->mirrors, stats.n_packets, stats.n_bytes); > + rule_credit_stats(facet->rule, &stats); > + netflow_flow_update_time(ofproto->netflow, &facet->nf_flow, > + facet->used); > + netflow_flow_update_flags(&facet->nf_flow, facet->tcp_flags); > + update_mirror_stats(ofproto, facet->mirrors, stats.n_packets, > + stats.n_bytes); > + > + ofpbuf_use_stub(&odp_actions, odp_actions_stub, > + sizeof odp_actions_stub); > + action_xlate_ctx_init(&ctx, ofproto, &facet->flow, > + &subfacet->initial_vals, facet->rule, > + stats.tcp_flags, NULL); > + ctx.resubmit_stats = &stats; > + ctx.may_learn = may_learn; > + xlate_actions(&ctx, facet->rule->up.ofpacts, > + facet->rule->up.ofpacts_len, &odp_actions); > + ofpbuf_uninit(&odp_actions); > } > } > > @@ -5251,7 +5247,7 @@ push_all_stats__(bool run_fast) > struct facet *facet; > > HMAP_FOR_EACH (facet, hmap_node, &ofproto->facets) { > - facet_push_stats(facet); > + facet_push_stats(facet, false); > if (run_fast) { > run_fast_rl(); > } > @@ -5274,25 +5270,6 @@ rule_credit_stats(struct rule_dpif *rule, const struct > dpif_flow_stats *stats) > rule->byte_count += stats->n_bytes; > ofproto_rule_update_used(&rule->up, stats->used); > } > - > -/* Pushes flow statistics to the rules which 'facet->flow' resubmits > - * into given 'facet->rule''s actions and mirrors. */ > -static void > -flow_push_stats(struct facet *facet, const struct dpif_flow_stats *stats) > -{ > - struct rule_dpif *rule = facet->rule; > - struct ofproto_dpif *ofproto = ofproto_dpif_cast(rule->up.ofproto); > - struct subfacet *subfacet = facet_get_subfacet(facet); > - struct action_xlate_ctx ctx; > - > - ofproto_rule_update_used(&rule->up, stats->used); > - > - action_xlate_ctx_init(&ctx, ofproto, &facet->flow, > - &subfacet->initial_vals, rule, 0, NULL); > - ctx.resubmit_stats = stats; > - xlate_actions_for_side_effects(&ctx, rule->up.ofpacts, > - rule->up.ofpacts_len); > -} > > /* Subfacets. */ > > @@ -5562,23 +5539,13 @@ subfacet_reset_dp_stats(struct subfacet *subfacet, > subfacet->dp_byte_count = 0; > } > > -/* Updates 'subfacet''s used time. The caller is responsible for calling > - * facet_push_stats() to update the flows which 'subfacet' resubmits into. */ > -static void > -subfacet_update_time(struct subfacet *subfacet, long long int used) > -{ > - if (used > subfacet->used) { > - subfacet->used = used; > - facet_update_time(subfacet->facet, used); > - } > -} > - > /* Folds the statistics from 'stats' into the counters in 'subfacet'. > * > * Because of the meaning of a subfacet's counters, it only makes sense to do > * this if 'stats' are not tracked in the datapath, that is, if 'stats' > * represents a packet that was sent by hand or if it represents statistics > * that have been cleared out of the datapath. */ > +/* TODO does this function have the right name? */ > static void > subfacet_update_stats(struct subfacet *subfacet, > const struct dpif_flow_stats *stats) > @@ -5586,11 +5553,11 @@ subfacet_update_stats(struct subfacet *subfacet, > if (stats->n_packets || stats->used > subfacet->used) { > struct facet *facet = subfacet->facet; > > - subfacet_update_time(subfacet, stats->used); > + subfacet->used = MAX(subfacet->used, stats->used); > + facet->used = MAX(facet->used, stats->used); > facet->packet_count += stats->n_packets; > facet->byte_count += stats->n_bytes; > facet->tcp_flags |= stats->tcp_flags; > - netflow_flow_update_flags(&facet->nf_flow, stats->tcp_flags); > } > } > > @@ -7185,21 +7152,6 @@ xlate_actions(struct action_xlate_ctx *ctx, > ofpbuf_uninit(&ctx->stack); > } > > -/* Translates the 'ofpacts_len' bytes of "struct ofpact"s starting at > 'ofpacts' > - * into datapath actions, using 'ctx', and discards the datapath actions. */ > -static void > -xlate_actions_for_side_effects(struct action_xlate_ctx *ctx, > - const struct ofpact *ofpacts, > - size_t ofpacts_len) > -{ > - uint64_t odp_actions_stub[1024 / 8]; > - struct ofpbuf odp_actions; > - > - ofpbuf_use_stub(&odp_actions, odp_actions_stub, sizeof odp_actions_stub); > - xlate_actions(ctx, ofpacts, ofpacts_len, &odp_actions); > - ofpbuf_uninit(&odp_actions); > -} > - > static void > xlate_report(struct action_xlate_ctx *ctx, const char *s) > { > -- > 1.7.9.5 > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev