Hi Cian,

Please find the comments inline.

> -----Original Message-----
> From: Ferriter, Cian <cian.ferri...@intel.com>
> Sent: Thursday, September 29, 2022 9:01 PM
> To: Amber, Kumar <kumar.am...@intel.com>; ovs-dev@openvswitch.org
> Cc: echau...@redhat.com; i.maxim...@ovn.org; Stokes, Ian
> <ian.sto...@intel.com>; f...@sysclose.org; Van Haaren, Harry
> <harry.van.haa...@intel.com>
> Subject: RE: [PATCH v5 8/9] mfex-study: Modify study func to select outer
> and inner mfex funcs.
> 
> Hi Amber,
> 
> My comments on the patch are below inline.
> 
> Thanks,
> Cian
> 
> > -----Original Message-----
> > From: Amber, Kumar <kumar.am...@intel.com>
> > Sent: Friday 26 August 2022 00:31
> > To: ovs-dev@openvswitch.org
> > Cc: echau...@redhat.com; i.maxim...@ovn.org; Ferriter, Cian
> > <cian.ferri...@intel.com>; Stokes, Ian <ian.sto...@intel.com>;
> > f...@sysclose.org; Van Haaren, Harry <harry.van.haa...@intel.com>;
> > Amber, Kumar <kumar.am...@intel.com>
> > Subject: [PATCH v5 8/9] mfex-study: Modify study func to select outer and
> inner mfex funcs.
> >
> > The Mfex study function is split into outer and inner to allow for
> > independent selection and studying of packets in outer and inner flows
> > to different ISA optimized Mfexs.
> 
> For the last line how about:
> > flows to different ISA optimized miniflow extract implementations.
> 
Fixed.

> >
> > Signed-off-by: Kumar Amber <kumar.am...@intel.com>
> > ---
> >  lib/dpif-netdev-extract-study.c | 126
> > +++++++++++++++++++++-----------
> >  1 file changed, 83 insertions(+), 43 deletions(-)
> >
> > diff --git a/lib/dpif-netdev-extract-study.c
> > b/lib/dpif-netdev-extract-study.c index 71354cc4c..03d97c64e 100644
> > --- a/lib/dpif-netdev-extract-study.c
> > +++ b/lib/dpif-netdev-extract-study.c
> > @@ -30,7 +30,9 @@ static atomic_uint32_t mfex_study_pkts_count =
> > MFEX_MAX_PKT_COUNT;
> >  /* Struct to hold miniflow study stats. */  struct study_stats {
> >      uint32_t pkt_count;
> > +    uint32_t pkt_inner_count;
> >      uint32_t impl_hitcount[MFEX_IMPL_MAX];
> > +    uint32_t impl_inner_hitcount[MFEX_IMPL_MAX];
> >  };
> >
> >  /* Define per thread data to hold the study stats. */ @@ -67,6 +69,58
> > @@ mfex_set_study_pkt_cnt(uint32_t pkt_cmp_count, const char *name)
> >      return -EINVAL;
> >  }
> >
> > +
> 
> Remove the extra newline here.
> 
Fixed.

