Richard Brown 2022-10-01 15:42:46 +00:00 committed by Git OBS Bridge
commit 7092f53a75
3 changed files with 362 additions and 0 deletions

View File

@ -0,0 +1,355 @@
From a77ad9693c8b49055389559187fe74eddb619746 Mon Sep 17 00:00:00 2001
From: David Marchand <david.marchand@redhat.com>
Date: Wed, 29 Jun 2022 09:32:24 +0200
Subject: [PATCH] dpif-netdev: Refactor AVX512 runtime checks.
As described in the bugzilla below, cpu_has_isa code may be compiled
with some AVX512 instructions in it, because cpu.c is built as part of
the libopenvswitchavx512.
This is a problem when this function (supposed to probe for AVX512
instructions availability) is invoked from generic OVS code, on older
CPUs that don't support them.
For the same reason, dpcls_subtable_avx512_gather_probe,
dp_netdev_input_outer_avx512_probe, mfex_avx512_probe and
mfex_avx512_vbmi_probe are potential runtime bombs and can't either be
built as part of libopenvswitchavx512.
Move cpu.c to be part of the "normal" libopenvswitch.
And move other helpers in generic OVS code.
Note:
- dpcls_subtable_avx512_gather_probe is split in two, because it also
needs to do its own magic,
- while moving those helpers, prefer direct calls to cpu_has_isa and
avoid cast to intermediate integer variables when a simple boolean
is enough,
Fixes: 352b6c7116cd ("dpif-lookup: add avx512 gather implementation.")
Fixes: abb807e27dd4 ("dpif-netdev: Add command to switch dpif implementation.")
Fixes: 250ceddcc2d0 ("dpif-netdev/mfex: Add AVX512 based optimized miniflow extract")
Fixes: b366fa2f4947 ("dpif-netdev: Call cpuid for x86 isa availability.")
Reported-at: https://bugzilla.redhat.com/2100393
Reported-by: Ales Musil <amusil@redhat.com>
Co-authored-by: Ales Musil <amusil@redhat.com>
Signed-off-by: Ales Musil <amusil@redhat.com>
Signed-off-by: David Marchand <david.marchand@redhat.com>
Acked-by: Sunil Pai G <sunil.pai.g@intel.com>
Acked-by: Ales Musil <amusil@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
lib/automake.mk | 4 +--
lib/dpif-netdev-avx512.c | 14 ---------
lib/dpif-netdev-extract-avx512.c | 43 --------------------------
lib/dpif-netdev-lookup-avx512-gather.c | 12 ++-----
lib/dpif-netdev-lookup.c | 15 +++++++++
lib/dpif-netdev-lookup.h | 3 +-
lib/dpif-netdev-private-dpif.c | 14 +++++++++
lib/dpif-netdev-private-dpif.h | 5 +--
lib/dpif-netdev-private-extract.c | 38 +++++++++++++++++++++++
lib/dpif-netdev-private-extract.h | 4 +--
10 files changed, 75 insertions(+), 77 deletions(-)
Index: openvswitch-2.17.2/lib/automake.mk
===================================================================
--- openvswitch-2.17.2.orig/lib/automake.mk
+++ openvswitch-2.17.2/lib/automake.mk
@@ -38,8 +38,6 @@ lib_libopenvswitchavx512_la_CFLAGS = \
-fPIC \
$(AM_CFLAGS)
lib_libopenvswitchavx512_la_SOURCES = \
- lib/cpu.c \
- lib/cpu.h \
lib/dpif-netdev-lookup-avx512-gather.c \
lib/dpif-netdev-extract-avx512.c \
lib/dpif-netdev-avx512.c
@@ -89,6 +87,8 @@ lib_libopenvswitch_la_SOURCES = \
lib/conntrack.h \
lib/coverage.c \
lib/coverage.h \
+ lib/cpu.c \
+ lib/cpu.h \
lib/crc32c.c \
lib/crc32c.h \
lib/csum.c \
Index: openvswitch-2.17.2/lib/dpif-netdev-avx512.c
===================================================================
--- openvswitch-2.17.2.orig/lib/dpif-netdev-avx512.c
+++ openvswitch-2.17.2/lib/dpif-netdev-avx512.c
@@ -20,7 +20,6 @@
#include <config.h>
-#include "cpu.h"
#include "dpif-netdev.h"
#include "dpif-netdev-perf.h"
#include "dpif-netdev-private.h"
@@ -60,19 +59,6 @@ struct dpif_userdata {
};
int32_t
-dp_netdev_input_outer_avx512_probe(void)
-{
- bool avx512f_available = cpu_has_isa(OVS_CPU_ISA_X86_AVX512F);
- bool bmi2_available = cpu_has_isa(OVS_CPU_ISA_X86_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,
odp_port_t in_port)
Index: openvswitch-2.17.2/lib/dpif-netdev-extract-avx512.c
===================================================================
--- openvswitch-2.17.2.orig/lib/dpif-netdev-extract-avx512.c
+++ openvswitch-2.17.2/lib/dpif-netdev-extract-avx512.c
@@ -42,7 +42,6 @@
#include <stdint.h>
#include <string.h>
-#include "cpu.h"
#include "internal/flow.h"
#include "dpif-netdev-private-dpcls.h"
@@ -659,47 +658,5 @@ DECLARE_MFEX_FUNC(ip_udp, PROFILE_ETH_IP
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 enum ovs_cpu_isa isa_required[] = {
- OVS_CPU_ISA_X86_AVX512F,
- OVS_CPU_ISA_X86_AVX512BW,
- OVS_CPU_ISA_X86_BMI2,
- };
-
- int32_t ret = 0;
- for (uint32_t i = 0; i < ARRAY_SIZE(isa_required); i++) {
- if (!cpu_has_isa(isa_required[i])) {
- ret = -ENOTSUP;
- }
- }
-
- if (needs_vbmi) {
- if (!cpu_has_isa(OVS_CPU_ISA_X86_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__ */
Index: openvswitch-2.17.2/lib/dpif-netdev-lookup-avx512-gather.c
===================================================================
--- openvswitch-2.17.2.orig/lib/dpif-netdev-lookup-avx512-gather.c
+++ openvswitch-2.17.2/lib/dpif-netdev-lookup-avx512-gather.c
@@ -396,18 +396,11 @@ dpcls_avx512_gather_mf_any(struct dpcls_
}
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 = cpu_has_isa(OVS_CPU_ISA_X86_AVX512F);
- int bmi2_available = cpu_has_isa(OVS_CPU_ISA_X86_BMI2);
- if (!avx512f_available || !bmi2_available) {
- return NULL;
- }
-
- int use_vpop = cpu_has_isa(OVS_CPU_ISA_X86_VPOPCNTDQ);
-
CHECK_LOOKUP_FUNCTION(9, 4, use_vpop);
CHECK_LOOKUP_FUNCTION(9, 1, use_vpop);
CHECK_LOOKUP_FUNCTION(5, 3, use_vpop);
Index: openvswitch-2.17.2/lib/dpif-netdev-lookup.c
===================================================================
--- openvswitch-2.17.2.orig/lib/dpif-netdev-lookup.c
+++ openvswitch-2.17.2/lib/dpif-netdev-lookup.c
@@ -18,10 +18,25 @@
#include <errno.h>
#include "dpif-netdev-lookup.h"
+#include "cpu.h"
#include "openvswitch/vlog.h"
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 (!cpu_has_isa(OVS_CPU_ISA_X86_AVX512F)
+ || !cpu_has_isa(OVS_CPU_ISA_X86_BMI2)) {
+ return NULL;
+ }
+
+ return dpcls_subtable_avx512_gather_probe__(u0_bits, u1_bits,
+ cpu_has_isa(OVS_CPU_ISA_X86_VPOPCNTDQ));
+}
+#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
Index: openvswitch-2.17.2/lib/dpif-netdev-lookup.h
===================================================================
--- openvswitch-2.17.2.orig/lib/dpif-netdev-lookup.h
+++ openvswitch-2.17.2/lib/dpif-netdev-lookup.h
@@ -44,7 +44,8 @@ dpcls_subtable_generic_probe(uint32_t u0
/* 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 */
Index: openvswitch-2.17.2/lib/dpif-netdev-private-dpif.c
===================================================================
--- openvswitch-2.17.2.orig/lib/dpif-netdev-private-dpif.c
+++ openvswitch-2.17.2/lib/dpif-netdev-private-dpif.c
@@ -22,6 +22,7 @@
#include <errno.h>
#include <string.h>
+#include "cpu.h"
#include "openvswitch/dynamic-string.h"
#include "openvswitch/vlog.h"
#include "internal/util.h"
@@ -33,6 +34,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 (!cpu_has_isa(OVS_CPU_ISA_X86_AVX512F)
+ || !cpu_has_isa(OVS_CPU_ISA_X86_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. */
Index: openvswitch-2.17.2/lib/dpif-netdev-private-dpif.h
===================================================================
--- openvswitch-2.17.2.orig/lib/dpif-netdev-private-dpif.h
+++ openvswitch-2.17.2/lib/dpif-netdev-private-dpif.h
@@ -67,10 +67,7 @@ dp_netdev_input(struct dp_netdev_pmd_thr
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,
Index: openvswitch-2.17.2/lib/dpif-netdev-private-extract.c
===================================================================
--- openvswitch-2.17.2.orig/lib/dpif-netdev-private-extract.c
+++ openvswitch-2.17.2/lib/dpif-netdev-private-extract.c
@@ -19,6 +19,7 @@
#include <stdint.h>
#include <string.h>
+#include "cpu.h"
#include "internal/dp-packet.h"
#include "dpif-netdev-private-dpcls.h"
#include "dpif-netdev-private-extract.h"
@@ -33,6 +34,43 @@ VLOG_DEFINE_THIS_MODULE(dpif_netdev_extr
/* 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 enum ovs_cpu_isa isa_required[] = {
+ OVS_CPU_ISA_X86_AVX512F,
+ OVS_CPU_ISA_X86_AVX512BW,
+ OVS_CPU_ISA_X86_BMI2,
+ };
+
+ for (uint32_t i = 0; i < ARRAY_SIZE(isa_required); i++) {
+ if (!cpu_has_isa(isa_required[i])) {
+ return -ENOTSUP;
+ }
+ }
+
+ if (needs_vbmi && !cpu_has_isa(OVS_CPU_ISA_X86_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.
*/
Index: openvswitch-2.17.2/lib/dpif-netdev-private-extract.h
===================================================================
--- openvswitch-2.17.2.orig/lib/dpif-netdev-private-extract.h
+++ openvswitch-2.17.2/lib/dpif-netdev-private-extract.h
@@ -176,10 +176,8 @@ mfex_study_traffic(struct dp_packet_batc
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 \

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Thu Sep 29 11:58:47 UTC 2022 - Dirk Müller <dmueller@suse.com>
- add a77ad9693c8b49055389559187fe74eddb619746.patch to avoid
the cpu detection code being compiled with AVX512 enabled
-------------------------------------------------------------------
Mon Sep 12 19:55:30 UTC 2022 - Andreas Stieger <andreas.stieger@gmx.de>

View File

@ -61,6 +61,7 @@ Patch4: install-ovsdb-tools.patch
Patch5: 0001-openvswitch-merge-compiler.h-files-into-one-file.patch
Patch6: 0002-build-Seperated-common-used-headers.patch
Patch7: openvswitch-2.17.2-Fix-tests-with-GNU-grep-3.8.patch
Patch8: a77ad9693c8b49055389559187fe74eddb619746.patch
# Python subpackage
BuildRequires: %{python_module devel}
BuildRequires: %{python_module setuptools}