eal: control max SIMD bitwidth
authorCiara Power <ciara.power@intel.com>
Mon, 19 Oct 2020 13:48:41 +0000 (15:48 +0200)
committerDavid Marchand <david.marchand@redhat.com>
Mon, 19 Oct 2020 14:45:02 +0000 (16:45 +0200)
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.

Signed-off-by: Ciara Power <ciara.power@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
Acked-by: Ray Kinsella <mdr@ashroe.eu>
12 files changed:
doc/guides/linux_gsg/eal_args.include.rst
doc/guides/prog_guide/env_abstraction_layer.rst
doc/guides/rel_notes/release_20_11.rst
lib/librte_eal/arm/include/rte_vect.h
lib/librte_eal/common/eal_common_options.c
lib/librte_eal/common/eal_internal_cfg.h
lib/librte_eal/common/eal_options.h
lib/librte_eal/include/generic/rte_vect.h
lib/librte_eal/ppc/include/rte_vect.h
lib/librte_eal/rte_eal_exports.def
lib/librte_eal/rte_eal_version.map
lib/librte_eal/x86/include/rte_vect.h

index 0fe4457..a0bfbd1 100644 (file)
@@ -210,3 +210,19 @@ Other options
 *    ``--no-telemetry``:
 
     Disable telemetry.
+
+*    ``--force-max-simd-bitwidth=<val>``:
+
+    Specify the maximum SIMD bitwidth size to handle. This limits which vector paths,
+    if any, are taken, as any paths taken must use a bitwidth below the max bitwidth limit.
+    For example, to allow all SIMD bitwidths up to and including AVX-512::
+
+        --force-max-simd-bitwidth=512
+
+    The following example shows limiting the bitwidth to 64-bits to disable all vector code::
+
+        --force-max-simd-bitwidth=64
+
+    To disable use of max SIMD bitwidth limit::
+
+        --force-max-simd-bitwidth=0
index 936c885..fafed83 100644 (file)
@@ -486,6 +486,40 @@ the desired addressing mode when virtual devices that are not directly attached
 To facilitate forcing the IOVA mode to a specific value the EAL command line option ``--iova-mode`` can
 be used to select either physical addressing('pa') or virtual addressing('va').
 
+.. _max_simd_bitwidth:
+
+
+Max SIMD bitwidth
+~~~~~~~~~~~~~~~~~
+
+The EAL provides a single setting to limit the max SIMD bitwidth used by DPDK,
+which is used in determining the vector path, if any, chosen by a component.
+The value can be set at runtime by an application using the
+'rte_vect_set_max_simd_bitwidth(uint16_t bitwidth)' function,
+which should only be called once at initialization, before EAL init.
+The value can be overridden by the user using the EAL command-line option '--force-max-simd-bitwidth'.
+
+When choosing a vector path, along with checking the CPU feature support,
+the value of the max SIMD bitwidth must also be checked, and can be retrieved using the
+'rte_vect_get_max_simd_bitwidth()' function.
+The value should be compared against the enum values for accepted max SIMD bitwidths:
+
+.. code-block:: c
+
+   enum rte_vect_max_simd {
+       RTE_VECT_SIMD_DISABLED = 64,
+       RTE_VECT_SIMD_128 = 128,
+       RTE_VECT_SIMD_256 = 256,
+       RTE_VECT_SIMD_512 = 512,
+       RTE_VECT_SIMD_MAX = INT16_MAX + 1,
+   };
+
+    if (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_512)
+        /* Take AVX-512 vector path */
+    else if (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256)
+        /* Take AVX2 vector path */
+
+
 Memory Segments and Memory Zones (memzone)
 ------------------------------------------
 
index 25ea3c2..278d8dd 100644 (file)
@@ -77,6 +77,13 @@ New Features
   This API is specific to x86 and implemented as a stub for other
   architectures.
 
+* **Added support for limiting maximum SIMD bitwidth.**
+
+  Added a new EAL config setting ``max_simd_bitwidth`` to limit the vector
+  path selection at runtime. This value can be set by apps using the
+  ``rte_vect_set_max_simd_bitwidth`` function, or by the user with EAL flag
+  ``--force-max-simd-bitwidth``.
+
 * **Updated CRC modules of the net library.**
 
   * Added runtime selection of the optimal architecture-specific CRC path.