> > +static inline void
> > +mfex_reset_stats(uint32_t *impls_hitcount, uint32_t *pkt_cnt) {
> > +    /* Reset stats so that study function can be called again
> > +     * for next traffic type and optimal function ptr can be
> > +     * chosen.
> > +     */
> 
> I prefer having this comment above the function rather than inside since it
> describes what the whole function does.
> I've reworded the comment to add 'the's and 'an'. How about this:
> Reset stats so that the study function can be called again for the next 
> traffic
> type and an optimal function pointer can be chosen.
> 

Fixed.

> > +    memset(impls_hitcount, 0, sizeof(uint32_t) * MFEX_IMPL_MAX);
> > +    *pkt_cnt = 0;
> > +}
> > +
> > +static inline void
> > +mfex_study_select_best_impls(struct dpif_miniflow_extract_impl
> *mfex_funcs,
> > +                             uint32_t pkt_cnt, uint32_t *impls_arr,
> > +                             atomic_uintptr_t *pmd_func, char *name)
> > +{
> > +
> > +    uint32_t best_func_index = MFEX_IMPL_START_IDX;
> > +    uint32_t max_hits = 0;
> > +
> > +    for (int i = MFEX_IMPL_START_IDX; i < MFEX_IMPL_MAX; i++) {
> > +        if (impls_arr[i] > max_hits) {
> > +            max_hits = impls_arr[i];
> > +            best_func_index = i;
> > +            }
> > +        }
> 
> These 2 braces are indented incorrectly. It should be like this:

Fixed.

> > +        }
> > +    }
> 
> 
> > +
> > +    /* If 50% of the packets hit, enable the function. */
> 
> How about this reword:
> If at least 50% of the packets hit the implementation, enable that
> implementation.
> 
Fixed.

