Only use the "avx512vbmi" compiler target when it is actually supported
by the compiler.

The order of mfex_impls and the 'dpif_miniflow_extract_impl_idx' enum
have to be changed to keep the start index and size of the impl list
correct in both VBMI and non VBMI cases.

Signed-off-by: Cian Ferriter <cian.ferri...@intel.com>

---

v2:
* Don't register vbmi specialized mfex impls unless VBMI is actually
  available.
  * This required some re-ordering of the mfex impl lists.
---
 acinclude.m4                      | 14 +++++++++++
 configure.ac                      |  1 +
 lib/dpif-netdev-extract-avx512.c  | 23 ++++++++++++++---
 lib/dpif-netdev-private-extract.c | 41 ++++++++++++++++---------------
 lib/dpif-netdev-private-extract.h | 12 +++++----
 5 files changed, 63 insertions(+), 28 deletions(-)

diff --git a/acinclude.m4 b/acinclude.m4
index 932ff4693..31033edca 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -100,6 +100,20 @@ AC_DEFUN([OVS_CHECK_AVX512BW_DQ], [
   fi
 ])
 
+dnl OVS_CHECK_AVX512VBMI
+dnl
+dnl Checks if compiler supports AVX512VBMI instructions.
+AC_DEFUN([OVS_CHECK_AVX512VBMI], [
+  OVS_CHECK_CC_OPTION(
+    [-mavx512vbmi], [ovs_have_cc_mavx512vbmi=yes],
+    [ovs_have_cc_mavx512vbmi=no])
+  AM_CONDITIONAL([HAVE_AVX512VBMI], [test $ovs_have_cc_mavx512vbmi = yes])
+  if test "$ovs_have_cc_mavx512vbmi" = yes; then
+    AC_DEFINE([HAVE_AVX512VBMI], [1],
+              [Define to 1 if compiler supports AVX512VBMI.])
+  fi
+])
+
 dnl OVS_ENABLE_WERROR
 AC_DEFUN([OVS_ENABLE_WERROR],
   [AC_ARG_ENABLE(
diff --git a/configure.ac b/configure.ac
index f849837e0..12b4010e5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -188,6 +188,7 @@ OVS_CHECK_DPIF_AVX512_DEFAULT
 OVS_CHECK_MFEX_AUTOVALIDATOR
 OVS_CHECK_AVX512
 OVS_CHECK_AVX512BW_DQ
+OVS_CHECK_AVX512VBMI
 
 AC_ARG_VAR(KARCH, [Kernel Architecture String])
 AC_SUBST(KARCH)
diff --git a/lib/dpif-netdev-extract-avx512.c b/lib/dpif-netdev-extract-avx512.c
index f36a6eab0..5d62f3607 100644
--- a/lib/dpif-netdev-extract-avx512.c
+++ b/lib/dpif-netdev-extract-avx512.c
@@ -110,7 +110,9 @@ _mm512_maskz_permutex2var_epi8_skx(__mmask64 k_mask,
 
 /* Wrapper function required to enable ISA. */
 static inline __m512i
+#if HAVE_AVX512VBMI
 __attribute__((__target__("avx512vbmi")))
+#endif
 _mm512_maskz_permutexvar_epi8_wrap(__mmask64 kmask, __m512i idx, __m512i a)
 {
     return _mm512_maskz_permutexvar_epi8(kmask, idx, a);
@@ -481,7 +483,7 @@ mfex_avx512_process(struct dp_packet_batch *packets,
                     odp_port_t in_port,
                     void *pmd_handle OVS_UNUSED,
                     const enum MFEX_PROFILES profile_id,
-                    const uint32_t use_vbmi)
+                    const uint32_t use_vbmi OVS_UNUSED)
 {
     uint32_t hitmask = 0;
     struct dp_packet *packet;
@@ -544,7 +546,11 @@ mfex_avx512_process(struct dp_packet_batch *packets,
          */
         __m512i v512_zeros = _mm512_setzero_si512();
         __m512i v_blk0;
+#if HAVE_AVX512VBMI
         if (__builtin_constant_p(use_vbmi) && use_vbmi) {
+#else
+        if (0) {
+#endif
             v_blk0 = _mm512_maskz_permutexvar_epi8_wrap(k_shuf, v_shuf,
                                                         v_pkt0);
         } else {
@@ -626,7 +632,9 @@ mfex_avx512_process(struct dp_packet_batch *packets,
 }
 
 
-#define DECLARE_MFEX_FUNC(name, profile)                                \
+#if HAVE_AVX512VBMI
+#define VBMI_MFEX_FUNC(name, profile)                                   \
+                                                                        \
 uint32_t                                                                \
 __attribute__((__target__("avx512f")))                                  \
 __attribute__((__target__("avx512vbmi")))                               \
@@ -637,7 +645,12 @@ mfex_avx512_vbmi_##name(struct dp_packet_batch *packets,   
             \
 {                                                                       \
     return mfex_avx512_process(packets, keys, keys_size, in_port,       \
                                pmd_handle, profile, 1);                 \
-}                                                                       \
+}
+#else
+#define VBMI_MFEX_FUNC(name, profile)
+#endif
+
+#define BASIC_MFEX_FUNC(name, profile)                                  \
                                                                         \
 uint32_t                                                                \
 __attribute__((__target__("avx512f")))                                  \
@@ -650,6 +663,10 @@ mfex_avx512_##name(struct dp_packet_batch *packets,        
             \
                                pmd_handle, profile, 0);                 \
 }
 
+#define DECLARE_MFEX_FUNC(name, profile)                                \
+VBMI_MFEX_FUNC(name, profile)                                           \
+BASIC_MFEX_FUNC(name, profile)                                          \
+
 /* Each profile gets a single declare here, which specializes the function
  * as required.
  */
diff --git a/lib/dpif-netdev-private-extract.c 
b/lib/dpif-netdev-private-extract.c
index 43b8b824e..ea2b03e5c 100644
--- a/lib/dpif-netdev-private-extract.c
+++ b/lib/dpif-netdev-private-extract.c
@@ -56,45 +56,46 @@ static struct dpif_miniflow_extract_impl mfex_impls[] = {
 /* Compile in implementations only if the compiler ISA checks pass. */
 #if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && HAVE_AVX512BW_DQ \
      && __SSE4_2__)
-    [MFEX_IMPL_VBMI_IPv4_UDP] = {
-        .probe = mfex_avx512_vbmi_probe,
-        .extract_func = mfex_avx512_vbmi_ip_udp,
-        .name = "avx512_vbmi_ipv4_udp", },
-
     [MFEX_IMPL_IPv4_UDP] = {
         .probe = mfex_avx512_probe,
         .extract_func = mfex_avx512_ip_udp,
         .name = "avx512_ipv4_udp", },
 
-    [MFEX_IMPL_VBMI_IPv4_TCP] = {
-        .probe = mfex_avx512_vbmi_probe,
-        .extract_func = mfex_avx512_vbmi_ip_tcp,
-        .name = "avx512_vbmi_ipv4_tcp", },
-
     [MFEX_IMPL_IPv4_TCP] = {
         .probe = mfex_avx512_probe,
         .extract_func = mfex_avx512_ip_tcp,
         .name = "avx512_ipv4_tcp", },
 
-    [MFEX_IMPL_VBMI_DOT1Q_IPv4_UDP] = {
-        .probe = mfex_avx512_vbmi_probe,
-        .extract_func = mfex_avx512_vbmi_dot1q_ip_udp,
-        .name = "avx512_vbmi_dot1q_ipv4_udp", },
-
     [MFEX_IMPL_DOT1Q_IPv4_UDP] = {
         .probe = mfex_avx512_probe,
         .extract_func = mfex_avx512_dot1q_ip_udp,
         .name = "avx512_dot1q_ipv4_udp", },
 
-    [MFEX_IMPL_VBMI_DOT1Q_IPv4_TCP] = {
-        .probe = mfex_avx512_vbmi_probe,
-        .extract_func = mfex_avx512_vbmi_dot1q_ip_tcp,
-        .name = "avx512_vbmi_dot1q_ipv4_tcp", },
-
     [MFEX_IMPL_DOT1Q_IPv4_TCP] = {
         .probe = mfex_avx512_probe,
         .extract_func = mfex_avx512_dot1q_ip_tcp,
         .name = "avx512_dot1q_ipv4_tcp", },
+#if HAVE_AVX512VBMI
+    [MFEX_IMPL_VBMI_IPv4_UDP] = {
+        .probe = mfex_avx512_vbmi_probe,
+        .extract_func = mfex_avx512_vbmi_ip_udp,
+        .name = "avx512_vbmi_ipv4_udp", },
+
+    [MFEX_IMPL_VBMI_IPv4_TCP] = {
+        .probe = mfex_avx512_vbmi_probe,
+        .extract_func = mfex_avx512_vbmi_ip_tcp,
+        .name = "avx512_vbmi_ipv4_tcp", },
+
+    [MFEX_IMPL_VBMI_DOT1Q_IPv4_UDP] = {
+        .probe = mfex_avx512_vbmi_probe,
+        .extract_func = mfex_avx512_vbmi_dot1q_ip_udp,
+        .name = "avx512_vbmi_dot1q_ipv4_udp", },
+
+    [MFEX_IMPL_VBMI_DOT1Q_IPv4_TCP] = {
+        .probe = mfex_avx512_vbmi_probe,
+        .extract_func = mfex_avx512_vbmi_dot1q_ip_tcp,
+        .name = "avx512_vbmi_dot1q_ipv4_tcp", },
+#endif
 #endif
 };
 
diff --git a/lib/dpif-netdev-private-extract.h 
b/lib/dpif-netdev-private-extract.h
index bbb80ddca..ea1d03918 100644
--- a/lib/dpif-netdev-private-extract.h
+++ b/lib/dpif-netdev-private-extract.h
@@ -83,14 +83,16 @@ enum dpif_miniflow_extract_impl_idx {
     MFEX_IMPL_STUDY,
 #if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && HAVE_AVX512BW_DQ \
      && __SSE4_2__)
-    MFEX_IMPL_VBMI_IPv4_UDP,
     MFEX_IMPL_IPv4_UDP,
-    MFEX_IMPL_VBMI_IPv4_TCP,
     MFEX_IMPL_IPv4_TCP,
-    MFEX_IMPL_VBMI_DOT1Q_IPv4_UDP,
     MFEX_IMPL_DOT1Q_IPv4_UDP,
-    MFEX_IMPL_VBMI_DOT1Q_IPv4_TCP,
     MFEX_IMPL_DOT1Q_IPv4_TCP,
+#if HAVE_AVX512VBMI
+    MFEX_IMPL_VBMI_IPv4_UDP,
+    MFEX_IMPL_VBMI_IPv4_TCP,
+    MFEX_IMPL_VBMI_DOT1Q_IPv4_UDP,
+    MFEX_IMPL_VBMI_DOT1Q_IPv4_TCP,
+#endif
 #endif
     MFEX_IMPL_MAX
 };
@@ -103,7 +105,7 @@ extern struct ovs_mutex dp_netdev_mutex;
 #if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && HAVE_AVX512BW_DQ \
      && __SSE4_2__)
 
-#define MFEX_IMPL_START_IDX MFEX_IMPL_VBMI_IPv4_UDP
+#define MFEX_IMPL_START_IDX MFEX_IMPL_IPv4_UDP
 #else
 
 #define MFEX_IMPL_START_IDX MFEX_IMPL_MAX
-- 
2.25.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to