Btw, this version is based on master, and is ready for review.

Thanks,
Ethan

On Wed, May 29, 2013 at 5:43 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 |  114 
> +++++++++++++++++-------------------------------
>  1 file changed, 40 insertions(+), 74 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 386434d..40be3c8 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 *);
> @@ -420,7 +419,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 int subfacet_install(struct subfacet *,
> @@ -508,9 +506,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);
> @@ -4312,26 +4309,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);
> @@ -4387,7 +4387,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,
> @@ -4398,11 +4397,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) {
> @@ -4713,9 +4707,7 @@ facet_remove(struct facet *facet)
>  static void
>  facet_learn(struct facet *facet)
>  {
> -    struct ofproto_dpif *ofproto = 
> ofproto_dpif_cast(facet->rule->up.ofproto);
>      long long int now = time_msec();
> -    struct xlate_in xin;
>
>      if (!facet->xout.has_fin_timeout && now < facet->learn_rl) {
>          return;
> @@ -4730,10 +4722,7 @@ facet_learn(struct facet *facet)
>          return;
>      }
>
> -    xlate_in_init(&xin, ofproto, &facet->flow, &facet->initial_vals,
> -                  facet->rule, facet->tcp_flags, NULL);
> -    xin.may_learn = true;
> -    xlate_actions_for_side_effects(&xin);
> +    facet_push_stats(facet, true);
>  }
>
>  static void
> @@ -4820,7 +4809,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;
> @@ -5061,19 +5050,6 @@ facet_revalidate(struct facet *facet)
>      return true;
>  }
>
> -/* 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)
>  {
> @@ -5085,7 +5061,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;
>
> @@ -5096,19 +5072,37 @@ 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 ofproto_dpif *ofproto =
> +            ofproto_dpif_cast(facet->rule->up.ofproto);
> +
> +        struct ofport_dpif *in_port;
> +        struct xlate_in xin;
>
> -    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->xout.mirrors, stats.n_packets,
> +        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->xout.mirrors, stats.n_packets,
>                              stats.n_bytes);
> +
> +        xlate_in_init(&xin, ofproto, &facet->flow, &facet->initial_vals,
> +                      facet->rule, stats.tcp_flags, NULL);
> +        xin.resubmit_stats = &stats;
> +        xin.may_learn = may_learn;
> +        xlate_actions_for_side_effects(&xin);
>      }
>  }
>
> @@ -5126,7 +5120,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();
>              }
> @@ -5149,23 +5143,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 xlate_in xin;
> -
> -    ofproto_rule_update_used(&rule->up, stats->used);
> -
> -    xlate_in_init(&xin, ofproto, &facet->flow, &facet->initial_vals, rule,
> -                  0, NULL);
> -    xin.resubmit_stats = stats;
> -    xlate_actions_for_side_effects(&xin);
> -}
>
>  /* Subfacets. */
>
> @@ -5386,17 +5363,6 @@ 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
> @@ -5410,11 +5376,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);
>      }
>  }
>
> --
> 1.7.9.5
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to