> > +    if (max_hits >= (mfex_study_pkts_count / 2)) {
> > +        atomic_store_relaxed(pmd_func,
> > +                    (uintptr_t) mfex_funcs[best_func_index].extract_func);
> > +        VLOG_INFO("MFEX %s study chose impl %s: (hits %u/%u pkts)",
> > +                  name, mfex_funcs[best_func_index].name, max_hits,
> > +                  pkt_cnt);
> 
> The 'pkt_cnt' doesn't have to be wrapped to the next line.
> 
Fixed.

> > +    } else {
> > +        /* Set the implementation to null for default miniflow. */
> > +        atomic_store_relaxed(pmd_func,
> > +                    (uintptr_t) mfex_funcs[MFEX_IMPL_SCALAR].extract_func);
> > +        VLOG_INFO("Not enough packets matched (%u/%u), disabling"
> > +                  " optimized MFEX.", max_hits, pkt_cnt);
> > +    }
> > +
> > +    /* In debug mode show stats for all the counters. */
> > +    if (VLOG_IS_DBG_ENABLED()) {
> > +        for (int i = MFEX_IMPL_START_IDX; i < MFEX_IMPL_MAX; i++) {
> > +                VLOG_DBG("MFEX study results for implementation %s:"
> > +                         " (hits %u/%u pkts)", mfex_funcs[i].name,
> > +                         impls_arr[i], pkt_cnt);
> > +        }
> > +    }
> > +}
> > +
> >  uint32_t
> >  mfex_study_traffic(struct dp_packet_batch *packets,
> >                     struct netdev_flow_key *keys, @@ -76,10 +130,12 @@
> > mfex_study_traffic(struct dp_packet_batch *packets,  {
> >      uint32_t hitmask = 0;
> >      uint32_t mask = 0;
> > +    uint32_t study_cnt_pkts;
> >      struct dp_netdev_pmd_thread *pmd = pmd_handle;
> >      struct dpif_miniflow_extract_impl *miniflow_funcs;
> >      struct study_stats *stats = mfex_study_get_study_stats_ptr();
> >      miniflow_funcs = dpif_mfex_impl_info_get();
> > +    atomic_read_relaxed(&mfex_study_pkts_count, &study_cnt_pkts);
> >
> >      /* Run traffic optimized miniflow_extract to collect the hitmask
> >       * to be compared after certain packets have been hit to choose
> > @@ -93,7 +149,11 @@ mfex_study_traffic(struct dp_packet_batch
> *packets,
> >          hitmask = miniflow_funcs[i].extract_func(packets, keys, keys_size,
> >                                                   in_port, pmd_handle,
> >                                                   md_is_valid);
> > -        stats->impl_hitcount[i] += count_1bits(hitmask);
> > +        if (!md_is_valid) {
> > +            stats->impl_hitcount[i] += count_1bits(hitmask);
> > +        } else {
> > +            stats->impl_inner_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
> > @@ -102,54 +162,34 @@ mfex_study_traffic(struct dp_packet_batch
> *packets,
> >          mask |= hitmask;
> >      }
> >
> > -    stats->pkt_count += dp_packet_batch_size(packets);
> > -
> >      /* Choose the best implementation after a minimum packets have been
> >       * processed.
> >       */
> 
> How about updating the comment to:
> Choose the best miniflow extract implementation to use for inner and outer
> packets separately.
> 
Fixed.

> > -    uint32_t study_cnt_pkts;
> > -    atomic_read_relaxed(&mfex_study_pkts_count, &study_cnt_pkts);
> > -
> > -    if (stats->pkt_count >= study_cnt_pkts) {
> > -        uint32_t best_func_index = MFEX_IMPL_START_IDX;
> > -        uint32_t max_hits = 0;
> > -        for (int i = MFEX_IMPL_START_IDX; i < MFEX_IMPL_MAX; i++) {
> > -            if (stats->impl_hitcount[i] > max_hits) {
> > -                max_hits = stats->impl_hitcount[i];
> > -                best_func_index = i;
> > -            }
> > +    if (!md_is_valid) {
> > +        stats->pkt_count += dp_packet_batch_size(packets);
> > +
> > +        if (stats->pkt_count >= study_cnt_pkts) {
> > +            char name[] = "outer";
> > +            mfex_study_select_best_impls(miniflow_funcs, stats->pkt_count,
> > +                             stats->impl_hitcount,
> > +                             (void *)&pmd->miniflow_extract_opt,
> > +                             name);
> > +            mfex_reset_stats(stats->impl_hitcount,
> > + &stats->pkt_count);
> >          }
> >
> > -        /* If 50% of the packets hit, enable the function. */
> > -        if (max_hits >= (mfex_study_pkts_count / 2)) {
> > -            atomic_store_relaxed(&pmd->miniflow_extract_opt,
> > -                                 
> > miniflow_funcs[best_func_index].extract_func);
> > -            VLOG_INFO("MFEX study chose impl %s: (hits %u/%u pkts)",
> > -                      miniflow_funcs[best_func_index].name, max_hits,
> > -                      stats->pkt_count);
> > -        } else {
> > -            /* Set the implementation to null for default miniflow. */
> > -            atomic_store_relaxed(&pmd->miniflow_extract_opt,
> > -                    miniflow_funcs[MFEX_IMPL_SCALAR].extract_func);
> > -            VLOG_INFO("Not enough packets matched (%u/%u), disabling"
> > -                      " optimized MFEX.", max_hits, stats->pkt_count);
> > +    } else {
> > +        stats->pkt_inner_count += dp_packet_batch_size(packets);
> > +
> > +        if (stats->pkt_inner_count >= study_cnt_pkts) {
> > +            char name[] = "inner";
> > +            mfex_study_select_best_impls(miniflow_funcs,
> > +                             stats->pkt_inner_count,
> > +                             stats->impl_inner_hitcount,
> > +                             (void *)&pmd->miniflow_extract_inner_opt,
> > +                             name);
> > +            mfex_reset_stats(stats->impl_inner_hitcount,
> > +                             &stats->pkt_inner_count);
> >          }
> > -
> > -        /* In debug mode show stats for all the counters. */
> > -        if (VLOG_IS_DBG_ENABLED()) {
> > -
> > -            for (int i = MFEX_IMPL_START_IDX; i < MFEX_IMPL_MAX; i++) {
> > -                VLOG_DBG("MFEX study results for implementation %s:"
> > -                         " (hits %u/%u pkts)", miniflow_funcs[i].name,
> > -                         stats->impl_hitcount[i], stats->pkt_count);
> > -            }
> > -        }
> > -
> > -        /* 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;
> >  }
> > --
> > 2.25.1
> 
> Overall, I like the reuse of code. And I think the patch looks good. The above
> are all smaller comments. The only major thing is what I mentioned in patch
> 7/9 about seeing whether we can get the same behaviour without using the
> 'md_is_valid' bool at all.

Thanks, Md_is_valid is a better solution.

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

Reply via email to