Hi Eelco,

Pls find replies inline.

<Snip>

> > +uint32_t
> > +mfex_study_traffic(struct dp_packet_batch *packets,
> > +                   struct netdev_flow_key *keys,
> > +                   uint32_t keys_size, odp_port_t in_port,
> > +                   struct dp_netdev_pmd_thread *pmd_handle) {
> > +    uint32_t hitmask = 0;
> > +    uint32_t mask = 0;
> > +    struct dp_netdev_pmd_thread *pmd = pmd_handle;
> > +    struct dpif_miniflow_extract_impl *miniflow_funcs;
> > +    uint32_t impl_count = dpif_mfex_impl_info_get(&miniflow_funcs);
> 
> This function returns an -errno on failure, so we should test the return.
> 

Added check in v7.
> > +    struct study_stats *stats = mfex_study_get_study_stats_ptr();
> > +
> > +    /* Run traffic optimized miniflow_extract to collect the hitmask
> > +     * to be compared after certain packets have been hit to choose
> > +     * the best miniflow_extract version for that traffic.
> > +     */
> > +    for (int i = MFEX_IMPL_MAX; i < impl_count; i++) {
> 
> See comment on patch 2 on using an explicit minimum value.
> 
> > +        if (miniflow_funcs[i].available) {
> 
> For consistency, and to safe one indent level, why not do the below, as you 
> did
> in your other patch:
> 
> if (!miniflow_funcs[i].available) {
>   Continue;
> }

Applied to v7.
> 
> > +            hitmask = miniflow_funcs[i].extract_func(packets, keys, 
> > keys_size,
> > +                                                     in_port, pmd_handle);
> > +            stats->impl_hitcount[i] += count_1bits(hitmask);
> > +
> > +            /* If traffic is not classified then we dont overwrite the keys
> > +             * array in minfiflow implementations so its safe to create a
> > +             * mask for all those packets whose miniflow have been created.
> > +             */
> > +            mask |= hitmask;
> > +        }
> > +    }
> > +    stats->pkt_count += dp_packet_batch_size(packets);
> > +
> > +    /* Choose the best implementation after a minimum packets have been
> > +     * processed.
> > +     */
> > +    if (stats->pkt_count >= MFEX_MAX_COUNT) {
> > +        uint32_t best_func_index = MFEX_IMPL_MAX;
> 
> See comment on MFEX_IMPL_START_IDX for above and for loop below.
> 

Fixed in v7.

> > +        uint32_t max_hits = 0;
> > +        for (int i = MFEX_IMPL_MAX; i < impl_count; i++) {
> > +            if (stats->impl_hitcount[i] > max_hits) {
> > +                max_hits = stats->impl_hitcount[i];
> > +                best_func_index = i;
> > +            }
> > +        }
> > +
> > +        /* If 50% of the packets hit, enable the function. */
> > +        if (max_hits >= (mfex_study_pkts_count / 2)) {
> > +            miniflow_extract_func mf_func =
> > +                        miniflow_funcs[best_func_index].extract_func;
> > +            atomic_uintptr_t *pmd_func = (void 
> > *)&pmd->miniflow_extract_opt;
> > +            atomic_store_relaxed(pmd_func, (uintptr_t) mf_func);
> > +            VLOG_INFO("MFEX study chose impl %s: (hits %d/%d pkts)",
> > +                      miniflow_funcs[best_func_index].name, max_hits,
> > +                      stats->pkt_count);
> > +        } else {
> > +            /* Set the implementation to null for default miniflow. */
> > +            miniflow_extract_func mf_func =
> > +                        miniflow_funcs[MFEX_IMPL_SCALAR].extract_func;
> > +            atomic_uintptr_t *pmd_func = (void 
> > *)&pmd->miniflow_extract_opt;
> > +            atomic_store_relaxed(pmd_func, (uintptr_t) mf_func);
> > +            VLOG_INFO("Not enough packets matched (%d/%d), disabling"
> > +                      " optimized MFEX.", max_hits, stats->pkt_count);
> > +        }
> 
> I still would like to see the hits for all hits when debugging is enabled.
> Maybe something like
>
> if (VLOG_IS_DBG_ENABLED()) {
>       for each imp in i:
>        VLOG_DBG(“MFEX study results for implementation %s: (hits %d/%d pkts)",
>                       miniflow_funcs[i].name, stats->impl_hitcount[i],
>                       stats->pkt_count);
> 
> }
> 

Applied in v7.
> > +        /* Reset stats so that study function can be called again
> > +         * for next traffic type and optimal function ptr can be
> > +         * chosen.
> > +         */
> > +        memset(stats, 0, sizeof(struct study_stats));
> > +    }
> > +    return mask;
> > +}
> > diff --git a/lib/dpif-netdev-private-extract.c
> > b/lib/dpif-netdev-private-extract.c
> > index 62170ff6c..eaddeceaf 100644
> > --- a/lib/dpif-netdev-private-extract.c
> > +++ b/lib/dpif-netdev-private-extract.c
> > @@ -47,6 +47,11 @@ static struct dpif_miniflow_extract_impl mfex_impls[] =
> {
> >          .probe = NULL,
> >          .extract_func = NULL,
> >          .name = "scalar", },
> > +
> > +    [MFEX_IMPL_STUDY] = {
> > +        .probe = NULL,
> > +        .extract_func = mfex_study_traffic,
> > +        .name = "study", },
> >  };
> >
> >  BUILD_ASSERT_DECL(MFEX_IMPL_MAX >= ARRAY_SIZE(mfex_impls)); @@ -
> 88,7
> > +93,6 @@ dp_mfex_impl_set_default_by_name(const char *name)  {
> >      miniflow_extract_func new_default;
> >
> > -
> 
> Guess this need to be fixed in the previous patch.
> 

Fixed already.
> >      int32_t err = dp_mfex_impl_get_by_name(name, &new_default);
> >
> >      if (!err) {
> > @@ -146,7 +150,6 @@ dp_mfex_impl_get_by_name(const char *name,
> miniflow_extract_func *out_func)
> >      }
> >
> >      uint32_t i;
> > -
> 
> Guess this need to be fixed in the previous patch.
> 

Fixed already in v7.

> >      for (i = 0; i < ARRAY_SIZE(mfex_impls); i++) {
> >          if (strcmp(mfex_impls[i].name, name) == 0) {
> >              /* Probe function is optional - so check it is set before
> > exec. */ @@ -163,6 +166,18 @@ dp_mfex_impl_get_by_name(const char
> *name, miniflow_extract_func *out_func)
> >      return -EINVAL;
> >  }
> >
> > +int32_t
> 
> Please make this an int.
>

Done.
 
> > +dpif_mfex_impl_info_get(struct dpif_miniflow_extract_impl **out_ptr)
> > +{
> > +    if (out_ptr == NULL) {
> > +        return -EINVAL;
> > +    }
> > +
> > +    *out_ptr = mfex_impls;
> > +
> > +    return ARRAY_SIZE(mfex_impls);
> > +}
> > +
> >  uint32_t
> >  dpif_miniflow_extract_autovalidator(struct dp_packet_batch *packets,
> >                                      struct netdev_flow_key *keys,
> > diff --git a/lib/dpif-netdev-private-extract.h
> > b/lib/dpif-netdev-private-extract.h
> > index 10525c378..cd46c94dd 100644
> > --- a/lib/dpif-netdev-private-extract.h
> > +++ b/lib/dpif-netdev-private-extract.h
> > @@ -71,6 +71,7 @@ struct dpif_miniflow_extract_impl {  enum
> > dpif_miniflow_extract_impl_idx {
> >      MFEX_IMPL_AUTOVALIDATOR,
> >      MFEX_IMPL_SCALAR,
> > +    MFEX_IMPL_STUDY,
> >      MFEX_IMPL_MAX
> >  };
> >
> > @@ -94,6 +95,13 @@ miniflow_extract_func
> > dp_mfex_impl_get_default(void);
> >  /* Overrides the default MFEX with the user set MFEX. */  int32_t
> > dp_mfex_impl_set_default_by_name(const char *name);
> >
> > +/* Retrieve the array of miniflow implementations for iteration.
> > + * On error, returns a negative number.
> > + * On success, returns the size of the arrays pointed to by the out 
> > parameter.
> > + */
> > +int32_t
> > +dpif_mfex_impl_info_get(struct dpif_miniflow_extract_impl **out_ptr);
> > +
> >
> >  /* Initializes the available miniflow extract implementations by probing 
> > for
> >   * the CPU ISA requirements. As the runtime available CPU ISA does
> > not change @@ -115,4 +123,16 @@
> dpif_miniflow_extract_autovalidator(struct dp_packet_batch *batch,
> >                                      uint32_t keys_size, odp_port_t in_port,
> >                                      struct dp_netdev_pmd_thread
> > *pmd_handle);
> >
> > +/* Retrieve the number of packets by studying packets using different
> > +miniflow
> > + * implementations to choose the best implementation using the
> > +maximum hitmask
> > + * count.
> > + * On error, returns a zero for no packets.
> > + * On success, returns mask of the packets hit.
> > + */
> > +uint32_t
> > +mfex_study_traffic(struct dp_packet_batch *packets,
> > +                   struct netdev_flow_key *keys,
> > +                   uint32_t keys_size, odp_port_t in_port,
> > +                   struct dp_netdev_pmd_thread *pmd_handle);
> > +
> >  #endif /* MFEX_AVX512_EXTRACT */
> > --
> > 2.32.0

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to