Looks good thank you.

Ethan

On Fri, Aug 17, 2012 at 11:27 PM, Ben Pfaff <b...@nicira.com> wrote:
> commit 6a0a5bbbc (ofproto-dpif: Make sure one-packet flows have zero
> duration.) was supposed to fix failures in the "ofproto-dpif - NetFlow
> flow expiration" test, but it didn't fix the whole problem.  That commit
> eliminated one reason why a one-packet flow might be shown as having an
> nonzero duration, but missed another.
>
> The other reason was that the call to dpif_flow_stats_extract() could
> obtain a time later than the time that a new facet was created.  (This
> wasn't obvious because dpif_flow_stats_extract() obtained the time
> internally instead of taking it from the caller.)  This commit fixes that
> problem, by using the facet creation there too for the first packet in
> a facet.
>
> This problem has suddenly started showing up in a lot of builds.  I think
> it's probably because of the recent change that makes x86-64 skip the timer
> optimizations, so that the return value of time_msec() changes every 1 ms,
> not just every 100 ms.
>
> I've tested this by running the test in question in a loop for several
> minutes, without any failures.
>
> Signed-off-by: Ben Pfaff <b...@nicira.com>
> ---
>  ofproto/ofproto-dpif.c |   36 +++++++++++++++++++++---------------
>  1 files changed, 21 insertions(+), 15 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 2fcb025..b83a50f 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -368,7 +368,8 @@ struct subfacet {
>
>  static struct subfacet *subfacet_create(struct facet *, enum odp_key_fitness,
>                                          const struct nlattr *key,
> -                                        size_t key_len, ovs_be16 
> initial_tci);
> +                                        size_t key_len, ovs_be16 initial_tci,
> +                                        long long int now);
>  static struct subfacet *subfacet_find(struct ofproto_dpif *,
>                                        const struct nlattr *key, size_t 
> key_len);
>  static void subfacet_destroy(struct subfacet *);
> @@ -2904,9 +2905,17 @@ handle_flow_miss_without_facet(struct flow_miss *miss,
>  }
>
>  /* Handles 'miss', which matches 'facet'.  May add any required datapath
> - * operations to 'ops', incrementing '*n_ops' for each new op. */
> + * operations to 'ops', incrementing '*n_ops' for each new op.
> + *
> + * All of the packets in 'miss' are considered to have arrived at time 'now'.
> + * This is really important only for new facets: if we just called 
> time_msec()
> + * here, then the new subfacet or its packets could look (occasionally) as
> + * though it was used some time after the facet was used.  That can make a
> + * one-packet flow look like it has a nonzero duration, which looks odd in
> + * e.g. NetFlow statistics. */
>  static void
>  handle_flow_miss_with_facet(struct flow_miss *miss, struct facet *facet,
> +                            long long int now,
>                              struct flow_miss_op *ops, size_t *n_ops)
>  {
>      struct ofproto_dpif *ofproto = 
> ofproto_dpif_cast(facet->rule->up.ofproto);
> @@ -2916,7 +2925,7 @@ handle_flow_miss_with_facet(struct flow_miss *miss, 
> struct facet *facet,
>
>      subfacet = subfacet_create(facet,
>                                 miss->key_fitness, miss->key, miss->key_len,
> -                               miss->initial_tci);
> +                               miss->initial_tci, now);
>
>      LIST_FOR_EACH (packet, list_node, &miss->packets) {
>          struct flow_miss_op *op = &ops[*n_ops];
> @@ -2930,7 +2939,7 @@ handle_flow_miss_with_facet(struct flow_miss *miss, 
> struct facet *facet,
>              subfacet_make_actions(subfacet, packet, &odp_actions);
>          }
>
> -        dpif_flow_stats_extract(&facet->flow, packet, time_msec(), &stats);
> +        dpif_flow_stats_extract(&facet->flow, packet, now, &stats);
>          subfacet_update_stats(subfacet, &stats);
>
>          if (subfacet->actions_len) {
> @@ -2984,6 +2993,7 @@ handle_flow_miss(struct ofproto_dpif *ofproto, struct 
> flow_miss *miss,
>                   struct flow_miss_op *ops, size_t *n_ops)
>  {
>      struct facet *facet;
> +    long long int now;
>      uint32_t hash;
>
>      /* The caller must ensure that miss->hmap_node.hash contains
> @@ -3000,8 +3010,11 @@ handle_flow_miss(struct ofproto_dpif *ofproto, struct 
> flow_miss *miss,
>          }
>
>          facet = facet_create(rule, &miss->flow, hash);
> +        now = facet->used;
> +    } else {
> +        now = time_msec();
>      }
> -    handle_flow_miss_with_facet(miss, facet, ops, n_ops);
> +    handle_flow_miss_with_facet(miss, facet, now, ops, n_ops);
>  }
>
>  /* Like odp_flow_key_to_flow(), this function converts the 'key_len' bytes of
> @@ -4248,7 +4261,8 @@ subfacet_find__(struct ofproto_dpif *ofproto,
>   * subfacet_make_actions(). */
>  static struct subfacet *
>  subfacet_create(struct facet *facet, enum odp_key_fitness key_fitness,
> -                const struct nlattr *key, size_t key_len, ovs_be16 
> initial_tci)
> +                const struct nlattr *key, size_t key_len,
> +                ovs_be16 initial_tci, long long int now)
>  {
>      struct ofproto_dpif *ofproto = 
> ofproto_dpif_cast(facet->rule->up.ofproto);
>      uint32_t key_hash = odp_flow_key_hash(key, key_len);
> @@ -4256,14 +4270,6 @@ subfacet_create(struct facet *facet, enum 
> odp_key_fitness key_fitness,
>
>      if (list_is_empty(&facet->subfacets)) {
>          subfacet = &facet->one_subfacet;
> -
> -        /* This subfacet should conceptually be created, and have its first
> -         * packet pass through, at the same time that its facet was created.
> -         * If we called time_msec() here, then the subfacet could look
> -         * (occasionally) as though it was used some time after the facet was
> -         * used.  That can make a one-packet flow look like it has a nonzero
> -         * duration, which looks odd in e.g. NetFlow statistics. */
> -        subfacet->used = facet->used;
>      } else {
>          subfacet = subfacet_find__(ofproto, key, key_len, key_hash,
>                                     &facet->flow);
> @@ -4278,7 +4284,6 @@ subfacet_create(struct facet *facet, enum 
> odp_key_fitness key_fitness,
>          }
>
>          subfacet = xmalloc(sizeof *subfacet);
> -        subfacet->used = time_msec();
>      }
>
>      hmap_insert(&ofproto->subfacets, &subfacet->hmap_node, key_hash);
> @@ -4292,6 +4297,7 @@ subfacet_create(struct facet *facet, enum 
> odp_key_fitness key_fitness,
>          subfacet->key = NULL;
>          subfacet->key_len = 0;
>      }
> +    subfacet->used = now;
>      subfacet->dp_packet_count = 0;
>      subfacet->dp_byte_count = 0;
>      subfacet->actions_len = 0;
> --
> 1.7.2.5
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to