Currently, power intrinsics are inline functions. Make them part of the
ABI so that we can have various internal data associated with them
without exposing said data to the outside world.

Signed-off-by: Anatoly Burakov <anatoly.bura...@intel.com>
---
 .../arm/include/rte_power_intrinsics.h        |   6 +-
 .../include/generic/rte_power_intrinsics.h    |   6 +-
 .../ppc/include/rte_power_intrinsics.h        |   6 +-
 lib/librte_eal/version.map                    |   5 +
 .../x86/include/rte_power_intrinsics.h        | 115 -----------------
 lib/librte_eal/x86/meson.build                |   1 +
 lib/librte_eal/x86/rte_power_intrinsics.c     | 120 ++++++++++++++++++
 7 files changed, 135 insertions(+), 124 deletions(-)
 create mode 100644 lib/librte_eal/x86/rte_power_intrinsics.c

diff --git a/lib/librte_eal/arm/include/rte_power_intrinsics.h 
b/lib/librte_eal/arm/include/rte_power_intrinsics.h
index a4a1bc1159..5e384d380e 100644
--- a/lib/librte_eal/arm/include/rte_power_intrinsics.h
+++ b/lib/librte_eal/arm/include/rte_power_intrinsics.h
@@ -16,7 +16,7 @@ extern "C" {
 /**
  * This function is not supported on ARM.
  */
-static inline void
+void
 rte_power_monitor(const volatile void *p, const uint64_t expected_value,
                const uint64_t value_mask, const uint64_t tsc_timestamp,
                const uint8_t data_sz)
@@ -31,7 +31,7 @@ rte_power_monitor(const volatile void *p, const uint64_t 
expected_value,
 /**
  * This function is not supported on ARM.
  */
-static inline void
+void
 rte_power_monitor_sync(const volatile void *p, const uint64_t expected_value,
                const uint64_t value_mask, const uint64_t tsc_timestamp,
                const uint8_t data_sz, rte_spinlock_t *lck)
@@ -47,7 +47,7 @@ rte_power_monitor_sync(const volatile void *p, const uint64_t 
expected_value,
 /**
  * This function is not supported on ARM.
  */
-static inline void
+void
 rte_power_pause(const uint64_t tsc_timestamp)
 {
        RTE_SET_USED(tsc_timestamp);
diff --git a/lib/librte_eal/include/generic/rte_power_intrinsics.h 
b/lib/librte_eal/include/generic/rte_power_intrinsics.h
index dd520d90fa..67977bd511 100644
--- a/lib/librte_eal/include/generic/rte_power_intrinsics.h
+++ b/lib/librte_eal/include/generic/rte_power_intrinsics.h
@@ -52,7 +52,7 @@
  *   to undefined result.
  */
 __rte_experimental
-static inline void rte_power_monitor(const volatile void *p,
+void rte_power_monitor(const volatile void *p,
                const uint64_t expected_value, const uint64_t value_mask,
                const uint64_t tsc_timestamp, const uint8_t data_sz);
 
@@ -97,7 +97,7 @@ static inline void rte_power_monitor(const volatile void *p,
  *   wakes up.
  */
 __rte_experimental
-static inline void rte_power_monitor_sync(const volatile void *p,
+void rte_power_monitor_sync(const volatile void *p,
                const uint64_t expected_value, const uint64_t value_mask,
                const uint64_t tsc_timestamp, const uint8_t data_sz,
                rte_spinlock_t *lck);
@@ -118,6 +118,6 @@ static inline void rte_power_monitor_sync(const volatile 
void *p,
  *   architecture-dependent.
  */
 __rte_experimental
-static inline void rte_power_pause(const uint64_t tsc_timestamp);
+void rte_power_pause(const uint64_t tsc_timestamp);
 
 #endif /* _RTE_POWER_INTRINSIC_H_ */
diff --git a/lib/librte_eal/ppc/include/rte_power_intrinsics.h 
b/lib/librte_eal/ppc/include/rte_power_intrinsics.h
index 4ed03d521f..4cb5560c02 100644
--- a/lib/librte_eal/ppc/include/rte_power_intrinsics.h
+++ b/lib/librte_eal/ppc/include/rte_power_intrinsics.h
@@ -16,7 +16,7 @@ extern "C" {
 /**
  * This function is not supported on PPC64.
  */
-static inline void
+void
 rte_power_monitor(const volatile void *p, const uint64_t expected_value,
                const uint64_t value_mask, const uint64_t tsc_timestamp,
                const uint8_t data_sz)
@@ -31,7 +31,7 @@ rte_power_monitor(const volatile void *p, const uint64_t 
expected_value,
 /**
  * This function is not supported on PPC64.
  */
-static inline void
+void
 rte_power_monitor_sync(const volatile void *p, const uint64_t expected_value,
                const uint64_t value_mask, const uint64_t tsc_timestamp,
                const uint8_t data_sz, rte_spinlock_t *lck)
@@ -47,7 +47,7 @@ rte_power_monitor_sync(const volatile void *p, const uint64_t 
expected_value,
 /**
  * This function is not supported on PPC64.
  */
-static inline void
+void
 rte_power_pause(const uint64_t tsc_timestamp)
 {
        RTE_SET_USED(tsc_timestamp);
diff --git a/lib/librte_eal/version.map b/lib/librte_eal/version.map
index 354c068f31..31bf76ae81 100644
--- a/lib/librte_eal/version.map
+++ b/lib/librte_eal/version.map
@@ -403,6 +403,11 @@ EXPERIMENTAL {
        rte_service_lcore_may_be_active;
        rte_vect_get_max_simd_bitwidth;
        rte_vect_set_max_simd_bitwidth;
+
+       # added in 21.02
+       rte_power_monitor;
+       rte_power_monitor_sync;
+       rte_power_pause;
 };
 
 INTERNAL {
diff --git a/lib/librte_eal/x86/include/rte_power_intrinsics.h 
b/lib/librte_eal/x86/include/rte_power_intrinsics.h
index c7d790c854..e4c2b87f73 100644
--- a/lib/librte_eal/x86/include/rte_power_intrinsics.h
+++ b/lib/librte_eal/x86/include/rte_power_intrinsics.h
@@ -13,121 +13,6 @@ extern "C" {
 
 #include "generic/rte_power_intrinsics.h"
 
-static inline uint64_t
-__rte_power_get_umwait_val(const volatile void *p, const uint8_t sz)
-{
-       switch (sz) {
-       case sizeof(uint8_t):
-               return *(const volatile uint8_t *)p;
-       case sizeof(uint16_t):
-               return *(const volatile uint16_t *)p;
-       case sizeof(uint32_t):
-               return *(const volatile uint32_t *)p;
-       case sizeof(uint64_t):
-               return *(const volatile uint64_t *)p;
-       default:
-               /* this is an intrinsic, so we can't have any error handling */
-               RTE_ASSERT(0);
-               return 0;
-       }
-}
-
-/**
- * This function uses UMONITOR/UMWAIT instructions and will enter C0.2 state.
- * For more information about usage of these instructions, please refer to
- * Intel(R) 64 and IA-32 Architectures Software Developer's Manual.
- */
-static inline void
-rte_power_monitor(const volatile void *p, const uint64_t expected_value,
-               const uint64_t value_mask, const uint64_t tsc_timestamp,
-               const uint8_t data_sz)
-{
-       const uint32_t tsc_l = (uint32_t)tsc_timestamp;
-       const uint32_t tsc_h = (uint32_t)(tsc_timestamp >> 32);
-       /*
-        * we're using raw byte codes for now as only the newest compiler
-        * versions support this instruction natively.
-        */
-
-       /* set address for UMONITOR */
-       asm volatile(".byte 0xf3, 0x0f, 0xae, 0xf7;"
-                       :
-                       : "D"(p));
-
-       if (value_mask) {
-               const uint64_t cur_value = __rte_power_get_umwait_val(p, 
data_sz);
-               const uint64_t masked = cur_value & value_mask;
-
-               /* if the masked value is already matching, abort */
-               if (masked == expected_value)
-                       return;
-       }
-       /* execute UMWAIT */
-       asm volatile(".byte 0xf2, 0x0f, 0xae, 0xf7;"
-                       : /* ignore rflags */
-                       : "D"(0), /* enter C0.2 */
-                         "a"(tsc_l), "d"(tsc_h));
-}
-
-/**
- * This function uses UMONITOR/UMWAIT instructions and will enter C0.2 state.
- * For more information about usage of these instructions, please refer to
- * Intel(R) 64 and IA-32 Architectures Software Developer's Manual.
- */
-static inline void
-rte_power_monitor_sync(const volatile void *p, const uint64_t expected_value,
-               const uint64_t value_mask, const uint64_t tsc_timestamp,
-               const uint8_t data_sz, rte_spinlock_t *lck)
-{
-       const uint32_t tsc_l = (uint32_t)tsc_timestamp;
-       const uint32_t tsc_h = (uint32_t)(tsc_timestamp >> 32);
-       /*
-        * we're using raw byte codes for now as only the newest compiler
-        * versions support this instruction natively.
-        */
-
-       /* set address for UMONITOR */
-       asm volatile(".byte 0xf3, 0x0f, 0xae, 0xf7;"
-                       :
-                       : "D"(p));
-
-       if (value_mask) {
-               const uint64_t cur_value = __rte_power_get_umwait_val(p, 
data_sz);
-               const uint64_t masked = cur_value & value_mask;
-
-               /* if the masked value is already matching, abort */
-               if (masked == expected_value)
-                       return;
-       }
-       rte_spinlock_unlock(lck);
-
-       /* execute UMWAIT */
-       asm volatile(".byte 0xf2, 0x0f, 0xae, 0xf7;"
-                       : /* ignore rflags */
-                       : "D"(0), /* enter C0.2 */
-                         "a"(tsc_l), "d"(tsc_h));
-
-       rte_spinlock_lock(lck);
-}
-
-/**
- * This function uses TPAUSE instruction  and will enter C0.2 state. For more
- * information about usage of this instruction, please refer to Intel(R) 64 and
- * IA-32 Architectures Software Developer's Manual.
- */
-static inline void
-rte_power_pause(const uint64_t tsc_timestamp)
-{
-       const uint32_t tsc_l = (uint32_t)tsc_timestamp;
-       const uint32_t tsc_h = (uint32_t)(tsc_timestamp >> 32);
-
-       /* execute TPAUSE */
-       asm volatile(".byte 0x66, 0x0f, 0xae, 0xf7;"
-               : /* ignore rflags */
-               : "D"(0), /* enter C0.2 */
-                 "a"(tsc_l), "d"(tsc_h));
-}
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/x86/meson.build b/lib/librte_eal/x86/meson.build
index e78f29002e..dfd42dee0c 100644
--- a/lib/librte_eal/x86/meson.build
+++ b/lib/librte_eal/x86/meson.build
@@ -8,4 +8,5 @@ sources += files(
        'rte_cycles.c',
        'rte_hypervisor.c',
        'rte_spinlock.c',
+       'rte_power_intrinsics.c',
 )
diff --git a/lib/librte_eal/x86/rte_power_intrinsics.c 
b/lib/librte_eal/x86/rte_power_intrinsics.c
new file mode 100644
index 0000000000..34c5fd9c3e
--- /dev/null
+++ b/lib/librte_eal/x86/rte_power_intrinsics.c
@@ -0,0 +1,120 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation
+ */
+
+#include "rte_power_intrinsics.h"
+
+static inline uint64_t
+__get_umwait_val(const volatile void *p, const uint8_t sz)
+{
+       switch (sz) {
+       case sizeof(uint8_t):
+               return *(const volatile uint8_t *)p;
+       case sizeof(uint16_t):
+               return *(const volatile uint16_t *)p;
+       case sizeof(uint32_t):
+               return *(const volatile uint32_t *)p;
+       case sizeof(uint64_t):
+               return *(const volatile uint64_t *)p;
+       default:
+               /* this is an intrinsic, so we can't have any error handling */
+               RTE_ASSERT(0);
+               return 0;
+       }
+}
+
+/**
+ * This function uses UMONITOR/UMWAIT instructions and will enter C0.2 state.
+ * For more information about usage of these instructions, please refer to
+ * Intel(R) 64 and IA-32 Architectures Software Developer's Manual.
+ */
+void
+rte_power_monitor(const volatile void *p, const uint64_t expected_value,
+               const uint64_t value_mask, const uint64_t tsc_timestamp,
+               const uint8_t data_sz)
+{
+       const uint32_t tsc_l = (uint32_t)tsc_timestamp;
+       const uint32_t tsc_h = (uint32_t)(tsc_timestamp >> 32);
+       /*
+        * we're using raw byte codes for now as only the newest compiler
+        * versions support this instruction natively.
+        */
+
+       /* set address for UMONITOR */
+       asm volatile(".byte 0xf3, 0x0f, 0xae, 0xf7;"
+                       :
+                       : "D"(p));
+
+       if (value_mask) {
+               const uint64_t cur_value = __get_umwait_val(p, data_sz);
+               const uint64_t masked = cur_value & value_mask;
+
+               /* if the masked value is already matching, abort */
+               if (masked == expected_value)
+                       return;
+       }
+       /* execute UMWAIT */
+       asm volatile(".byte 0xf2, 0x0f, 0xae, 0xf7;"
+                       : /* ignore rflags */
+                       : "D"(0), /* enter C0.2 */
+                         "a"(tsc_l), "d"(tsc_h));
+}
+
+/**
+ * This function uses UMONITOR/UMWAIT instructions and will enter C0.2 state.
+ * For more information about usage of these instructions, please refer to
+ * Intel(R) 64 and IA-32 Architectures Software Developer's Manual.
+ */
+void
+rte_power_monitor_sync(const volatile void *p, const uint64_t expected_value,
+               const uint64_t value_mask, const uint64_t tsc_timestamp,
+               const uint8_t data_sz, rte_spinlock_t *lck)
+{
+       const uint32_t tsc_l = (uint32_t)tsc_timestamp;
+       const uint32_t tsc_h = (uint32_t)(tsc_timestamp >> 32);
+       /*
+        * we're using raw byte codes for now as only the newest compiler
+        * versions support this instruction natively.
+        */
+
+       /* set address for UMONITOR */
+       asm volatile(".byte 0xf3, 0x0f, 0xae, 0xf7;"
+                       :
+                       : "D"(p));
+
+       if (value_mask) {
+               const uint64_t cur_value = __get_umwait_val(p, data_sz);
+               const uint64_t masked = cur_value & value_mask;
+
+               /* if the masked value is already matching, abort */
+               if (masked == expected_value)
+                       return;
+       }
+       rte_spinlock_unlock(lck);
+
+       /* execute UMWAIT */
+       asm volatile(".byte 0xf2, 0x0f, 0xae, 0xf7;"
+                       : /* ignore rflags */
+                       : "D"(0), /* enter C0.2 */
+                         "a"(tsc_l), "d"(tsc_h));
+
+       rte_spinlock_lock(lck);
+}
+
+/**
+ * This function uses TPAUSE instruction  and will enter C0.2 state. For more
+ * information about usage of this instruction, please refer to Intel(R) 64 and
+ * IA-32 Architectures Software Developer's Manual.
+ */
+void
+rte_power_pause(const uint64_t tsc_timestamp)
+{
+       const uint32_t tsc_l = (uint32_t)tsc_timestamp;
+       const uint32_t tsc_h = (uint32_t)(tsc_timestamp >> 32);
+
+       /* execute TPAUSE */
+       asm volatile(".byte 0x66, 0x0f, 0xae, 0xf7;"
+                       : /* ignore rflags */
+                       : "D"(0), /* enter C0.2 */
+                       "a"(tsc_l), "d"(tsc_h));
+}
-- 
2.17.1

Reply via email to