]> git.droids-corp.org - dpdk.git/commitdiff
eal: add intrinsics support check infrastructure
authorLiang Ma <liang.j.ma@intel.com>
Tue, 27 Oct 2020 14:59:03 +0000 (14:59 +0000)
committerThomas Monjalon <thomas@monjalon.net>
Thu, 29 Oct 2020 21:46:31 +0000 (22:46 +0100)
Currently, it is not possible to check support for intrinsics that
are platform-specific, cannot be abstracted in a generic way, or do not
have support on all architectures. The CPUID flags can be used to some
extent, but they are only defined for their platform, while intrinsics
will be available to all code as they are in generic headers.

This patch introduces infrastructure to check support for certain
platform-specific intrinsics, and adds support for checking support for
IA power management-related intrinsics for UMWAIT/UMONITOR and TPAUSE.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Signed-off-by: Liang Ma <liang.j.ma@intel.com>
Acked-by: David Christensen <drc@linux.vnet.ibm.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
Acked-by: Ruifeng Wang <ruifeng.wang@arm.com>
Acked-by: Ray Kinsella <mdr@ashroe.eu>
lib/librte_eal/arm/rte_cpuflags.c
lib/librte_eal/include/generic/rte_cpuflags.h
lib/librte_eal/include/generic/rte_power_intrinsics.h
lib/librte_eal/ppc/rte_cpuflags.c
lib/librte_eal/version.map
lib/librte_eal/x86/rte_cpuflags.c

index 7b257b7873fb71b23c3f712e59467784ea29cb84..e3a53bcece5bcc3c453f0c61c128281064e62c3d 100644 (file)
@@ -151,3 +151,9 @@ rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
                return NULL;
        return rte_cpu_feature_table[feature].name;
 }
+
+void
+rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics)
+{
+       memset(intrinsics, 0, sizeof(*intrinsics));
+}
index 872f0ebe3e5337b327b4985b500e69df871e177e..28a5aecde89db11431de86a5ba2de516be4f62eb 100644 (file)
 #include "rte_common.h"
 #include <errno.h>
 
+#include <rte_compat.h>
+
+/**
+ * Structure used to describe platform-specific intrinsics that may or may not
+ * be supported at runtime.
+ */
+struct rte_cpu_intrinsics {
+       uint32_t power_monitor : 1;
+       /**< indicates support for rte_power_monitor function */
+       uint32_t power_pause : 1;
+       /**< indicates support for rte_power_pause function */
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Check CPU support for various intrinsics at runtime.
+ *
+ * @param intrinsics
+ *     Pointer to a structure to be filled.
+ */
+__rte_experimental
+void
+rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics);
+
 /**
  * Enumeration of all CPU features supported
  */
index fb897d9060cd7158654f07f5c9e1382c4c33bb34..9622c7f9ce355cf90d2da49eb24d574906ffbd6a 100644 (file)
  * checked against the expected value, and if they match, the entering of
  * optimized power state may be aborted.
  *
+ * @warning It is responsibility of the user to check if this function is
+ *   supported at runtime using `rte_cpu_get_features()` API call.
+ *   Failing to do so may result in an illegal CPU instruction error.
+ *
  * @param p
  *   Address to monitor for changes.
  * @param expected_value
@@ -69,6 +73,10 @@ static inline void rte_power_monitor(const volatile void *p,
  * This call will also lock a spinlock on entering sleep, and release it on
  * waking up the CPU.
  *
+ * @warning It is responsibility of the user to check if this function is
+ *   supported at runtime using `rte_cpu_get_features()` API call.
+ *   Failing to do so may result in an illegal CPU instruction error.
+ *
  * @param p
  *   Address to monitor for changes.
  * @param expected_value
@@ -101,6 +109,10 @@ static inline void rte_power_monitor_sync(const volatile void *p,
  * Enter an architecture-defined optimized power state until a certain TSC
  * timestamp is reached.
  *
+ * @warning It is responsibility of the user to check if this function is
+ *   supported at runtime using `rte_cpu_get_features()` API call.
+ *   Failing to do so may result in an illegal CPU instruction error.
+ *
  * @param tsc_timestamp
  *   Maximum TSC timestamp to wait for. Note that the wait behavior is
  *   architecture-dependent.
index 3bb7563ce93c72eec6d54ff59d0026bc5a9dc66c..61db5c216d72742b72252c72f95e2d6734e0c393 100644 (file)
@@ -8,6 +8,7 @@
 #include <elf.h>
 #include <fcntl.h>
 #include <assert.h>
+#include <string.h>
 #include <unistd.h>
 
 /* Symbolic values for the entries in the auxiliary table */
@@ -108,3 +109,9 @@ rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
                return NULL;
        return rte_cpu_feature_table[feature].name;
 }
+
+void
+rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics)
+{
+       memset(intrinsics, 0, sizeof(*intrinsics));
+}
index c23ff57ce611a2c1eb00582725610930c4f93eb3..354c068f318847be5b65dd8e59264361bfc664f0 100644 (file)
@@ -398,6 +398,7 @@ EXPERIMENTAL {
 
        # added in 20.11
        __rte_eal_trace_generic_size_t;
+       rte_cpu_get_intrinsics_support;
        rte_epoll_wait_interruptible;
        rte_service_lcore_may_be_active;
        rte_vect_get_max_simd_bitwidth;
index 0325c4b93b9d49884353934403cebf2d6d12fd6c..a96312ff7fd9ddbeb0cc8ab1f9a4370506cee34c 100644 (file)
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <stdint.h>
+#include <string.h>
 
 #include "rte_cpuid.h"
 
@@ -179,3 +180,14 @@ rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
                return NULL;
        return rte_cpu_feature_table[feature].name;
 }
+
+void
+rte_cpu_get_intrinsics_support(struct rte_cpu_intrinsics *intrinsics)
+{
+       memset(intrinsics, 0, sizeof(*intrinsics));
+
+       if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_WAITPKG)) {
+               intrinsics->power_monitor = 1;
+               intrinsics->power_pause = 1;
+       }
+}