On 12 Oct 2022, at 13:55, Cian Ferriter wrote:

> From: Kumar Amber <[email protected]>
>
> 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 miniflow extract implementations.
>
> Signed-off-by: Kumar Amber <[email protected]>
> Acked-by: Cian Ferriter <[email protected]>
> Acked-by: Sunil Pai G <[email protected]>
> ---

Please change the inner/outer references to (original) input packet, 
recirculating handling?

>  lib/dpif-netdev-extract-study.c | 127 +++++++++++++++++++++-----------
>  1 file changed, 82 insertions(+), 45 deletions(-)
>
> diff --git a/lib/dpif-netdev-extract-study.c b/lib/dpif-netdev-extract-study.c
> index 71354cc4c..da4734256 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];
>  };
>

  struct study_stats {
      uint32_t input_pkt_count;
      uint32_t recirc_pkt_count;
      uint32_t impl_input_hitcount[MFEX_IMPL_MAX];
      uint32_t impl_recirc_hitcount[MFEX_IMPL_MAX];
  };

>  /* Define per thread data to hold the study stats. */
> @@ -67,6 +69,57 @@ mfex_set_study_pkt_cnt(uint32_t pkt_cmp_count, const char 
> *name)
>      return -EINVAL;
>  }
>
> +/* Reset stats so that the study function can be called again for the next
> + * traffic type and an optimal function pointer can be chosen.
> + */
> +static inline void
> +mfex_reset_stats(uint32_t *impls_hitcount, uint32_t *pkt_cnt) {
> +    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;
> +        }
> +    }
> +
> +    /* If at least 50% of the packets hit the implementation,
> +     * enable that implementation.
> +     */
> +    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);
> +    } 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);
> +        }
> +    }

For all the VLOG's above we should inform what implementation we report on, 
i.e. the input or recirc packet extract implementation.

> +}
> +
>  uint32_t
>  mfex_study_traffic(struct dp_packet_batch *packets,
>                     struct netdev_flow_key *keys,
> @@ -76,10 +129,12 @@ mfex_study_traffic(struct dp_packet_batch *packets,
>  {
>      uint32_t hitmask = 0;
>      uint32_t mask = 0;
> +    uint32_t study_cnt_pkts;

Please add as the first variable to adhere to reverse Christmas tree

>      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();

While your here, please add a new line between definitions and other code.

>      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 +148,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 +161,32 @@ 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.
> +    /* Choose the best miniflow extract implementation to use for inner
> +     * and outer packets separately.
>       */
> -    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 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);
> +    if (!md_is_valid) {
> +        stats->pkt_count += dp_packet_batch_size(packets);
> +
> +        if (stats->pkt_count >= study_cnt_pkts) {
> +            char name[] = "outer";

"original packet"

> +            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);
>          }
>
> -        /* 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);
> -            }
> +    } else {
> +        stats->pkt_inner_count += dp_packet_batch_size(packets);
> +
> +        if (stats->pkt_inner_count >= study_cnt_pkts) {
> +            char name[] = "inner";

"recirculation packet"

> +            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);
>          }
> -
> -        /* 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

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to