From 4a01538cc9bdd55cfd5b26b4a0998a33e89ba878 Mon Sep 17 00:00:00 2001 From: Open vSwitch CI Date: Jun 29 2022 20:03:07 +0000 Subject: Import openvswitch2.16-2.16.0-85 from Fast DataPath --- diff --git a/SOURCES/openvswitch-2.16.0.patch b/SOURCES/openvswitch-2.16.0.patch index 13825ed..6a23fe8 100644 --- a/SOURCES/openvswitch-2.16.0.patch +++ b/SOURCES/openvswitch-2.16.0.patch @@ -1839,11 +1839,43 @@ index b7d577870d..fe24f9abdf 100644 "cannot use CPU flag based optimizations"); return false; } +diff --git a/lib/dpif-netdev-avx512.c b/lib/dpif-netdev-avx512.c +index 544d36903e..01011f679a 100644 +--- a/lib/dpif-netdev-avx512.c ++++ b/lib/dpif-netdev-avx512.c +@@ -58,19 +58,6 @@ struct dpif_userdata { + struct pkt_flow_meta pkt_meta[NETDEV_MAX_BURST]; + }; + +-int32_t +-dp_netdev_input_outer_avx512_probe(void) +-{ +- bool avx512f_available = dpdk_get_cpu_has_isa("x86_64", "avx512f"); +- bool bmi2_available = dpdk_get_cpu_has_isa("x86_64", "bmi2"); +- +- if (!avx512f_available || !bmi2_available) { +- return -ENOTSUP; +- } +- +- return 0; +-} +- + int32_t + dp_netdev_input_outer_avx512(struct dp_netdev_pmd_thread *pmd, + struct dp_packet_batch *packets, diff --git a/lib/dpif-netdev-extract-avx512.c b/lib/dpif-netdev-extract-avx512.c -index ec64419e38..28b54ef2f1 100644 +index ec64419e38..993d07e401 100644 --- a/lib/dpif-netdev-extract-avx512.c +++ b/lib/dpif-netdev-extract-avx512.c -@@ -157,10 +157,19 @@ _mm512_maskz_permutexvar_epi8_wrap(__mmask64 kmask, __m512i idx, __m512i a) +@@ -43,7 +43,6 @@ + #include + + #include "flow.h" +-#include "dpdk.h" + + #include "dpif-netdev-private-dpcls.h" + #include "dpif-netdev-private-extract.h" +@@ -157,10 +156,19 @@ _mm512_maskz_permutexvar_epi8_wrap(__mmask64 kmask, __m512i idx, __m512i a) 0, 0, 0, 0, /* Src IP */ \ 0, 0, 0, 0, /* Dst IP */ @@ -1864,7 +1896,7 @@ index ec64419e38..28b54ef2f1 100644 #define NU 0 #define PATTERN_IPV4_UDP_SHUFFLE \ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, NU, NU, /* Ether */ \ -@@ -217,6 +226,25 @@ _mm512_maskz_permutexvar_epi8_wrap(__mmask64 kmask, __m512i idx, __m512i a) +@@ -217,6 +225,25 @@ _mm512_maskz_permutexvar_epi8_wrap(__mmask64 kmask, __m512i idx, __m512i a) #define PATTERN_DT1Q_IPV4_TCP_KMASK \ (KMASK_ETHER | (KMASK_DT1Q << 16) | (KMASK_IPV4 << 24) | (KMASK_TCP << 40)) @@ -1890,7 +1922,7 @@ index ec64419e38..28b54ef2f1 100644 /* This union allows initializing static data as u8, but easily loading it * into AVX512 registers too. The union ensures proper alignment for the zmm. */ -@@ -241,8 +269,9 @@ struct mfex_profile { +@@ -241,8 +268,9 @@ struct mfex_profile { union mfex_data probe_mask; union mfex_data probe_data; @@ -1901,7 +1933,7 @@ index ec64419e38..28b54ef2f1 100644 __mmask64 store_kmsk; /* Constant data to set in mf.bits and dp_packet data on hit. */ -@@ -310,6 +339,7 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = +@@ -310,6 +338,7 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = .probe_data.u8_data = { PATTERN_ETHERTYPE_IPV4 PATTERN_IPV4_UDP}, .store_shuf.u8_data = { PATTERN_IPV4_UDP_SHUFFLE }, @@ -1909,7 +1941,7 @@ index ec64419e38..28b54ef2f1 100644 .store_kmsk = PATTERN_IPV4_UDP_KMASK, .mf_bits = { 0x18a0000000000000, 0x0000000000040401}, -@@ -320,10 +350,19 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = +@@ -320,10 +349,19 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = }, [PROFILE_ETH_IPV4_TCP] = { @@ -1931,7 +1963,7 @@ index ec64419e38..28b54ef2f1 100644 .store_kmsk = PATTERN_IPV4_TCP_KMASK, .mf_bits = { 0x18a0000000000000, 0x0000000000044401}, -@@ -342,6 +381,7 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = +@@ -342,6 +380,7 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = }, .store_shuf.u8_data = { PATTERN_DT1Q_IPV4_UDP_SHUFFLE }, @@ -1939,7 +1971,7 @@ index ec64419e38..28b54ef2f1 100644 .store_kmsk = PATTERN_DT1Q_IPV4_UDP_KMASK, .mf_bits = { 0x38a0000000000000, 0x0000000000040401}, -@@ -353,20 +393,27 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = +@@ -353,20 +392,27 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = [PROFILE_ETH_VLAN_IPV4_TCP] = { .probe_mask.u8_data = { @@ -1970,7 +2002,7 @@ index ec64419e38..28b54ef2f1 100644 }, }; -@@ -374,16 +421,31 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = +@@ -374,16 +420,31 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = /* Protocol specific helper functions, for calculating offsets/lenghts. */ static int32_t mfex_ipv4_set_l2_pad_size(struct dp_packet *pkt, struct ip_header *nh, @@ -2011,7 +2043,7 @@ index ec64419e38..28b54ef2f1 100644 } /* Fixup the VLAN CFI and PCP, reading the PCP from the input to this function, -@@ -433,6 +495,7 @@ mfex_avx512_process(struct dp_packet_batch *packets, +@@ -433,6 +494,7 @@ mfex_avx512_process(struct dp_packet_batch *packets, __m512i v_vals = _mm512_loadu_si512(&profile->probe_data); __m512i v_mask = _mm512_loadu_si512(&profile->probe_mask); __m512i v_shuf = _mm512_loadu_si512(&profile->store_shuf); @@ -2019,7 +2051,7 @@ index ec64419e38..28b54ef2f1 100644 __mmask64 k_shuf = profile->store_kmsk; __m128i v_bits = _mm_loadu_si128((void *) &profile->mf_bits); -@@ -450,10 +513,17 @@ mfex_avx512_process(struct dp_packet_batch *packets, +@@ -450,10 +512,17 @@ mfex_avx512_process(struct dp_packet_batch *packets, /* Load packet data and probe with AVX512 mask & compare. */ const uint8_t *pkt = dp_packet_data(packet); @@ -2039,7 +2071,7 @@ index ec64419e38..28b54ef2f1 100644 continue; } -@@ -474,15 +544,20 @@ mfex_avx512_process(struct dp_packet_batch *packets, +@@ -474,15 +543,20 @@ mfex_avx512_process(struct dp_packet_batch *packets, */ __m512i v512_zeros = _mm512_setzero_si512(); __m512i v_blk0; @@ -2061,7 +2093,7 @@ index ec64419e38..28b54ef2f1 100644 /* Perform "post-processing" per profile, handling details not easily * handled in the above generic AVX512 code. Examples include TCP flag -@@ -498,7 +573,8 @@ mfex_avx512_process(struct dp_packet_batch *packets, +@@ -498,7 +572,8 @@ mfex_avx512_process(struct dp_packet_batch *packets, uint32_t size_from_ipv4 = size - VLAN_ETH_HEADER_LEN; struct ip_header *nh = (void *)&pkt[VLAN_ETH_HEADER_LEN]; @@ -2071,7 +2103,7 @@ index ec64419e38..28b54ef2f1 100644 continue; } -@@ -512,7 +588,8 @@ mfex_avx512_process(struct dp_packet_batch *packets, +@@ -512,7 +587,8 @@ mfex_avx512_process(struct dp_packet_batch *packets, uint32_t size_from_ipv4 = size - VLAN_ETH_HEADER_LEN; struct ip_header *nh = (void *)&pkt[VLAN_ETH_HEADER_LEN]; @@ -2081,7 +2113,7 @@ index ec64419e38..28b54ef2f1 100644 continue; } } break; -@@ -525,7 +602,8 @@ mfex_avx512_process(struct dp_packet_batch *packets, +@@ -525,7 +601,8 @@ mfex_avx512_process(struct dp_packet_batch *packets, /* Handle dynamic l2_pad_size. */ uint32_t size_from_ipv4 = size - sizeof(struct eth_header); struct ip_header *nh = (void *)&pkt[sizeof(struct eth_header)]; @@ -2091,7 +2123,7 @@ index ec64419e38..28b54ef2f1 100644 continue; } } break; -@@ -534,7 +612,8 @@ mfex_avx512_process(struct dp_packet_batch *packets, +@@ -534,7 +611,8 @@ mfex_avx512_process(struct dp_packet_batch *packets, /* Handle dynamic l2_pad_size. */ uint32_t size_from_ipv4 = size - sizeof(struct eth_header); struct ip_header *nh = (void *)&pkt[sizeof(struct eth_header)]; @@ -2101,6 +2133,118 @@ index ec64419e38..28b54ef2f1 100644 continue; } +@@ -584,47 +662,5 @@ DECLARE_MFEX_FUNC(ip_udp, PROFILE_ETH_IPV4_UDP) + DECLARE_MFEX_FUNC(ip_tcp, PROFILE_ETH_IPV4_TCP) + DECLARE_MFEX_FUNC(dot1q_ip_udp, PROFILE_ETH_VLAN_IPV4_UDP) + DECLARE_MFEX_FUNC(dot1q_ip_tcp, PROFILE_ETH_VLAN_IPV4_TCP) +- +- +-static int32_t +-avx512_isa_probe(uint32_t needs_vbmi) +-{ +- static const char *isa_required[] = { +- "avx512f", +- "avx512bw", +- "bmi2", +- }; +- +- int32_t ret = 0; +- for (uint32_t i = 0; i < ARRAY_SIZE(isa_required); i++) { +- if (!dpdk_get_cpu_has_isa("x86_64", isa_required[i])) { +- ret = -ENOTSUP; +- } +- } +- +- if (needs_vbmi) { +- if (!dpdk_get_cpu_has_isa("x86_64", "avx512vbmi")) { +- ret = -ENOTSUP; +- } +- } +- +- return ret; +-} +- +-/* Probe functions to check ISA requirements. */ +-int32_t +-mfex_avx512_probe(void) +-{ +- const uint32_t needs_vbmi = 0; +- return avx512_isa_probe(needs_vbmi); +-} +- +-int32_t +-mfex_avx512_vbmi_probe(void) +-{ +- const uint32_t needs_vbmi = 1; +- return avx512_isa_probe(needs_vbmi); +-} +- + #endif /* __CHECKER__ */ + #endif /* __x86_64__ */ +diff --git a/lib/dpif-netdev-lookup-avx512-gather.c b/lib/dpif-netdev-lookup-avx512-gather.c +index 072831e96a..154f9318d4 100644 +--- a/lib/dpif-netdev-lookup-avx512-gather.c ++++ b/lib/dpif-netdev-lookup-avx512-gather.c +@@ -394,18 +394,11 @@ dpcls_avx512_gather_mf_any(struct dpcls_subtable *subtable, uint32_t keys_map, + } + + dpcls_subtable_lookup_func +-dpcls_subtable_avx512_gather_probe(uint32_t u0_bits, uint32_t u1_bits) ++dpcls_subtable_avx512_gather_probe__(uint32_t u0_bits, uint32_t u1_bits, ++ bool use_vpop) + { + dpcls_subtable_lookup_func f = NULL; + +- int avx512f_available = dpdk_get_cpu_has_isa("x86_64", "avx512f"); +- int bmi2_available = dpdk_get_cpu_has_isa("x86_64", "bmi2"); +- if (!avx512f_available || !bmi2_available) { +- return NULL; +- } +- +- int use_vpop = dpdk_get_cpu_has_isa("x86_64", "avx512vpopcntdq"); +- + CHECK_LOOKUP_FUNCTION(9, 4, use_vpop); + CHECK_LOOKUP_FUNCTION(9, 1, use_vpop); + CHECK_LOOKUP_FUNCTION(5, 3, use_vpop); +diff --git a/lib/dpif-netdev-lookup.c b/lib/dpif-netdev-lookup.c +index bd0a99abe7..5cb52386f2 100644 +--- a/lib/dpif-netdev-lookup.c ++++ b/lib/dpif-netdev-lookup.c +@@ -22,6 +22,20 @@ + + VLOG_DEFINE_THIS_MODULE(dpif_netdev_lookup); + ++#if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && __SSE4_2__) ++static dpcls_subtable_lookup_func ++dpcls_subtable_avx512_gather_probe(uint32_t u0_bits, uint32_t u1_bits) ++{ ++ if (!dpdk_get_cpu_has_isa("x86_64", "avx512f") ++ || !dpdk_get_cpu_has_isa("x86_64", "bmi2")) { ++ return NULL; ++ } ++ ++ return dpcls_subtable_avx512_gather_probe__(u0_bits, u1_bits, ++ dpdk_get_cpu_has_isa("x86_64", "avx512vpopcntdq")); ++} ++#endif ++ + /* Actual list of implementations goes here */ + static struct dpcls_subtable_lookup_info_t subtable_lookups[] = { + /* The autovalidator implementation will not be used by default, it must +diff --git a/lib/dpif-netdev-lookup.h b/lib/dpif-netdev-lookup.h +index 59f51faa0e..5d2d845945 100644 +--- a/lib/dpif-netdev-lookup.h ++++ b/lib/dpif-netdev-lookup.h +@@ -44,7 +44,8 @@ dpcls_subtable_generic_probe(uint32_t u0_bit_count, uint32_t u1_bit_count); + + /* Probe function for AVX-512 gather implementation */ + dpcls_subtable_lookup_func +-dpcls_subtable_avx512_gather_probe(uint32_t u0_bit_cnt, uint32_t u1_bit_cnt); ++dpcls_subtable_avx512_gather_probe__(uint32_t u0_bit_cnt, uint32_t u1_bit_cnt, ++ bool use_vpop); + + + /* Subtable registration and iteration helpers */ diff --git a/lib/dpif-netdev-private-dfc.h b/lib/dpif-netdev-private-dfc.h index 92092ebec9..3dfc91f0fe 100644 --- a/lib/dpif-netdev-private-dfc.h @@ -2132,6 +2276,110 @@ index 7c4a840cb1..0d5da73c7a 100644 /* Caches the masks to match a packet to, reducing runtime calculations. */ uint64_t *mf_masks; +diff --git a/lib/dpif-netdev-private-dpif.c b/lib/dpif-netdev-private-dpif.c +index 84d4ec156e..ac40757281 100644 +--- a/lib/dpif-netdev-private-dpif.c ++++ b/lib/dpif-netdev-private-dpif.c +@@ -33,6 +33,19 @@ enum dpif_netdev_impl_info_idx { + DPIF_NETDEV_IMPL_AVX512 + }; + ++#if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && __SSE4_2__) ++static int32_t ++dp_netdev_input_outer_avx512_probe(void) ++{ ++ if (!dpdk_get_cpu_has_isa("x86_64", "avx512f") ++ || !dpdk_get_cpu_has_isa("x86_64", "bmi2")) { ++ return -ENOTSUP; ++ } ++ ++ return 0; ++} ++#endif ++ + /* Actual list of implementations goes here. */ + static struct dpif_netdev_impl_info_t dpif_impls[] = { + /* The default scalar C code implementation. */ +diff --git a/lib/dpif-netdev-private-dpif.h b/lib/dpif-netdev-private-dpif.h +index 0da639c55a..3e38630f53 100644 +--- a/lib/dpif-netdev-private-dpif.h ++++ b/lib/dpif-netdev-private-dpif.h +@@ -67,10 +67,7 @@ dp_netdev_input(struct dp_netdev_pmd_thread *pmd, + struct dp_packet_batch *packets, + odp_port_t in_port); + +-/* AVX512 enabled DPIF implementation and probe functions. */ +-int32_t +-dp_netdev_input_outer_avx512_probe(void); +- ++/* AVX512 enabled DPIF implementation function. */ + int32_t + dp_netdev_input_outer_avx512(struct dp_netdev_pmd_thread *pmd, + struct dp_packet_batch *packets, +diff --git a/lib/dpif-netdev-private-extract.c b/lib/dpif-netdev-private-extract.c +index 7a06dbf6fd..245d1c0cad 100644 +--- a/lib/dpif-netdev-private-extract.c ++++ b/lib/dpif-netdev-private-extract.c +@@ -33,6 +33,43 @@ VLOG_DEFINE_THIS_MODULE(dpif_netdev_extract); + /* Variable to hold the default MFEX implementation. */ + static ATOMIC(miniflow_extract_func) default_mfex_func; + ++#if (__x86_64__ && HAVE_AVX512F && HAVE_LD_AVX512_GOOD && __SSE4_2__) ++static int32_t ++avx512_isa_probe(bool needs_vbmi) ++{ ++ static const char *isa_required[] = { ++ "avx512f", ++ "avx512bw", ++ "bmi2", ++ }; ++ ++ for (uint32_t i = 0; i < ARRAY_SIZE(isa_required); i++) { ++ if (!dpdk_get_cpu_has_isa("x86_64", isa_required[i])) { ++ return -ENOTSUP; ++ } ++ } ++ ++ if (needs_vbmi && !dpdk_get_cpu_has_isa("x86_64", "avx512vbmi")) { ++ return -ENOTSUP; ++ } ++ ++ return 0; ++} ++ ++/* Probe functions to check ISA requirements. */ ++static int32_t ++mfex_avx512_probe(void) ++{ ++ return avx512_isa_probe(false); ++} ++ ++static int32_t ++mfex_avx512_vbmi_probe(void) ++{ ++ return avx512_isa_probe(true); ++} ++#endif ++ + /* Implementations of available extract options and + * the implementations are always in order of preference. + */ +diff --git a/lib/dpif-netdev-private-extract.h b/lib/dpif-netdev-private-extract.h +index f9a757ba41..3e06148c5a 100644 +--- a/lib/dpif-netdev-private-extract.h ++++ b/lib/dpif-netdev-private-extract.h +@@ -176,10 +176,8 @@ mfex_study_traffic(struct dp_packet_batch *packets, + int + mfex_set_study_pkt_cnt(uint32_t pkt_cmp_count, const char *name); + +-/* AVX512 MFEX Probe and Implementations functions. */ ++/* AVX512 MFEX Implementation functions. */ + #ifdef __x86_64__ +-int32_t mfex_avx512_probe(void); +-int32_t mfex_avx512_vbmi_probe(void); + + #define DECLARE_AVX512_MFEX_PROTOTYPE(name) \ + uint32_t \ diff --git a/lib/dpif-netdev-private-flow.h b/lib/dpif-netdev-private-flow.h index 3030660675..32ad020d90 100644 --- a/lib/dpif-netdev-private-flow.h diff --git a/SPECS/openvswitch2.16.spec b/SPECS/openvswitch2.16.spec index 993e703..d5b1c11 100644 --- a/SPECS/openvswitch2.16.spec +++ b/SPECS/openvswitch2.16.spec @@ -57,7 +57,7 @@ Summary: Open vSwitch Group: System Environment/Daemons daemon/database/utilities URL: http://www.openvswitch.org/ Version: 2.16.0 -Release: 84%{?dist} +Release: 85%{?dist} # Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the # lib/sflow*.[ch] files are SISSL @@ -699,6 +699,12 @@ exit 0 %endif %changelog +* Wed Jun 29 2022 Open vSwitch CI - 2.16.0-85 +- Merging upstream branch-2.16 [RH git: df1ebc7699] + Commit list: + 0fe91ee5b0 dpif-netdev: Refactor AVX512 runtime checks. (#2100393) + + * Tue Jun 28 2022 Open vSwitch CI - 2.16.0-84 - Merging upstream branch-2.16 [RH git: 058ebc82c2] Commit list: