> -----Original Message-----
> From: Ciara Power <[email protected]>
> Sent: Tuesday, October 13, 2020 7:04 PM
> To: [email protected]
> Cc: [email protected]; Ruifeng Wang <[email protected]>;
> [email protected]; [email protected]; [email protected];
> [email protected]; Ciara Power <[email protected]>;
> Honnappa Nagarahalli <[email protected]>; Dmitry Kozlyuk
> <[email protected]>; Narcisa Ana Maria Vasile
> <[email protected]>; Dmitry Malloy <[email protected]>;
> Pallavi Kadam <[email protected]>; Ray Kinsella <[email protected]>;
> Neil Horman <[email protected]>
> Subject: [PATCH v5 01/17] eal: add max SIMD bitwidth
> 
> This patch adds a max SIMD bitwidth EAL configuration. The API allows for an
> app to set this value. It can also be set using EAL argument --force-max-simd-
> bitwidth, which will lock the value and override any modifications made by
> the app.
> 
> Each arch has a define for the default SIMD bitwidth value, this is used on 
> EAL
> init to set the config max SIMD bitwidth.
> 
> Cc: Ruifeng Wang <[email protected]>
> Cc: Jerin Jacob <[email protected]>
> Cc: Honnappa Nagarahalli <[email protected]>
> Cc: David Christensen <[email protected]>
> 
> Signed-off-by: Ciara Power <[email protected]>
> 
> ---
> v4:
>   - Used RTE_SIMD_MAX instead of UINT16_MAX.
>   - Renamed enums to better reflect usage.
>   - Added functions to windows symbol export file.
>   - Modified Doxygen comments.
>   - Modified enum name.
>   - Changed RTE_SIMD_MAX value to a power of 2.
>   - Merged patch 2 into this patch.
>   - Enum now used for default value defines.
>   - Fixed some small comments on v3.
> v3:
>   - Added enum value to essentially disable using max SIMD to choose
>     paths, intended for use by ARM SVE.
>   - Fixed parsing bitwidth argument to return an error for values
>     greater than uint16_t.
>   - Removed unnecessary define in generic rte_vect.h
>   - Changed default bitwidth for ARM to UINT16_MAX, to allow for SVE.
> v2:
>   - Added to Doxygen comment for API.
>   - Changed default bitwidth for Arm to 128.
> ---
>  lib/librte_eal/arm/include/rte_vect.h      |  2 +
>  lib/librte_eal/common/eal_common_options.c | 66
> ++++++++++++++++++++++
>  lib/librte_eal/common/eal_internal_cfg.h   |  8 +++
>  lib/librte_eal/common/eal_options.h        |  2 +
>  lib/librte_eal/include/rte_eal.h           | 40 +++++++++++++
>  lib/librte_eal/ppc/include/rte_vect.h      |  2 +
>  lib/librte_eal/rte_eal_exports.def         |  2 +
>  lib/librte_eal/rte_eal_version.map         |  2 +
>  lib/librte_eal/x86/include/rte_vect.h      |  2 +
>  9 files changed, 126 insertions(+)
> 
> diff --git a/lib/librte_eal/arm/include/rte_vect.h
> b/lib/librte_eal/arm/include/rte_vect.h
> index 01c51712a1..f53c89be97 100644
> --- a/lib/librte_eal/arm/include/rte_vect.h
> +++ b/lib/librte_eal/arm/include/rte_vect.h
> @@ -14,6 +14,8 @@
>  extern "C" {
>  #endif
> 
> +#define RTE_DEFAULT_SIMD_BITWIDTH RTE_SIMD_MAX
> +
>  typedef int32x4_t xmm_t;
> 
>  #define      XMM_SIZE        (sizeof(xmm_t))
> diff --git a/lib/librte_eal/common/eal_common_options.c
> b/lib/librte_eal/common/eal_common_options.c
> index a5426e1234..8c79f1b2fc 100644
> --- a/lib/librte_eal/common/eal_common_options.c
> +++ b/lib/librte_eal/common/eal_common_options.c
> @@ -35,6 +35,7 @@
>  #ifndef RTE_EXEC_ENV_WINDOWS
>  #include <rte_telemetry.h>
>  #endif
> +#include <rte_vect.h>
> 
>  #include "eal_internal_cfg.h"
>  #include "eal_options.h"
> @@ -102,6 +103,7 @@ eal_long_options[] = {
>       {OPT_MATCH_ALLOCATIONS, 0, NULL,
> OPT_MATCH_ALLOCATIONS_NUM},
>       {OPT_TELEMETRY,         0, NULL, OPT_TELEMETRY_NUM        },
>       {OPT_NO_TELEMETRY,      0, NULL, OPT_NO_TELEMETRY_NUM     },
> +     {OPT_FORCE_MAX_SIMD_BITWIDTH, 1, NULL,
> +OPT_FORCE_MAX_SIMD_BITWIDTH_NUM},
>       {0,                     0, NULL, 0                        }
>  };
> 
> @@ -343,6 +345,8 @@ eal_reset_internal_config(struct internal_config
> *internal_cfg)
>       internal_cfg->user_mbuf_pool_ops_name = NULL;
>       CPU_ZERO(&internal_cfg->ctrl_cpuset);
>       internal_cfg->init_complete = 0;
> +     internal_cfg->max_simd_bitwidth.bitwidth =
> RTE_DEFAULT_SIMD_BITWIDTH;
> +     internal_cfg->max_simd_bitwidth.forced = 0;
>  }
> 
>  static int
> @@ -1309,6 +1313,34 @@ eal_parse_iova_mode(const char *name)
>       return 0;
>  }
> 
> +static int
> +eal_parse_simd_bitwidth(const char *arg) {
> +     char *end;
> +     unsigned long bitwidth;
> +     int ret;
> +     struct internal_config *internal_conf =
> +             eal_get_internal_configuration();
> +
> +     if (arg == NULL || arg[0] == '\0')
> +             return -1;
> +
> +     errno = 0;
> +     bitwidth = strtoul(arg, &end, 0);
> +
> +     /* check for errors */
> +     if (errno != 0 || end == NULL || *end != '\0' || bitwidth >
> RTE_SIMD_MAX)
> +             return -1;
> +
> +     if (bitwidth == 0)
> +             bitwidth = (unsigned long) RTE_SIMD_MAX;
> +     ret = rte_set_max_simd_bitwidth(bitwidth);
> +     if (ret < 0)
> +             return -1;
> +     internal_conf->max_simd_bitwidth.forced = 1;
> +     return 0;
> +}
> +
>  static int
>  eal_parse_base_virtaddr(const char *arg)  { @@ -1707,6 +1739,13 @@
> eal_parse_common_option(int opt, const char *optarg,
>       case OPT_NO_TELEMETRY_NUM:
>               conf->no_telemetry = 1;
>               break;
> +     case OPT_FORCE_MAX_SIMD_BITWIDTH_NUM:
> +             if (eal_parse_simd_bitwidth(optarg) < 0) {
> +                     RTE_LOG(ERR, EAL, "invalid parameter for --"
> +                                     OPT_FORCE_MAX_SIMD_BITWIDTH
> "\n");
> +                     return -1;
> +             }
> +             break;
> 
>       /* don't know what to do, leave this to caller */
>       default:
> @@ -1903,6 +1942,32 @@ eal_check_common_options(struct
> internal_config *internal_cfg)
>       return 0;
>  }
> 
> +uint16_t
> +rte_get_max_simd_bitwidth(void)
> +{
> +     const struct internal_config *internal_conf =
> +             eal_get_internal_configuration();
> +     return internal_conf->max_simd_bitwidth.bitwidth;
> +}
> +
> +int
> +rte_set_max_simd_bitwidth(uint16_t bitwidth) {
> +     struct internal_config *internal_conf =
> +             eal_get_internal_configuration();
> +     if (internal_conf->max_simd_bitwidth.forced) {
> +             RTE_LOG(NOTICE, EAL, "Cannot set max SIMD bitwidth - user
> runtime override enabled");
> +             return -EPERM;
> +     }
> +
> +     if (bitwidth < RTE_SIMD_DISABLED || !rte_is_power_of_2(bitwidth))
> {
> +             RTE_LOG(ERR, EAL, "Invalid bitwidth value!\n");
> +             return -EINVAL;
> +     }
> +     internal_conf->max_simd_bitwidth.bitwidth = bitwidth;
> +     return 0;
> +}
> +
>  void
>  eal_common_usage(void)
>  {
> @@ -1981,6 +2046,7 @@ eal_common_usage(void)
>              "  --"OPT_BASE_VIRTADDR"     Base virtual address\n"
>              "  --"OPT_TELEMETRY"   Enable telemetry support (on by
> default)\n"
>              "  --"OPT_NO_TELEMETRY"   Disable telemetry support\n"
> +            "  --"OPT_FORCE_MAX_SIMD_BITWIDTH" Force the max SIMD
> bitwidth\n"
>              "\nEAL options for DEBUG use only:\n"
>              "  --"OPT_HUGE_UNLINK"       Unlink hugepage files after init\n"
>              "  --"OPT_NO_HUGE"           Use malloc instead of hugetlbfs\n"
> diff --git a/lib/librte_eal/common/eal_internal_cfg.h
> b/lib/librte_eal/common/eal_internal_cfg.h
> index 13f93388a7..0c880cbe17 100644
> --- a/lib/librte_eal/common/eal_internal_cfg.h
> +++ b/lib/librte_eal/common/eal_internal_cfg.h
> @@ -33,6 +33,12 @@ struct hugepage_info {
>       int lock_descriptor;    /**< file descriptor for hugepage dir */
>  };
> 
> +struct simd_bitwidth {
> +     bool forced;
> +     /**< flag indicating if bitwidth is forced and can't be modified */
> +     uint16_t bitwidth; /**< bitwidth value */ };
> +
>  /**
>   * internal configuration
>   */
> @@ -85,6 +91,8 @@ struct internal_config {
>       volatile unsigned int init_complete;
>       /**< indicates whether EAL has completed initialization */
>       unsigned int no_telemetry; /**< true to disable Telemetry */
> +     struct simd_bitwidth max_simd_bitwidth;
> +     /**< max simd bitwidth path to use */
>  };
> 
>  void eal_reset_internal_config(struct internal_config *internal_cfg); diff 
> --git
> a/lib/librte_eal/common/eal_options.h
> b/lib/librte_eal/common/eal_options.h
> index 89769d48b4..ef33979664 100644
> --- a/lib/librte_eal/common/eal_options.h
> +++ b/lib/librte_eal/common/eal_options.h
> @@ -85,6 +85,8 @@ enum {
>       OPT_TELEMETRY_NUM,
>  #define OPT_NO_TELEMETRY      "no-telemetry"
>       OPT_NO_TELEMETRY_NUM,
> +#define OPT_FORCE_MAX_SIMD_BITWIDTH  "force-max-simd-bitwidth"
> +     OPT_FORCE_MAX_SIMD_BITWIDTH_NUM,
>       OPT_LONG_MAX_NUM
>  };
> 
> diff --git a/lib/librte_eal/include/rte_eal.h 
> b/lib/librte_eal/include/rte_eal.h
> index e3c2ef185e..706d3cca5a 100644
> --- a/lib/librte_eal/include/rte_eal.h
> +++ b/lib/librte_eal/include/rte_eal.h
> @@ -43,6 +43,23 @@ enum rte_proc_type_t {
>       RTE_PROC_INVALID
>  };
> 
> +/**
> + * The max SIMD bitwidth value to limit vector path selection.
> + */
> +enum rte_max_simd {
> +     RTE_SIMD_DISABLED = 64,
> +     /**< Limits path selection to scalar, disables all vector paths. */
> +     RTE_SIMD_128 = 128,
> +     /**< Limits path selection to SSE/NEON/Altivec or below. */
> +     RTE_SIMD_256 = 256, /**< Limits path selection to AVX2 or below. */
> +     RTE_SIMD_512 = 512, /**< Limits path selection to AVX512 or below.
> */
> +     RTE_SIMD_MAX = INT16_MAX + 1,
> +     /**<
> +      * Disables limiting by max SIMD bitwidth, allows all suitable paths.
> +      * This value is used as it is a large number and a power of 2.
> +      */
> +};
> +
>  /**
>   * Get the process type in a multi-process setup
>   *
> @@ -51,6 +68,29 @@ enum rte_proc_type_t {
>   */
>  enum rte_proc_type_t rte_eal_process_type(void);
> 
> +/**
> + * Get the supported SIMD bitwidth.
> + *
> + * @return
> + *   uint16_t bitwidth.
> + */
> +__rte_experimental
> +uint16_t rte_get_max_simd_bitwidth(void);
> +
> +/**
> + * Set the supported SIMD bitwidth.
> + * This API should only be called once at initialization, before EAL init.
> + *
> + * @param bitwidth
> + *   uint16_t bitwidth.
> + * @return
> + *   - 0 on success.
> + *   - -EINVAL on invalid bitwidth parameter.
> + *   - -EPERM if bitwidth is forced.
> + */
> +__rte_experimental
> +int rte_set_max_simd_bitwidth(uint16_t bitwidth);
> +
>  /**
>   * Request iopl privilege for all RPL.
>   *
> diff --git a/lib/librte_eal/ppc/include/rte_vect.h
> b/lib/librte_eal/ppc/include/rte_vect.h
> index b0545c878c..a69aabc568 100644
> --- a/lib/librte_eal/ppc/include/rte_vect.h
> +++ b/lib/librte_eal/ppc/include/rte_vect.h
> @@ -15,6 +15,8 @@
>  extern "C" {
>  #endif
> 
> +#define RTE_DEFAULT_SIMD_BITWIDTH RTE_SIMD_256
> +
>  typedef vector signed int xmm_t;
> 
>  #define      XMM_SIZE        (sizeof(xmm_t))
> diff --git a/lib/librte_eal/rte_eal_exports.def
> b/lib/librte_eal/rte_eal_exports.def
> index 7b35beb702..81e99b00d9 100644
> --- a/lib/librte_eal/rte_eal_exports.def
> +++ b/lib/librte_eal/rte_eal_exports.def
> @@ -26,6 +26,7 @@ EXPORTS
>       rte_eal_tailq_register
>       rte_eal_using_phys_addrs
>       rte_free
> +     rte_get_max_simd_bitwidth
>       rte_get_tsc_hz
>       rte_hexdump
>       rte_intr_rx_ctl
> @@ -62,6 +63,7 @@ EXPORTS
>       rte_memzone_reserve_aligned
>       rte_memzone_reserve_bounded
>       rte_memzone_walk
> +     rte_set_max_simd_bitwidth
>       rte_socket_id
>       rte_strerror
>       rte_strsplit
> diff --git a/lib/librte_eal/rte_eal_version.map
> b/lib/librte_eal/rte_eal_version.map
> index a93dea9fe6..714be49377 100644
> --- a/lib/librte_eal/rte_eal_version.map
> +++ b/lib/librte_eal/rte_eal_version.map
> @@ -400,6 +400,8 @@ EXPERIMENTAL {
>       # added in 20.11
>       __rte_eal_trace_generic_size_t;
>       rte_service_lcore_may_be_active;
> +     rte_get_max_simd_bitwidth;
> +     rte_set_max_simd_bitwidth;
>  };
> 
>  INTERNAL {
> diff --git a/lib/librte_eal/x86/include/rte_vect.h
> b/lib/librte_eal/x86/include/rte_vect.h
> index df5a607623..a00d3d5a62 100644
> --- a/lib/librte_eal/x86/include/rte_vect.h
> +++ b/lib/librte_eal/x86/include/rte_vect.h
> @@ -35,6 +35,8 @@
>  extern "C" {
>  #endif
> 
> +#define RTE_DEFAULT_SIMD_BITWIDTH RTE_SIMD_256
> +
>  typedef __m128i xmm_t;
> 
>  #define      XMM_SIZE        (sizeof(xmm_t))
> --
> 2.22.0
Arm SVE may not perfectly fit into this. Because SIMD bitwidth is unknown / 
unconcerned by application. 
I think vector path will be taken when max SIMD bitwidth is not set to 
RTE_SIMD_DISABLED.

Reviewed-by: Ruifeng Wang <[email protected]>

Reply via email to