index f6a455b..a739e6e 100644 (file)
@@ -14,6 +14,8 @@
 extern "C" {
 #endif
 
+#define RTE_VECT_DEFAULT_SIMD_BITWIDTH RTE_VECT_SIMD_MAX
+
 typedef int32x4_t xmm_t;
 
 #define        XMM_SIZE        (sizeof(xmm_t))
index a5426e1..60f0e4c 100644 (file)
@@ -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_VECT_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_VECT_SIMD_MAX)
+               return -1;
+
+       if (bitwidth == 0)
+               bitwidth = (unsigned long) RTE_VECT_SIMD_MAX;
+       ret = rte_vect_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_vect_get_max_simd_bitwidth(void)
+{
+       const struct internal_config *internal_conf =
+               eal_get_internal_configuration();
+       return internal_conf->max_simd_bitwidth.bitwidth;
+}
+
+int
+rte_vect_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_VECT_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"
index de627c7..51dbe86 100644 (file)
@@ -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);
index 89769d4..ef33979 100644 (file)
@@ -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
 };
 
index 3fc4797..3fec2bf 100644 (file)
@@ -7,13 +7,16 @@
 
 /**
  * @file
- * SIMD vector types
+ * SIMD vector types and control
  *
- * This file defines types to use vector instructions with generic C code.
+ * This file defines types to use vector instructions with generic C code
+ * and APIs to enable the code using them.
  */
 
 #include <stdint.h>
 
+#include <rte_compat.h>
+
 /* Unsigned vector types */
 
 /**
@@ -183,4 +186,50 @@ typedef int32_t rte_v256s32_t __attribute__((vector_size(32), aligned(32)));
  */
 typedef int64_t rte_v256s64_t __attribute__((vector_size(32), aligned(32)));
 
+/**
+ * The max SIMD bitwidth value to limit vector path selection.
+ */
+enum rte_vect_max_simd {
+       RTE_VECT_SIMD_DISABLED = 64,
+       /**< Limits path selection to scalar, disables all vector paths. */
+       RTE_VECT_SIMD_128 = 128,
+       /**< Limits path selection to SSE/NEON/Altivec or below. */
+       RTE_VECT_SIMD_256 = 256, /**< Limits path selection to AVX2 or below. */
+       RTE_VECT_SIMD_512 = 512, /**< Limits path selection to AVX512 or below. */
+       RTE_VECT_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.
+        */
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Get the supported SIMD bitwidth.
+ *
+ * @return
+ *   uint16_t bitwidth.
+ */
+__rte_experimental
+uint16_t rte_vect_get_max_simd_bitwidth(void);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * 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_vect_set_max_simd_bitwidth(uint16_t bitwidth);
+
 #endif /* _RTE_VECT_H_ */
index b0545c8..c1f0b06 100644 (file)
@@ -15,6 +15,8 @@
 extern "C" {
 #endif
 
+#define RTE_VECT_DEFAULT_SIMD_BITWIDTH RTE_VECT_SIMD_256
+
 typedef vector signed int xmm_t;
 
 #define        XMM_SIZE        (sizeof(xmm_t))
index 975acb8..7eab9fb 100644 (file)
@@ -303,6 +303,9 @@ EXPORTS
        rte_thread_register
        rte_thread_unregister
 
+       rte_vect_get_max_simd_bitwidth
+       rte_vect_set_max_simd_bitwidth
+
        rte_mem_lock
        rte_mem_map
        rte_mem_page_size
index df8e0af..a625ca2 100644 (file)
@@ -400,6 +400,8 @@ EXPERIMENTAL {
        __rte_eal_trace_generic_size_t;
        rte_epoll_wait_interruptible;
        rte_service_lcore_may_be_active;
+       rte_vect_get_max_simd_bitwidth;
+       rte_vect_set_max_simd_bitwidth;
 };
 
 INTERNAL {
index 64383c3..2e40b77 100644 (file)
@@ -36,6 +36,8 @@
 extern "C" {
 #endif
 
+#define RTE_VECT_DEFAULT_SIMD_BITWIDTH RTE_VECT_SIMD_256
+
 typedef __m128i xmm_t;
 
 #define        XMM_SIZE        (sizeof(xmm_t))