{"id":2229661,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2229661/?format=json","web_url":"http://patchwork.ozlabs.org/project/openvswitch/patch/20260428151926.3798626-5-i.maximets@ovn.org/","project":{"id":47,"url":"http://patchwork.ozlabs.org/api/1.1/projects/47/?format=json","name":"Open vSwitch","link_name":"openvswitch","list_id":"ovs-dev.openvswitch.org","list_email":"ovs-dev@openvswitch.org","web_url":"http://openvswitch.org/","scm_url":"git@github.com:openvswitch/ovs.git","webscm_url":"https://github.com/openvswitch/ovs"},"msgid":"<20260428151926.3798626-5-i.maximets@ovn.org>","date":"2026-04-28T15:19:09","name":"[ovs-dev,4/6] dpif-netdev: Remove deprecated AVX512-optimized subtable lookup.","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"5b729cd33836a98966933aa8fbf0c2077774222d","submitter":{"id":76798,"url":"http://patchwork.ozlabs.org/api/1.1/people/76798/?format=json","name":"Ilya Maximets","email":"i.maximets@ovn.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/openvswitch/patch/20260428151926.3798626-5-i.maximets@ovn.org/mbox/","series":[{"id":501877,"url":"http://patchwork.ozlabs.org/api/1.1/series/501877/?format=json","web_url":"http://patchwork.ozlabs.org/project/openvswitch/list/?series=501877","date":"2026-04-28T15:19:05","name":"dpif-netdev: Remove deprecated AVX512-based optimizations.","version":1,"mbox":"http://patchwork.ozlabs.org/series/501877/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2229661/comments/","check":"success","checks":"http://patchwork.ozlabs.org/api/patches/2229661/checks/","tags":{},"headers":{"Return-Path":"<ovs-dev-bounces@openvswitch.org>","X-Original-To":["incoming@patchwork.ozlabs.org","ovs-dev@openvswitch.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","ovs-dev@lists.linuxfoundation.org"],"Authentication-Results":["legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org\n (client-ip=2605:bc80:3010::133; helo=smtp2.osuosl.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org)","smtp4.osuosl.org;\n dmarc=none (p=none dis=none) header.from=ovn.org"],"Received":["from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g4kdd2Jgwz1xrS\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 Apr 2026 01:20:21 +1000 (AEST)","from localhost (localhost [127.0.0.1])\n\tby smtp2.osuosl.org (Postfix) with ESMTP id A194140831;\n\tTue, 28 Apr 2026 15:20:14 +0000 (UTC)","from smtp2.osuosl.org ([127.0.0.1])\n by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id WVrNgouiKGtm; Tue, 28 Apr 2026 15:20:07 +0000 (UTC)","from lists.linuxfoundation.org (lf-lists.osuosl.org\n [IPv6:2605:bc80:3010:104::8cd3:938])\n\tby smtp2.osuosl.org (Postfix) with ESMTPS id 62E60407B4;\n\tTue, 28 Apr 2026 15:20:02 +0000 (UTC)","from lf-lists.osuosl.org (localhost [127.0.0.1])\n\tby lists.linuxfoundation.org (Postfix) with ESMTP id 0765DC058F;\n\tTue, 28 Apr 2026 15:20:02 +0000 (UTC)","from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137])\n by lists.linuxfoundation.org (Postfix) with ESMTP id 07B2AC0626\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 15:19:59 +0000 (UTC)","from localhost (localhost [127.0.0.1])\n by smtp4.osuosl.org (Postfix) with ESMTP id 989834143F\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 15:19:50 +0000 (UTC)","from smtp4.osuosl.org ([127.0.0.1])\n by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP\n id Ctw-PQp2kj88 for <ovs-dev@openvswitch.org>;\n Tue, 28 Apr 2026 15:19:48 +0000 (UTC)","from mail-wm1-f66.google.com (mail-wm1-f66.google.com\n [209.85.128.66])\n by smtp4.osuosl.org (Postfix) with ESMTPS id 67208412E3\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 15:19:47 +0000 (UTC)","by mail-wm1-f66.google.com with SMTP id\n 5b1f17b1804b1-488a88aeec9so142006115e9.2\n for <ovs-dev@openvswitch.org>; Tue, 28 Apr 2026 08:19:47 -0700 (PDT)","from im-t490s.redhat.com (89-24-34-32.nat.epc.tmcz.cz.\n [89.24.34.32])\n by smtp.gmail.com with ESMTPSA id\n ffacd0b85a97d-4463fa89038sm7080967f8f.26.2026.04.28.08.19.43\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 28 Apr 2026 08:19:43 -0700 (PDT)"],"X-Virus-Scanned":["amavis at osuosl.org","amavis at osuosl.org"],"X-Comment":"SPF check N/A for local connections -\n client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org;\n envelope-from=ovs-dev-bounces@openvswitch.org; receiver=<UNKNOWN> ","DKIM-Filter":["OpenDKIM Filter v2.11.0 smtp2.osuosl.org 62E60407B4","OpenDKIM Filter v2.11.0 smtp4.osuosl.org 67208412E3"],"Received-SPF":"Pass (mailfrom) identity=mailfrom; client-ip=209.85.128.66;\n helo=mail-wm1-f66.google.com; envelope-from=i.maximets.ovn@gmail.com;\n receiver=<UNKNOWN>","DMARC-Filter":"OpenDMARC Filter v1.4.2 smtp4.osuosl.org 67208412E3","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777389585; x=1777994385;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=zLOt7X4S/5GUAqeibcI7eM+kva+RgQbJAXXlIWJ6B8Q=;\n b=gOgVIotgkTvor4HLUnPbvSlsaE+jMRK2ot+q7CjV38pr/lTrYMEBN15Rvq2vVFSfLc\n FoITgt+ZuhVJW5coW3+I40NBis96+wC88cmmWCmZZ+GwtjItb7cC3pqusI5WBfBZIVLx\n UYSwIiQ4/k2r0PLca5p1biZYGi7oLJZ5ou3q4a1R4/CVx6H17xR97075a3gvrg+VSsk/\n 3cL0uZ+YSKmx4mJ3CUv+13VwGWrmll8oGtnmI9nlQP54X6s8z1u7Of2vPXe9+Zrs+lLE\n sstcTBZF71zhkzHgbsx9fs/nOMAhqbgBfINxKFMDlbsPeQWmdJTobZ9lRKGPnIW7x0GQ\n hBGA==","X-Gm-Message-State":"AOJu0Yy3dIrFQ6pmJOLuOAupkcKeuFZ7VquqZBnXRxhyF3gqtVbIcq0O\n JDblfIhqXElJnWgbP/zAjnP7SzgaC7rf1v5XNI7umiZChuWEteqNQmzXFDiREtk6WA8=","X-Gm-Gg":"AeBDievOQkA0YvwvgFvkgCFgiEbXDh/4K2pAQhINmsOBC1bz8SDQhSwf1c13fMH5av1\n +8QmAxhbwBzMkLxAv/OXGwxy+KN/CBuXUcSZLUEb9419gxAKPU8awNlFyLSeV7Z+lO9mCF2gLwj\n u3EpX68cEz7DTZ2/3q+FHEB1G0WNg8wn8p5xyBsLamp1arzqkt4WSa7tic0IpTnIBAc8dBW+TDI\n BD/75NBQbwdQH9bJ0YwY3ekg9mw7oKr9ejz1g/IuGuwKD5J1W7KpSQdPgfd9612/81WUXBc2odc\n JJqXs0U3m/ahG6RD+WKaFBKM3F9zEiZ/A5jRd6MHiIgyzWPFnM1pOgKUUP+pXNk2M1+y6vWlXOG\n M/NjEGMWtn+7LXs1vuLvDmvRA6y5iupC5jtkujlw0iagoFcC4N9b4PBDV8Gjarvt7tZDY+I53uO\n Zq+7dR/Z+OhiVY++gOEasBpweBDeKdwurd08ncSPW+EydaOd1WcKuDgx4Fwk1BX5dftoQ=","X-Received":"by 2002:a05:600c:a40f:b0:489:5022:39a4 with SMTP id\n 5b1f17b1804b1-48a77adc6ccmr51146615e9.9.1777389584345;\n Tue, 28 Apr 2026 08:19:44 -0700 (PDT)","From":"Ilya Maximets <i.maximets@ovn.org>","To":"ovs-dev@openvswitch.org","Cc":"Ilya Maximets <i.maximets@ovn.org>","Date":"Tue, 28 Apr 2026 17:19:09 +0200","Message-ID":"<20260428151926.3798626-5-i.maximets@ovn.org>","X-Mailer":"git-send-email 2.53.0","In-Reply-To":"<20260428151926.3798626-1-i.maximets@ovn.org>","References":"<20260428151926.3798626-1-i.maximets@ovn.org>","MIME-Version":"1.0","Subject":"[ovs-dev] [PATCH 4/6] dpif-netdev: Remove deprecated\n AVX512-optimized subtable lookup.","X-BeenThere":"ovs-dev@openvswitch.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"<ovs-dev.openvswitch.org>","List-Unsubscribe":"<https://mail.openvswitch.org/mailman/options/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=unsubscribe>","List-Archive":"<http://mail.openvswitch.org/pipermail/ovs-dev/>","List-Post":"<mailto:ovs-dev@openvswitch.org>","List-Help":"<mailto:ovs-dev-request@openvswitch.org?subject=help>","List-Subscribe":"<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>,\n <mailto:ovs-dev-request@openvswitch.org?subject=subscribe>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"ovs-dev-bounces@openvswitch.org","Sender":"\"dev\" <ovs-dev-bounces@openvswitch.org>"},"content":"This functionality was deprecated in 3.7 due to lack of use, testing\nand maintenance.  It's time to remove it.\n\nWe still have the compile-time optimized versions of lookup functions\nfor different subtable bit configurations, so some parts of the\ninfrastructure for them stays.  But we no longer need the internal\ndpif-netdev-private.h header and the dpif-netdev-lookup-generic\nis now the only dpif-netdev-lookup implementation.  So, removing the\ndpif-netdev-lookup infra, hooking up dpif-netdev-lookup-generic\ndirectly into the callers and renaming it similarly to the rest of the\nsub-modules of dpif-netdev.  The 'private' part in the names doesn't\nreally make sense after the private header removal.  Will be renamed\nin the next commit to avoid unnecessary complexity in the diff.\n\nSigned-off-by: Ilya Maximets <i.maximets@ovn.org>\n---\n Documentation/intro/install/dpdk.rst          |  32 +-\n Documentation/topics/dpdk/bridge.rst          |  92 ----\n Documentation/topics/testing.rst              |  43 --\n NEWS                                          |   1 +\n acinclude.m4                                  |  52 +-\n configure.ac                                  |   2 -\n lib/automake.mk                               |  42 +-\n lib/dpif-netdev-lookup-autovalidator.c        | 109 -----\n lib/dpif-netdev-lookup-avx512-gather.c        | 445 ------------------\n lib/dpif-netdev-lookup.c                      | 193 --------\n lib/dpif-netdev-lookup.h                      |  92 ----\n ...-generic.c => dpif-netdev-private-dpcls.c} |  37 +-\n lib/dpif-netdev-private-dpcls.h               |  13 +-\n lib/dpif-netdev-private-flow.h                |   3 -\n lib/dpif-netdev-private-thread.h              |   4 -\n lib/dpif-netdev-private.h                     |  52 --\n lib/dpif-netdev-unixctl.man                   |  12 -\n lib/dpif-netdev.c                             | 191 +-------\n m4/openvswitch.m4                             |  70 ---\n tests/pmd.at                                  |  68 ---\n 20 files changed, 43 insertions(+), 1510 deletions(-)\n delete mode 100644 lib/dpif-netdev-lookup-autovalidator.c\n delete mode 100644 lib/dpif-netdev-lookup-avx512-gather.c\n delete mode 100644 lib/dpif-netdev-lookup.c\n delete mode 100644 lib/dpif-netdev-lookup.h\n rename lib/{dpif-netdev-lookup-generic.c => dpif-netdev-private-dpcls.c} (91%)\n delete mode 100644 lib/dpif-netdev-private.h","diff":"diff --git a/Documentation/intro/install/dpdk.rst b/Documentation/intro/install/dpdk.rst\nindex 6f4687bde..ccc06ec2e 100644\n--- a/Documentation/intro/install/dpdk.rst\n+++ b/Documentation/intro/install/dpdk.rst\n@@ -155,19 +155,8 @@ has to be configured to build against the DPDK library (``--with-dpdk``).\n      While ``--with-dpdk`` is required, you can pass any other configuration\n      option described in :ref:`general-configuring`.\n \n-   .. note::\n-     The AVX512 Datapath Classifier Performance feature is deprecated and will\n-     be removed in a future release.\n-\n    It is strongly recommended to build OVS with at least ``-msse4.2`` and\n-   ``-mpopcnt`` optimization flags. If these flags are not enabled, the AVX512\n-   optimized DPCLS implementation is not available in the resulting binary.\n-   For technical details see the subtable registration code in the\n-   ``lib/dpif-netdev-lookup.c`` file.\n-\n-   An example that enables the AVX512 optimizations is::\n-\n-       $ ./configure --with-dpdk=static CFLAGS=\"-Ofast -msse4.2 -mpopcnt\"\n+   ``-mpopcnt`` optimization flags.\n \n #. Build and install OVS, as described in :ref:`general-building`\n \n@@ -181,25 +170,6 @@ Additional information can be found in :doc:`general`.\n __ https://github.com/openvswitch/ovs/blob/main/rhel/README.RHEL.rst\n \n \n-Possible issues when enabling AVX512\n-++++++++++++++++++++++++++++++++++++\n-\n-The enabling of ISA optimized builds requires build-system support.\n-Certain versions of the assembler provided by binutils is known to have\n-AVX512 assembling issues. The binutils versions affected are 2.30 and 2.31.\n-As many distros backport fixes to previous versions of a package, checking\n-the version output of ``as -v`` can err on the side of disabling AVX512. To\n-remedy this, the OVS build system uses a build-time check to see if ``as``\n-will correctly assemble the AVX512 code. The output of a good version when\n-running the ``./configure`` step of the build process is as follows::\n-\n-   $ checking binutils avx512 assembler checks passing... yes\n-\n-If a bug is detected in the binutils assembler, it would indicate ``no``.\n-Build an updated binutils, or request a backport of this binutils\n-fix commit ``2069ccaf8dc28ea699bd901fdd35d90613e4402a`` to fix the issue.\n-\n-\n Setup\n -----\n \ndiff --git a/Documentation/topics/dpdk/bridge.rst b/Documentation/topics/dpdk/bridge.rst\nindex ab09f89f1..163bcc2e2 100644\n--- a/Documentation/topics/dpdk/bridge.rst\n+++ b/Documentation/topics/dpdk/bridge.rst\n@@ -161,95 +161,3 @@ currently turned off by default.\n To turn on SMC::\n \n     $ ovs-vsctl --no-wait set Open_vSwitch . other_config:smc-enable=true\n-\n-Datapath Classifier Performance\n--------------------------------\n-\n-.. note::\n-\n-   The AVX512 Datapath Classifier Performance feature is deprecated and will be\n-   removed in a future release.\n-\n-The datapath classifier (dpcls) performs wildcard rule matching, a compute\n-intensive process of matching a packet ``miniflow`` to a rule ``miniflow``. The\n-code that does this compute work impacts datapath performance, and optimizing\n-it can provide higher switching performance.\n-\n-Modern CPUs provide extensive SIMD instructions which can be used to get higher\n-performance. The CPU OVS is being deployed on must be capable of running these\n-SIMD instructions in order to take advantage of the performance benefits.\n-In OVS v2.14 runtime CPU detection was introduced to enable identifying if\n-these CPU ISA additions are available, and to allow the user to enable them.\n-\n-OVS provides multiple implementations of dpcls. The following command enables\n-the user to check what implementations are available in a running instance::\n-\n-    $ ovs-appctl dpif-netdev/subtable-lookup-info-get\n-    Available dpcls implementations:\n-            autovalidator (Use count: 1, Priority: 5)\n-            generic (Use count: 0, Priority: 1)\n-            avx512_gather (Use count: 0, Priority: 3)\n-\n-To set the priority of a lookup function, run the ``prio-set`` command::\n-\n-    $ ovs-appctl dpif-netdev/subtable-lookup-prio-set avx512_gather 5\n-    Lookup priority change affected 1 dpcls ports and 1 subtables.\n-\n-The highest priority lookup function is used for classification, and the output\n-above indicates that one subtable of one DPCLS port is has changed its lookup\n-function due to the command being run. To verify the prioritization, re-run the\n-get command, note the updated priority of the ``avx512_gather`` function::\n-\n-    $ ovs-appctl dpif-netdev/subtable-lookup-info-get\n-    Available dpcls implementations:\n-            autovalidator (Use count: 1, Priority: 5)\n-            generic (Use count: 0, Priority: 1)\n-            avx512_gather (Use count: 0, Priority: 3)\n-\n-If two lookup functions have the same priority, the first one in the list is\n-chosen, and the 2nd occurrence of that priority is not used. Put in logical\n-terms, a subtable is chosen if its priority is greater than the previous\n-best candidate.\n-\n-Note that the ``avx512_gather`` implementation uses instructions which may be\n-affected by the Gather Data Sampling (GDS) vulnerability, aka Downfall,\n-mitigation (see documentation for CVE-2022-40982 for details). This could\n-result in lower performance when these mitigations are enabled.\n-\n-Optimizing Specific Subtable Search\n-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n-\n-.. note::\n-\n-   The AVX512 Optimizing Specific Subtable Search feature is deprecated and\n-   will be removed in a future release.\n-\n-During the packet classification, the datapath can use specialized lookup\n-tables to optimize the search.  However, not all situations are optimized.  If\n-you see a message like the following one in the OVS logs, it means that there\n-is no specialized implementation available for the current network traffic::\n-\n-  Using non-specialized AVX512 lookup for subtable (X,Y) and possibly others.\n-\n-In this case, OVS will continue to process the traffic normally using a more\n-generic lookup table.\n-\n-Additional specialized lookups can be added to OVS if the user provides that\n-log message along with the command output as show below to the OVS mailing\n-list.  Note that the numbers in the log message (``subtable (X,Y)``) need to\n-match with the numbers in the provided command output\n-(``dp-extra-info:miniflow_bits(X,Y)``).\n-\n-``ovs-appctl dpctl/dump-flows -m``, which results in output like this::\n-\n-    ufid:82770b5d-ca38-44ff-8283-74ba36bd1ca5, skb_priority(0/0),skb_mark(0/0)\n-    ,ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),recirc_id(0),\n-    dp_hash(0/0),in_port(pcap0),packet_type(ns=0,id=0),eth(src=00:00:00:00:00:\n-    00/00:00:00:00:00:00,dst=ff:ff:ff:ff:ff:ff/00:00:00:00:00:00),eth_type(\n-    0x8100),vlan(vid=1,pcp=0),encap(eth_type(0x0800),ipv4(src=127.0.0.1/0.0.0.0\n-    ,dst=127.0.0.1/0.0.0.0,proto=17/0,tos=0/0,ttl=64/0,frag=no),udp(src=53/0,\n-    dst=53/0)), packets:77072681, bytes:3545343326, used:0.000s, dp:ovs,\n-    actions:vhostuserclient0, dp-extra-info:miniflow_bits(4,1)\n-\n-Please send an email to the OVS mailing list ovs-dev@openvswitch.org with\n-the output of the ``dp-extra-info:miniflow_bits(4,1)`` values.\ndiff --git a/Documentation/topics/testing.rst b/Documentation/topics/testing.rst\nindex e3b06321a..278b5c1d0 100644\n--- a/Documentation/topics/testing.rst\n+++ b/Documentation/topics/testing.rst\n@@ -326,49 +326,6 @@ To invoke the DPDK offloads testsuite with the userspace datapath, run::\n    This has only been tested on NVIDIA blades due to the limited availability\n    of other blades that support rte_flow.\n \n-Userspace datapath: Testing and Validation of CPU-specific Optimizations\n-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n-\n-.. note::\n-  The AVX512 CPU-specific optimization features are deprecated and will be\n-  removed in a future release.\n-\n-As multiple versions of the datapath classifier each with different CPU ISA\n-optimizations, it is important to validate that they all give the exact same\n-results.  To easily test all the implementations, an ``autovalidator``\n-implementation of them exists.  This implementation runs all other available\n-implementations, and verifies that the results are identical.\n-\n-Running the OVS unit tests with the autovalidator enabled ensures all\n-implementations provide the same results.  Note that the performance of the\n-autovalidator is lower than all other implementations, as it tests the scalar\n-implementation against itself, and against all other enabled implementations.\n-\n-To adjust the autovalidator priority for a datapath classifier, use this\n-command::\n-\n-    $ ovs-appctl dpif-netdev/subtable-lookup-prio-set autovalidator 7\n-\n-To run the OVS unit test suite with the autovalidator as the default\n-implementation, it is required to recompile OVS.  During the recompilation,\n-the default priority of the `autovalidator` implementation is set to the\n-maximum priority, ensuring every test will be run with every implementation::\n-\n-    $ ./configure --enable-autovalidator\n-\n-The following line should be seen in the configuration log when the above\n-options are used::\n-\n-    checking whether DPCLS Autovalidator is default implementation... yes\n-\n-Compile OVS in debug mode to have `ovs_assert` statements error out if\n-there is a mismatch in the datapath classifier lookup.\n-\n-.. note::\n-  Run all the available testsuites including `make check`,\n-  `make check-system-userspace` and `make check-dpdk` to ensure the optimal\n-  test coverage.\n-\n Kernel datapath\n +++++++++++++++\n \ndiff --git a/NEWS b/NEWS\nindex cfaafe534..ed52d2405 100644\n--- a/NEWS\n+++ b/NEWS\n@@ -5,6 +5,7 @@ Post-v3.7.0\n        timer can be configured with 'tnl/neigh/retrans_time'.\n    - The following deprecated AVX512-specific features of the userspace\n      datapath are now removed:\n+     * AVX512-optimized DPCLS lookups.\n      * AVX512-optimized action handling.\n      * AVX512-optimized packet parsing (miniflow extraction).\n      * AVX512-optimized DPIF input processing.\ndiff --git a/acinclude.m4 b/acinclude.m4\nindex 58d5b9df8..bc26a284b 100644\n--- a/acinclude.m4\n+++ b/acinclude.m4\n@@ -14,39 +14,6 @@\n # See the License for the specific language governing permissions and\n # limitations under the License.\n \n-dnl Set OVS DPCLS Autovalidator as default subtable search at compile time?\n-dnl This enables automatically running all unit tests with all DPCLS\n-dnl implementations.\n-AC_DEFUN([OVS_CHECK_DPCLS_AUTOVALIDATOR], [\n-  AC_ARG_ENABLE([autovalidator],\n-                [AS_HELP_STRING([--enable-autovalidator],\n-                                [Enable DPCLS autovalidator as default subtable\n-                                 search implementation.])],\n-                [autovalidator=yes],[autovalidator=no])\n-  AC_MSG_CHECKING([whether DPCLS Autovalidator is default implementation])\n-  if test \"$autovalidator\" != yes; then\n-    AC_MSG_RESULT([no])\n-  else\n-    AC_DEFINE([DPCLS_AUTOVALIDATOR_DEFAULT], [1],\n-              [Autovalidator for the userspace datapath classifier is a\n-               default implementation.])\n-    AC_MSG_RESULT([yes])\n-    AC_MSG_WARN(\n-      [Explicit AVX512 feature support will be deprecated in the next release.])\n-  fi\n-])\n-\n-dnl OVS_CHECK_AVX512\n-dnl\n-dnl Checks if compiler and binutils supports various AVX512 ISA.\n-AC_DEFUN([OVS_CHECK_AVX512], [\n-  OVS_CHECK_BINUTILS_AVX512\n-  OVS_CONDITIONAL_CC_OPTION_DEFINE([-mavx512f], [HAVE_AVX512F])\n-  OVS_CONDITIONAL_CC_OPTION_DEFINE([-mavx512bw], [HAVE_AVX512BW])\n-  OVS_CONDITIONAL_CC_OPTION_DEFINE([-mavx512vl], [HAVE_AVX512VL])\n-  OVS_CHECK_AVX512VPOPCNTDQ\n-])\n-\n dnl OVS_ENABLE_WERROR\n AC_DEFUN([OVS_ENABLE_WERROR],\n   [AC_ARG_ENABLE(\n@@ -435,11 +402,7 @@ AC_DEFUN([OVS_CHECK_DPDK], [\n     # forces in pkg-config since this could override user-specified options.\n     # It's enough to have -mssse3 to build with DPDK headers.\n     DPDK_INCLUDE=$(echo \"$DPDK_INCLUDE\" | sed 's/-march=[[^ ]]*//g')\n-    # Also stripping out '-mno-avx512f'.  Support for AVX512 will be disabled\n-    # if OVS will detect that it's broken.  OVS could be built with a\n-    # completely different toolchain that correctly supports AVX512, flags\n-    # forced by DPDK only breaks our feature detection mechanism and leads to\n-    # build failures: https://github.com/openvswitch/ovs-issues/issues/201\n+    # Also stripping out '-mno-avx512f' for the same reasons.\n     DPDK_INCLUDE=$(echo \"$DPDK_INCLUDE\" | sed 's/-mno-avx512f//g')\n     OVS_CFLAGS=\"$OVS_CFLAGS $DPDK_INCLUDE\"\n     OVS_ENABLE_OPTION([-mssse3])\n@@ -613,19 +576,6 @@ AC_DEFUN([OVS_CONDITIONAL_CC_OPTION],\n    AM_CONDITIONAL([$2], [test $ovs_have_cc_option = yes])])\n dnl ----------------------------------------------------------------------\n \n-dnl OVS_CONDITIONAL_CC_OPTION_DEFINE([OPTION], [CONDITIONAL])\n-dnl Check whether the given C compiler OPTION is accepted.\n-dnl If so, enable the given Automake CONDITIONAL and define it.\n-dnl Example: OVS_CONDITIONAL_CC_OPTION_DEFINE([-mavx512f], [HAVE_AVX512F])\n-AC_DEFUN([OVS_CONDITIONAL_CC_OPTION_DEFINE],\n-  [OVS_CHECK_CC_OPTION(\n-    [$1], [ovs_have_cc_option=yes], [ovs_have_cc_option=no])\n-   AM_CONDITIONAL([$2], [test $ovs_have_cc_option = yes])\n-   if test \"$ovs_have_cc_option\" = yes; then\n-     AC_DEFINE([$2], [1],\n-               [Define to 1 if compiler supports the '$1' option.])\n-   fi])\n-\n dnl OVS_CHECK_SPARSE_TARGET\n dnl\n dnl The \"cgcc\" script from \"sparse\" isn't very good at detecting the\ndiff --git a/configure.ac b/configure.ac\nindex bc5fabcd8..bf9514c74 100644\n--- a/configure.ac\n+++ b/configure.ac\n@@ -190,8 +190,6 @@ OVS_CONDITIONAL_CC_OPTION([-Wno-unused-parameter], [HAVE_WNO_UNUSED_PARAMETER])\n OVS_ENABLE_WERROR_TOP\n OVS_ENABLE_SPARSE\n OVS_CTAGS_IDENTIFIERS\n-OVS_CHECK_DPCLS_AUTOVALIDATOR\n-OVS_CHECK_AVX512\n \n AC_ARG_VAR(KARCH, [Kernel Architecture String])\n AC_SUBST(KARCH)\ndiff --git a/lib/automake.mk b/lib/automake.mk\nindex bcd79f0d8..bf1aba0ed 100644\n--- a/lib/automake.mk\n+++ b/lib/automake.mk\n@@ -20,34 +20,6 @@ lib_libopenvswitch_la_LDFLAGS = \\\n         -Wl,--version-script=$(top_builddir)/lib/libopenvswitch.sym \\\n         $(AM_LDFLAGS)\n \n-if HAVE_AVX512F\n-if HAVE_LD_AVX512_GOOD\n-# Build library of avx512 code with CPU ISA CFLAGS enabled. This allows the\n-# compiler to use the ISA features required for the ISA optimized code-paths.\n-# Use LDFLAGS to compile only static library of this code, as it should be\n-# statically linked into vswitchd even if vswitchd is a shared build.\n-noinst_LTLIBRARIES += lib/libopenvswitchavx512.la\n-lib_libopenvswitch_la_LIBADD += lib/libopenvswitchavx512.la\n-lib_libopenvswitchavx512_la_CFLAGS = \\\n-\t-mavx512f \\\n-\t-mbmi \\\n-\t-mbmi2 \\\n-\t-fPIC \\\n-\t$(AM_CFLAGS)\n-if HAVE_AVX512BW\n-if HAVE_AVX512VL\n-lib_libopenvswitchavx512_la_CFLAGS += \\\n-\t-mavx512bw \\\n-\t-mavx512vl\n-lib_libopenvswitchavx512_la_SOURCES = \\\n-\tlib/dpif-netdev-lookup-avx512-gather.c\n-endif # HAVE_AVX512VL\n-endif # HAVE_AVX512BW\n-lib_libopenvswitchavx512_la_LDFLAGS = \\\n-\t-static\n-endif # HAVE_LD_AVX512_GOOD\n-endif # HAVE_AVX512F\n-\n # Build core vswitch libraries as before\n lib_libopenvswitch_la_SOURCES = \\\n \tlib/aes128.c \\\n@@ -117,20 +89,16 @@ lib_libopenvswitch_la_SOURCES = \\\n \tlib/dp-packet-gso.c \\\n \tlib/dp-packet-gso.h \\\n \tlib/dpdk.h \\\n-\tlib/dpif-netdev-lookup.h \\\n-\tlib/dpif-netdev-lookup.c \\\n-\tlib/dpif-netdev-lookup-autovalidator.c \\\n-\tlib/dpif-netdev-lookup-generic.c \\\n-\tlib/dpif-netdev.c \\\n-\tlib/dpif-netdev.h \\\n+\tlib/dpif-netdev-perf.c \\\n+\tlib/dpif-netdev-perf.h \\\n \tlib/dpif-netdev-private-dfc.c \\\n \tlib/dpif-netdev-private-dfc.h \\\n+\tlib/dpif-netdev-private-dpcls.c \\\n \tlib/dpif-netdev-private-dpcls.h \\\n \tlib/dpif-netdev-private-flow.h \\\n \tlib/dpif-netdev-private-thread.h \\\n-\tlib/dpif-netdev-private.h \\\n-\tlib/dpif-netdev-perf.c \\\n-\tlib/dpif-netdev-perf.h \\\n+\tlib/dpif-netdev.c \\\n+\tlib/dpif-netdev.h \\\n \tlib/dpif-offload.c \\\n \tlib/dpif-offload.h \\\n \tlib/dpif-offload-dummy.c \\\ndiff --git a/lib/dpif-netdev-lookup-autovalidator.c b/lib/dpif-netdev-lookup-autovalidator.c\ndeleted file mode 100644\nindex 475e1ab1e..000000000\n--- a/lib/dpif-netdev-lookup-autovalidator.c\n+++ /dev/null\n@@ -1,109 +0,0 @@\n-/*\n- * Copyright (c) 2020 Intel Corporation.\n- *\n- * Licensed under the Apache License, Version 2.0 (the \"License\");\n- * you may not use this file except in compliance with the License.\n- * You may obtain a copy of the License at:\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-\n-#include <config.h>\n-#include \"dpif-netdev.h\"\n-#include \"dpif-netdev-lookup.h\"\n-#include \"openvswitch/vlog.h\"\n-\n-VLOG_DEFINE_THIS_MODULE(dpif_lookup_autovalidator);\n-\n-/* This file implements an automated validator for subtable search\n- * implementations. It compares the results of the generic scalar search result\n- * with ISA optimized implementations.\n- *\n- * Note the goal is *NOT* to test the *specialized* versions of subtables, as\n- * the compiler performs the specialization - and we rely on the correctness of\n- * the compiler to not break those specialized variants.\n- *\n- * The goal is to ensure identical results of the different implementations,\n- * despite that the implementations may have different methods to get those\n- * results.\n- *\n- * Example: AVX-512 ISA uses different instructions and algorithm to the scalar\n- * implementation, however the results (rules[] output) must be the same.\n- */\n-\n-dpcls_subtable_lookup_func\n-dpcls_subtable_autovalidator_probe(uint32_t u0 OVS_UNUSED,\n-                                   uint32_t u1 OVS_UNUSED);\n-\n-static uint32_t\n-dpcls_subtable_autovalidator(struct dpcls_subtable *subtable,\n-                             uint32_t keys_map,\n-                             const struct netdev_flow_key *keys[],\n-                             struct dpcls_rule **rules_good)\n-{\n-    const uint32_t u0_bit_count = subtable->mf_bits_set_unit0;\n-    const uint32_t u1_bit_count = subtable->mf_bits_set_unit1;\n-\n-    /* Scalar generic - the \"known correct\" version. */\n-    dpcls_subtable_lookup_func lookup_good;\n-    lookup_good = dpcls_subtable_generic_probe(u0_bit_count, u1_bit_count);\n-\n-    /* Run actual scalar implementation to get known good results. */\n-    uint32_t matches_good = lookup_good(subtable, keys_map, keys, rules_good);\n-\n-    struct dpcls_subtable_lookup_info_t *lookup_funcs;\n-    int32_t lookup_func_count = dpcls_subtable_lookup_info_get(&lookup_funcs);\n-    if (lookup_func_count < 0) {\n-        VLOG_ERR(\"failed to get lookup subtable function implementations\\n\");\n-        return 0;\n-    }\n-\n-    /* Ensure the autovalidator is the 0th item in the lookup_funcs array. */\n-    ovs_assert(lookup_funcs[0].probe(0, 0) == dpcls_subtable_autovalidator);\n-\n-    /* Now compare all other implementations against known good results.\n-     * Note we start iterating from array[1], as 0 is the autotester itself.\n-     */\n-    for (int i = 1; i < lookup_func_count; i++) {\n-        dpcls_subtable_lookup_func lookup_func;\n-        lookup_func = lookup_funcs[i].probe(u0_bit_count,\n-                            u1_bit_count);\n-\n-        /* If its probe returns a function, then test it. */\n-        if (lookup_func) {\n-            struct dpcls_rule *rules_test[NETDEV_MAX_BURST];\n-            size_t rules_size = sizeof(struct dpcls_rule *) * NETDEV_MAX_BURST;\n-            memset(rules_test, 0, rules_size);\n-            uint32_t matches_test = lookup_func(subtable, keys_map, keys,\n-                                                rules_test);\n-\n-            /* Ensure same packets matched against subtable. */\n-            if (matches_good != matches_test) {\n-                VLOG_ERR(\"matches_good 0x%x != matches_test 0x%x in func %s\\n\",\n-                         matches_good, matches_test, lookup_funcs[i].name);\n-            }\n-\n-            /* Ensure rules matched are the same for scalar / others. */\n-            int j;\n-            ULLONG_FOR_EACH_1 (j, matches_test) {\n-                ovs_assert(rules_good[j] == rules_test[j]);\n-            }\n-        }\n-    }\n-\n-    return matches_good;\n-}\n-\n-dpcls_subtable_lookup_func\n-dpcls_subtable_autovalidator_probe(uint32_t u0 OVS_UNUSED,\n-                                   uint32_t u1 OVS_UNUSED)\n-{\n-    /* Always return the same validator tester, it works for all subtables. */\n-    return dpcls_subtable_autovalidator;\n-}\ndiff --git a/lib/dpif-netdev-lookup-avx512-gather.c b/lib/dpif-netdev-lookup-avx512-gather.c\ndeleted file mode 100644\nindex b916b2487..000000000\n--- a/lib/dpif-netdev-lookup-avx512-gather.c\n+++ /dev/null\n@@ -1,445 +0,0 @@\n-/*\n- * Copyright (c) 2020, Intel Corporation.\n- *\n- * Licensed under the Apache License, Version 2.0 (the \"License\");\n- * you may not use this file except in compliance with the License.\n- * You may obtain a copy of the License at:\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-\n-#ifdef __x86_64__\n-#if !defined(__CHECKER__)\n-\n-#include <config.h>\n-\n-#include \"dpif-netdev.h\"\n-#include \"dpif-netdev-lookup.h\"\n-\n-#include \"cmap.h\"\n-#include \"flow.h\"\n-#include \"pvector.h\"\n-#include \"openvswitch/vlog.h\"\n-\n-#include \"immintrin.h\"\n-\n-/* Each AVX512 register (zmm register in assembly notation) can contain up to\n- * 512 bits, which is equivalent to 8 uint64_t variables. This is the maximum\n- * number of miniflow blocks that can be processed in a single pass of the\n- * AVX512 code at a time.\n- */\n-#define NUM_U64_IN_ZMM_REG (8)\n-\n-/* This implementation of AVX512 gather allows up to 16 blocks of MF data to be\n- * present in the blocks_cache, hence the multiply by 2 in the blocks count.\n- */\n-#define MF_BLOCKS_PER_PACKET (NUM_U64_IN_ZMM_REG * 2)\n-\n-/* Blocks cache size is the maximum number of miniflow blocks that this\n- * implementation of lookup can handle.\n- */\n-#define BLOCKS_CACHE_SIZE (NETDEV_MAX_BURST * MF_BLOCKS_PER_PACKET)\n-\n-/* The gather instruction can handle a scale for the size of the items to\n- * gather. For uint64_t data, this scale is 8.\n- */\n-#define GATHER_SCALE_8 (8)\n-\n-\n-VLOG_DEFINE_THIS_MODULE(dpif_lookup_avx512_gather);\n-\n-static inline __m512i\n-_mm512_popcnt_epi64_manual(__m512i v_in)\n-{\n-    static const uint8_t pop_lut[64] = {\n-        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,\n-        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,\n-        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,\n-        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,\n-    };\n-    __m512i v_pop_lut = _mm512_loadu_si512(pop_lut);\n-\n-    __m512i v_in_srl8 = _mm512_srli_epi64(v_in, 4);\n-    __m512i v_nibble_mask = _mm512_set1_epi8(0xF);\n-    __m512i v_in_lo = _mm512_and_si512(v_in, v_nibble_mask);\n-    __m512i v_in_hi = _mm512_and_si512(v_in_srl8, v_nibble_mask);\n-\n-    __m512i v_lo_pop = _mm512_shuffle_epi8(v_pop_lut, v_in_lo);\n-    __m512i v_hi_pop = _mm512_shuffle_epi8(v_pop_lut, v_in_hi);\n-    __m512i v_u8_pop = _mm512_add_epi8(v_lo_pop, v_hi_pop);\n-\n-    return _mm512_sad_epu8(v_u8_pop, _mm512_setzero_si512());\n-}\n-\n-/* Wrapper function required to enable ISA. First check if the compiler\n- * supports the ISA itself. If the ISA is supported, enable it via the\n- * attribute target.  If the ISA is not supported by the compiler it indicates\n- * the compiler is too old or is not capable of compiling the requested ISA\n- * level, so fallback to the integer manual implementation.\n- */\n-#if HAVE_AVX512VPOPCNTDQ\n-static inline __m512i\n-__attribute__((__target__(\"avx512vpopcntdq\")))\n-_mm512_popcnt_epi64_wrapper(__m512i v_in)\n-{\n-    return _mm512_popcnt_epi64(v_in);\n-}\n-#else\n-static inline __m512i\n-_mm512_popcnt_epi64_wrapper(__m512i v_in)\n-{\n-    return _mm512_popcnt_epi64_manual(v_in);\n-}\n-#endif\n-\n-static inline uint64_t\n-netdev_rule_matches_key(const struct dpcls_rule *rule,\n-                        const uint32_t mf_bits_total,\n-                        const uint64_t * block_cache)\n-{\n-    const uint64_t *keyp = miniflow_get_values(&rule->flow.mf);\n-    const uint64_t *maskp = miniflow_get_values(&rule->mask->mf);\n-    const uint32_t lane_mask = (1ULL << mf_bits_total) - 1;\n-\n-    /* Always load a full cache line from blocks_cache. Other loads must be\n-     * trimmed to the amount of data required for mf_bits_total blocks.\n-     */\n-    uint32_t res_mask;\n-\n-    /* To avoid a loop, we have two iterations of a block of code here.\n-     * Note the scope brackets { } are used to avoid accidental variable usage\n-     * in the second iteration.\n-     */\n-    {\n-        __m512i v_blocks = _mm512_loadu_si512(&block_cache[0]);\n-        __m512i v_mask   = _mm512_maskz_loadu_epi64(lane_mask, &maskp[0]);\n-        __m512i v_key    = _mm512_maskz_loadu_epi64(lane_mask, &keyp[0]);\n-        __m512i v_data = _mm512_and_si512(v_blocks, v_mask);\n-        res_mask = _mm512_mask_cmpeq_epi64_mask(lane_mask, v_data, v_key);\n-    }\n-\n-    if (mf_bits_total > 8) {\n-        uint32_t lane_mask_gt8 = lane_mask >> 8;\n-        __m512i v_blocks = _mm512_loadu_si512(&block_cache[8]);\n-        __m512i v_mask   = _mm512_maskz_loadu_epi64(lane_mask_gt8, &maskp[8]);\n-        __m512i v_key    = _mm512_maskz_loadu_epi64(lane_mask_gt8, &keyp[8]);\n-        __m512i v_data = _mm512_and_si512(v_blocks, v_mask);\n-        uint32_t c = _mm512_mask_cmpeq_epi64_mask(lane_mask_gt8, v_data,\n-                                                  v_key);\n-        res_mask |= (c << 8);\n-    }\n-\n-    /* Returns 1 assuming result of SIMD compare is all blocks matching. */\n-    return res_mask == lane_mask;\n-}\n-\n-/* Takes u0 and u1 inputs, and gathers the next 8 blocks to be stored\n- * contiguously into the blocks cache. Note that the pointers and bitmasks\n- * passed into this function must be incremented for handling next 8 blocks.\n- *\n- * Register contents on entry:\n- *   v_u0: register with all u64 lanes filled with u0 bits.\n- *   v_u1: register with all u64 lanes filled with u1 bits.\n- *   pkt_blocks: pointer to packet blocks.\n- *   tbl_blocks: pointer to table blocks.\n- *   tbl_mf_masks: pointer to miniflow bitmasks for this subtable.\n- *   u1_bcast_msk: bitmask of lanes where u1 bits are used.\n- *   pkt_mf_u0_pop: population count of bits in u0 of the packet.\n- *   zero_mask: bitmask of lanes to zero as packet doesn't have mf bits set.\n- *   u64_lanes_mask: bitmask of lanes to process.\n- *   use_vpop: compile-time constant indicating if VPOPCNT instruction allowed.\n- */\n-static inline ALWAYS_INLINE __m512i\n-avx512_blocks_gather(__m512i v_u0,\n-                     __m512i v_u1,\n-                     const void *pkt_blocks,\n-                     const void *tbl_blocks,\n-                     const void *tbl_mf_masks,\n-                     __mmask64 u1_bcast_msk,\n-                     const uint64_t pkt_mf_u0_pop,\n-                     __mmask64 zero_mask,\n-                     __mmask64 u64_lanes_mask,\n-                     const uint32_t use_vpop)\n-{\n-        /* Suggest to compiler to load tbl blocks ahead of gather(). */\n-        __m512i v_tbl_blocks = _mm512_maskz_loadu_epi64(u64_lanes_mask,\n-                                                        tbl_blocks);\n-\n-        /* Blend u0 and u1 bits together for these 8 blocks. */\n-        __m512i v_pkt_bits = _mm512_mask_blend_epi64(u1_bcast_msk, v_u0, v_u1);\n-\n-        /* Load pre-created tbl miniflow bitmasks, bitwise AND with them. */\n-        __m512i v_tbl_masks = _mm512_maskz_loadu_epi64(u64_lanes_mask,\n-                                                      tbl_mf_masks);\n-        __m512i v_masks = _mm512_and_si512(v_pkt_bits, v_tbl_masks);\n-\n-        /* Calculate AVX512 popcount for u64 lanes using the native instruction\n-         * if available, or using emulation if not available.\n-         */\n-        __m512i v_popcnts;\n-        if (use_vpop) {\n-            v_popcnts = _mm512_popcnt_epi64_wrapper(v_masks);\n-        } else {\n-            v_popcnts = _mm512_popcnt_epi64_manual(v_masks);\n-        }\n-\n-        /* Add popcounts and offset for u1 bits. */\n-        __m512i v_idx_u0_offset = _mm512_maskz_set1_epi64(u1_bcast_msk,\n-                                                          pkt_mf_u0_pop);\n-        __m512i v_indexes = _mm512_add_epi64(v_popcnts, v_idx_u0_offset);\n-\n-        /* Gather u64 blocks from packet miniflow. */\n-        __m512i v_zeros = _mm512_setzero_si512();\n-        __m512i v_blocks = _mm512_mask_i64gather_epi64(v_zeros, u64_lanes_mask,\n-                                                       v_indexes, pkt_blocks,\n-                                                       GATHER_SCALE_8);\n-\n-        /* Mask pkt blocks with subtable blocks, k-mask to zero lanes. */\n-        __m512i v_masked_blocks = _mm512_maskz_and_epi64(zero_mask, v_blocks,\n-                                                         v_tbl_blocks);\n-        return v_masked_blocks;\n-}\n-\n-static inline uint32_t ALWAYS_INLINE\n-avx512_lookup_impl(struct dpcls_subtable *subtable,\n-                   uint32_t keys_map,\n-                   const struct netdev_flow_key *keys[],\n-                   struct dpcls_rule **rules,\n-                   const uint32_t bit_count_u0,\n-                   const uint32_t bit_count_u1,\n-                   const uint32_t use_vpop)\n-{\n-    OVS_ALIGNED_VAR(CACHE_LINE_SIZE)uint64_t block_cache[BLOCKS_CACHE_SIZE];\n-    uint32_t hashes[NETDEV_MAX_BURST];\n-\n-    const uint32_t n_pkts = __builtin_popcountll(keys_map);\n-    ovs_assert(NETDEV_MAX_BURST >= n_pkts);\n-\n-    const uint32_t bit_count_total = bit_count_u0 + bit_count_u1;\n-    const uint64_t bit_count_total_mask = (1ULL << bit_count_total) - 1;\n-\n-    const uint64_t tbl_u0 = subtable->mask.mf.map.bits[0];\n-    const uint64_t tbl_u1 = subtable->mask.mf.map.bits[1];\n-\n-    const uint64_t *tbl_blocks = miniflow_get_values(&subtable->mask.mf);\n-    const uint64_t *tbl_mf_masks = subtable->mf_masks;\n-\n-    int i;\n-    ULLONG_FOR_EACH_1 (i, keys_map) {\n-        /* Create mask register with packet-specific u0 offset.\n-         * Note that as 16 blocks can be handled in total, the width of the\n-         * mask register must be >=16.\n-         */\n-        const uint64_t pkt_mf_u0_bits = keys[i]->mf.map.bits[0];\n-        const uint64_t pkt_mf_u0_pop = __builtin_popcountll(pkt_mf_u0_bits);\n-        const __mmask64 u1_bcast_mask = (UINT64_MAX << bit_count_u0);\n-\n-        /* Broadcast u0, u1 bitmasks to 8x u64 lanes. */\n-        __m512i v_u0 = _mm512_set1_epi64(keys[i]->mf.map.bits[0]);\n-        __m512i v_u1 = _mm512_set1_epi64(keys[i]->mf.map.bits[1]);\n-\n-        /* Zero out bits that pkt doesn't have:\n-         * - 2x pext() to extract bits from packet miniflow as needed by TBL\n-         * - Shift u1 over by bit_count of u0, OR to create zero bitmask\n-         */\n-        uint64_t u0_to_zero = _pext_u64(keys[i]->mf.map.bits[0], tbl_u0);\n-        uint64_t u1_to_zero = _pext_u64(keys[i]->mf.map.bits[1], tbl_u1);\n-        const uint64_t zero_mask_wip = (u1_to_zero << bit_count_u0) |\n-                                       u0_to_zero;\n-        const uint64_t zero_mask = zero_mask_wip & bit_count_total_mask;\n-\n-        /* Get ptr to packet data blocks. */\n-        const uint64_t *pkt_blocks = miniflow_get_values(&keys[i]->mf);\n-\n-        /* Store first 8 blocks cache, full cache line aligned. */\n-        __m512i v_blocks = avx512_blocks_gather(v_u0, v_u1,\n-                                                &pkt_blocks[0],\n-                                                &tbl_blocks[0],\n-                                                &tbl_mf_masks[0],\n-                                                u1_bcast_mask,\n-                                                pkt_mf_u0_pop,\n-                                                zero_mask,\n-                                                bit_count_total_mask,\n-                                                use_vpop);\n-        _mm512_storeu_si512(&block_cache[i * MF_BLOCKS_PER_PACKET], v_blocks);\n-\n-        if (bit_count_total > 8) {\n-            /* Shift masks over by 8.\n-             * Pkt blocks pointer remains 0, it is incremented by popcount.\n-             * Move tbl and mf masks pointers forward.\n-             * Increase offsets by 8.\n-             * Re-run same gather code.\n-             */\n-            uint64_t zero_mask_gt8 = (zero_mask >> 8);\n-            uint64_t u1_bcast_mask_gt8 = (u1_bcast_mask >> 8);\n-            uint64_t bit_count_gt8_mask = bit_count_total_mask >> 8;\n-\n-            __m512i v_blocks_gt8 = avx512_blocks_gather(v_u0, v_u1,\n-                                                    &pkt_blocks[0],\n-                                                    &tbl_blocks[8],\n-                                                    &tbl_mf_masks[8],\n-                                                    u1_bcast_mask_gt8,\n-                                                    pkt_mf_u0_pop,\n-                                                    zero_mask_gt8,\n-                                                    bit_count_gt8_mask,\n-                                                    use_vpop);\n-            _mm512_storeu_si512(&block_cache[(i * MF_BLOCKS_PER_PACKET) + 8],\n-                                v_blocks_gt8);\n-        }\n-\n-    }\n-\n-    /* Hash the now linearized blocks of packet metadata. */\n-    ULLONG_FOR_EACH_1 (i, keys_map) {\n-        uint64_t *block_ptr = &block_cache[i * MF_BLOCKS_PER_PACKET];\n-        uint32_t hash = hash_add_words64(0, block_ptr, bit_count_total);\n-        hashes[i] = hash_finish(hash, bit_count_total * 8);\n-    }\n-\n-    /* Lookup: this returns a bitmask of packets where the hash table had\n-     * an entry for the given hash key. Presence of a hash key does not\n-     * guarantee matching the key, as there can be hash collisions.\n-     */\n-    uint32_t found_map;\n-    const struct cmap_node *nodes[NETDEV_MAX_BURST];\n-    found_map = cmap_find_batch(&subtable->rules, keys_map, hashes, nodes);\n-\n-    /* Verify that packet actually matched rule. If not found, a hash\n-     * collision has taken place, so continue searching with the next node.\n-     */\n-    ULLONG_FOR_EACH_1 (i, found_map) {\n-        struct dpcls_rule *rule;\n-\n-        CMAP_NODE_FOR_EACH (rule, cmap_node, nodes[i]) {\n-            const uint32_t cidx = i * MF_BLOCKS_PER_PACKET;\n-            uint32_t match = netdev_rule_matches_key(rule, bit_count_total,\n-                                                     &block_cache[cidx]);\n-            if (OVS_LIKELY(match)) {\n-                rules[i] = rule;\n-                subtable->hit_cnt++;\n-                goto next;\n-            }\n-        }\n-\n-        /* None of the found rules was a match.  Clear the i-th bit to\n-         * search for this key in the next subtable. */\n-        ULLONG_SET0(found_map, i);\n-    next:\n-        ;                     /* Keep Sparse happy. */\n-    }\n-\n-    return found_map;\n-}\n-\n-/* Use a different pattern to conditionally use the VPOPCNTDQ target attribute\n- * here.\n- * The usual pattern using a '#if HAVE_AVX512VPOPCNTDQ' type check won't work\n- * inside a macro.\n- * Define VPOPCNTDQ_TARGET which will either be the \"avx512vpopcntdq\" target\n- * attribute or nothing depending on AVX512VPOPCNTDQ support in the compiler.\n- */\n-#if HAVE_AVX512VPOPCNTDQ\n-#define VPOPCNTDQ_TARGET __attribute__((__target__(\"avx512vpopcntdq\")))\n-#else\n-#define VPOPCNTDQ_TARGET\n-#endif\n-\n-/* Expand out specialized functions with U0 and U1 bit attributes. As the\n- * AVX512 vpopcnt instruction is not supported on all AVX512 capable CPUs,\n- * create two functions for each miniflow signature. This allows the runtime\n- * CPU detection in probe() to select the ideal implementation.\n- */\n-#define DECLARE_OPTIMIZED_LOOKUP_FUNCTION(U0, U1)                             \\\n-    static uint32_t                                                           \\\n-    dpcls_avx512_gather_mf_##U0##_##U1(struct dpcls_subtable *subtable,       \\\n-                                       uint32_t keys_map,                     \\\n-                                       const struct netdev_flow_key *keys[],  \\\n-                                       struct dpcls_rule **rules)             \\\n-    {                                                                         \\\n-        const uint32_t use_vpop = 0;                                          \\\n-        return avx512_lookup_impl(subtable, keys_map, keys, rules,            \\\n-                                  U0, U1, use_vpop);                          \\\n-    }                                                                         \\\n-                                                                              \\\n-    static uint32_t VPOPCNTDQ_TARGET                                          \\\n-    dpcls_avx512_gather_mf_##U0##_##U1##_vpop(struct dpcls_subtable *subtable,\\\n-                                       uint32_t keys_map,                     \\\n-                                       const struct netdev_flow_key *keys[],  \\\n-                                       struct dpcls_rule **rules)             \\\n-    {                                                                         \\\n-        const uint32_t use_vpop = 1;                                          \\\n-        return avx512_lookup_impl(subtable, keys_map, keys, rules,            \\\n-                                  U0, U1, use_vpop);                          \\\n-    }                                                                         \\\n-\n-DECLARE_OPTIMIZED_LOOKUP_FUNCTION(9, 4)\n-DECLARE_OPTIMIZED_LOOKUP_FUNCTION(9, 1)\n-DECLARE_OPTIMIZED_LOOKUP_FUNCTION(8, 1)\n-DECLARE_OPTIMIZED_LOOKUP_FUNCTION(5, 3)\n-DECLARE_OPTIMIZED_LOOKUP_FUNCTION(5, 2)\n-DECLARE_OPTIMIZED_LOOKUP_FUNCTION(5, 1)\n-DECLARE_OPTIMIZED_LOOKUP_FUNCTION(4, 1)\n-DECLARE_OPTIMIZED_LOOKUP_FUNCTION(4, 0)\n-\n-/* Check if a specialized function is valid for the required subtable.\n- * The use_vpop variable is used to decide if the VPOPCNT instruction can be\n- * used or not.\n- */\n-#define CHECK_LOOKUP_FUNCTION(U0, U1, use_vpop)                               \\\n-    ovs_assert((U0 + U1) <= (NUM_U64_IN_ZMM_REG * 2));                        \\\n-    if (!f && u0_bits == U0 && u1_bits == U1) {                               \\\n-        if (use_vpop) {                                                       \\\n-            f = dpcls_avx512_gather_mf_##U0##_##U1##_vpop;                    \\\n-        } else {                                                              \\\n-            f = dpcls_avx512_gather_mf_##U0##_##U1;                           \\\n-        }                                                                     \\\n-    }\n-\n-static uint32_t\n-dpcls_avx512_gather_mf_any(struct dpcls_subtable *subtable, uint32_t keys_map,\n-                           const struct netdev_flow_key *keys[],\n-                           struct dpcls_rule **rules)\n-{\n-    const uint32_t use_vpop = 0;\n-    return avx512_lookup_impl(subtable, keys_map, keys, rules,\n-                              subtable->mf_bits_set_unit0,\n-                              subtable->mf_bits_set_unit1,\n-                              use_vpop);\n-}\n-\n-dpcls_subtable_lookup_func\n-dpcls_subtable_avx512_gather_probe__(uint32_t u0_bits, uint32_t u1_bits,\n-                                     bool use_vpop)\n-{\n-    dpcls_subtable_lookup_func f = NULL;\n-\n-    CHECK_LOOKUP_FUNCTION(9, 4, use_vpop);\n-    CHECK_LOOKUP_FUNCTION(9, 1, use_vpop);\n-    CHECK_LOOKUP_FUNCTION(8, 1, use_vpop);\n-    CHECK_LOOKUP_FUNCTION(5, 3, use_vpop);\n-    CHECK_LOOKUP_FUNCTION(5, 2, use_vpop);\n-    CHECK_LOOKUP_FUNCTION(5, 1, use_vpop);\n-    CHECK_LOOKUP_FUNCTION(4, 1, use_vpop);\n-    CHECK_LOOKUP_FUNCTION(4, 0, use_vpop);\n-\n-    /* Check if the _any looping version of the code can perform this miniflow\n-     * lookup. Performance gain may be less pronounced due to non-specialized\n-     * hashing, however there is usually a good performance win overall.\n-     */\n-    if (!f && (u0_bits + u1_bits) < (NUM_U64_IN_ZMM_REG * 2)) {\n-        f = dpcls_avx512_gather_mf_any;\n-        VLOG_INFO_ONCE(\"Using non-specialized AVX512 lookup for subtable\"\n-                       \" (%d,%d) and possibly others.\", u0_bits, u1_bits);\n-    }\n-\n-    return f;\n-}\n-\n-#endif /* CHECKER */\n-#endif /* __x86_64__ */\ndiff --git a/lib/dpif-netdev-lookup.c b/lib/dpif-netdev-lookup.c\ndeleted file mode 100644\nindex 4c1379aa5..000000000\n--- a/lib/dpif-netdev-lookup.c\n+++ /dev/null\n@@ -1,193 +0,0 @@\n-/*\n- * Copyright (c) 2020 Intel Corporation.\n- *\n- * Licensed under the Apache License, Version 2.0 (the \"License\");\n- * you may not use this file except in compliance with the License.\n- * You may obtain a copy of the License at:\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-\n-#include <config.h>\n-#include <errno.h>\n-#include \"dpif-netdev-lookup.h\"\n-\n-#include \"cpu.h\"\n-#include \"openvswitch/vlog.h\"\n-\n-VLOG_DEFINE_THIS_MODULE(dpif_netdev_lookup);\n-#define DPCLS_IMPL_AVX512_CHECK (__x86_64__ && HAVE_AVX512F \\\n-    && HAVE_LD_AVX512_GOOD && HAVE_AVX512BW && __SSE4_2__)\n-\n-#if DPCLS_IMPL_AVX512_CHECK\n-static dpcls_subtable_lookup_func\n-dpcls_subtable_avx512_gather_probe(uint32_t u0_bits, uint32_t u1_bits)\n-{\n-    if (!cpu_has_isa(OVS_CPU_ISA_X86_AVX512F)\n-        || !cpu_has_isa(OVS_CPU_ISA_X86_BMI2)) {\n-        return NULL;\n-    }\n-\n-    return dpcls_subtable_avx512_gather_probe__(u0_bits, u1_bits,\n-        cpu_has_isa(OVS_CPU_ISA_X86_VPOPCNTDQ));\n-}\n-#endif\n-\n-/* Actual list of implementations goes here */\n-static struct dpcls_subtable_lookup_info_t subtable_lookups[] = {\n-    /* The autovalidator implementation will not be used by default, it must\n-     * be enabled at compile time to be the default lookup implementation. The\n-     * user may enable it at runtime using the normal \"prio-set\" command if\n-     * desired. The compile time default switch is here to enable all unit\n-     * tests to transparently run with the autovalidator.\n-     */\n-#ifdef DPCLS_AUTOVALIDATOR_DEFAULT\n-    { .prio = 255,\n-#else\n-    { .prio = 0,\n-#endif\n-      .probe = dpcls_subtable_autovalidator_probe,\n-      .name = \"autovalidator\",\n-      .usage_cnt = ATOMIC_COUNT_INIT(0), },\n-\n-    /* The default scalar C code implementation. */\n-    { .prio = 1,\n-      .probe = dpcls_subtable_generic_probe,\n-      .name = \"generic\",\n-      .usage_cnt = ATOMIC_COUNT_INIT(0), },\n-\n-#if DPCLS_IMPL_AVX512_CHECK\n-    /* Only available on x86_64 bit builds with SSE 4.2 used for OVS core. */\n-    { .prio = 0,\n-      .probe = dpcls_subtable_avx512_gather_probe,\n-      .name = \"avx512_gather\",\n-      .usage_cnt = ATOMIC_COUNT_INIT(0), },\n-#else\n-    /* Disabling AVX512 at compile time, as compile time requirements not met.\n-     * This could be due to a number of reasons:\n-     *  1) core OVS is not compiled with SSE4.2 instruction set.\n-     *     The SSE42 instructions are required to use CRC32 ISA for high-\n-     *     performance hashing. Consider ./configure of OVS with -msse42 (or\n-     *     newer) to enable CRC32 hashing and higher performance.\n-     *  2) The assembler in binutils versions 2.30 and 2.31 has bugs in AVX512\n-     *     assembly. Compile time probes check for this assembler issue, and\n-     *     disable the HAVE_LD_AVX512_GOOD check if an issue is detected.\n-     *     Please upgrade binutils, or backport this binutils fix commit:\n-     *     2069ccaf8dc28ea699bd901fdd35d90613e4402a\n-     */\n-#endif\n-};\n-\n-int\n-dpcls_subtable_lookup_info_get(struct dpcls_subtable_lookup_info_t **out_ptr)\n-{\n-    if (out_ptr == NULL) {\n-        return -1;\n-    }\n-\n-    *out_ptr = subtable_lookups;\n-    return ARRAY_SIZE(subtable_lookups);\n-}\n-\n-/* sets the priority of the lookup function with \"name\". */\n-int\n-dpcls_subtable_set_prio(const char *name, uint8_t priority)\n-{\n-    for (int i = 0; i < ARRAY_SIZE(subtable_lookups); i++) {\n-        if (strcmp(name, subtable_lookups[i].name) == 0) {\n-                subtable_lookups[i].prio = priority;\n-                VLOG_INFO(\"Subtable function '%s' set priority to %d\\n\",\n-                         name, priority);\n-                return 0;\n-        }\n-    }\n-    VLOG_WARN(\"Subtable function '%s' not found, failed to set priority\\n\",\n-              name);\n-    return -EINVAL;\n-}\n-\n-dpcls_subtable_lookup_func\n-dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count,\n-                             struct dpcls_subtable_lookup_info_t **info)\n-{\n-    struct dpcls_subtable_lookup_info_t *best_info = NULL;\n-    dpcls_subtable_lookup_func best_func = NULL;\n-    int prio = -1;\n-\n-    /* Iter over each subtable impl, and get highest priority one. */\n-    for (int i = 0; i < ARRAY_SIZE(subtable_lookups); i++) {\n-        struct dpcls_subtable_lookup_info_t *impl_info = &subtable_lookups[i];\n-        dpcls_subtable_lookup_func probed_func;\n-\n-        if (impl_info->prio <= prio) {\n-            continue;\n-        }\n-\n-        probed_func = subtable_lookups[i].probe(u0_bit_count,\n-                                                u1_bit_count);\n-        if (!probed_func) {\n-            continue;\n-        }\n-\n-        best_func = probed_func;\n-        best_info = impl_info;\n-        prio = impl_info->prio;\n-    }\n-\n-    /* Programming error - we must always return a valid func ptr. */\n-    ovs_assert(best_func != NULL && best_info != NULL);\n-\n-    VLOG_DBG(\"Subtable lookup function '%s' with units (%d,%d), priority %d\\n\",\n-             best_info->name, u0_bit_count, u1_bit_count, prio);\n-\n-    if (info) {\n-        *info = best_info;\n-    }\n-    return best_func;\n-}\n-\n-void\n-dpcls_info_inc_usage(struct dpcls_subtable_lookup_info_t *info)\n-{\n-    if (info) {\n-        atomic_count_inc(&info->usage_cnt);\n-    }\n-}\n-\n-void\n-dpcls_info_dec_usage(struct dpcls_subtable_lookup_info_t *info)\n-{\n-    if (info) {\n-        atomic_count_dec(&info->usage_cnt);\n-    }\n-}\n-\n-void\n-dpcls_impl_print_stats(struct ds *reply)\n-{\n-    struct dpcls_subtable_lookup_info_t *lookup_funcs = NULL;\n-    int count = dpcls_subtable_lookup_info_get(&lookup_funcs);\n-\n-    /* Add all DPCLS functions to reply string. */\n-    ds_put_cstr(reply, \"Available dpcls implementations:\\n\");\n-\n-    for (int i = 0; i < count; i++) {\n-        ds_put_format(reply, \"  %s (Use count: %d, Priority: %d\",\n-                      lookup_funcs[i].name,\n-                      atomic_count_get(&lookup_funcs[i].usage_cnt),\n-                      lookup_funcs[i].prio);\n-\n-        if (ds_last(reply) == ' ') {\n-            ds_put_cstr(reply, \"none\");\n-        }\n-\n-        ds_put_cstr(reply, \")\\n\");\n-    }\n-\n-}\ndiff --git a/lib/dpif-netdev-lookup.h b/lib/dpif-netdev-lookup.h\ndeleted file mode 100644\nindex ac6d97317..000000000\n--- a/lib/dpif-netdev-lookup.h\n+++ /dev/null\n@@ -1,92 +0,0 @@\n-/*\n- * Copyright (c) 2020 Intel Corporation.\n- *\n- * Licensed under the Apache License, Version 2.0 (the \"License\");\n- * you may not use this file except in compliance with the License.\n- * You may obtain a copy of the License at:\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-\n-#ifndef DPIF_NETDEV_LOOKUP_H\n-#define DPIF_NETDEV_LOOKUP_H 1\n-\n-#include <config.h>\n-#include \"dpif-netdev.h\"\n-#include \"dpif-netdev-private-dpcls.h\"\n-#include \"dpif-netdev-private-thread.h\"\n-\n-/* Function to perform a probe for the subtable bit fingerprint.\n- * Returns NULL if not valid, or a valid function pointer to call for this\n- * subtable on success.\n- */\n-typedef\n-dpcls_subtable_lookup_func (*dpcls_subtable_probe_func)(uint32_t u0_bit_count,\n-                                                        uint32_t u1_bit_count);\n-\n-/* Prototypes for subtable implementations */\n-dpcls_subtable_lookup_func\n-dpcls_subtable_autovalidator_probe(uint32_t u0_bit_count,\n-                                   uint32_t u1_bit_count);\n-\n-/* Probe function to select a specialized version of the generic lookup\n- * implementation. This provides performance benefit due to compile-time\n- * optimizations such as loop-unrolling. These are enabled by the compile-time\n- * constants in the specific function implementations.\n- */\n-dpcls_subtable_lookup_func\n-dpcls_subtable_generic_probe(uint32_t u0_bit_count, uint32_t u1_bit_count);\n-\n-/* Probe function for AVX-512 gather implementation */\n-dpcls_subtable_lookup_func\n-dpcls_subtable_avx512_gather_probe__(uint32_t u0_bit_cnt, uint32_t u1_bit_cnt,\n-                                     bool use_vpop);\n-\n-\n-/* Subtable registration and iteration helpers */\n-struct dpcls_subtable_lookup_info_t {\n-    /* higher priority gets used over lower values. This allows deployments\n-     * to select the best implementation for the use-case.\n-     */\n-    uint8_t prio;\n-\n-    /* Probe function: tests if the (u0,u1) combo is supported. If not\n-     * supported, this function returns NULL. If supported, a function pointer\n-     * is returned which when called will perform the lookup on the subtable.\n-     */\n-    dpcls_subtable_probe_func probe;\n-\n-    /* Human readable name, used in setting subtable priority commands */\n-    const char *name;\n-\n-    /* Counter which holds the usage count of each implementations. */\n-    atomic_count usage_cnt;\n-};\n-\n-int dpcls_subtable_set_prio(const char *name, uint8_t priority);\n-void dpcls_info_inc_usage(struct dpcls_subtable_lookup_info_t *info);\n-void dpcls_info_dec_usage(struct dpcls_subtable_lookup_info_t *info);\n-\n-/* Lookup the best subtable lookup implementation for the given u0,u1 count. */\n-dpcls_subtable_lookup_func\n-dpcls_subtable_get_best_impl(uint32_t u0_bit_count, uint32_t u1_bit_count,\n-                             struct dpcls_subtable_lookup_info_t **info);\n-\n-/* Retrieve the array of lookup implementations for iteration.\n- * On error, returns a negative number.\n- * On success, returns the size of the arrays pointed to by the out parameter.\n- */\n-int\n-dpcls_subtable_lookup_info_get(struct dpcls_subtable_lookup_info_t **out_ptr);\n-\n-/* Prints dpcls subtables in use for different implementations. */\n-void\n-dpcls_impl_print_stats(struct ds *reply);\n-\n-#endif /* dpif-netdev-lookup.h */\ndiff --git a/lib/dpif-netdev-lookup-generic.c b/lib/dpif-netdev-private-dpcls.c\nsimilarity index 91%\nrename from lib/dpif-netdev-lookup-generic.c\nrename to lib/dpif-netdev-private-dpcls.c\nindex 76f92dd5e..31e1a357e 100644\n--- a/lib/dpif-netdev-lookup-generic.c\n+++ b/lib/dpif-netdev-private-dpcls.c\n@@ -17,7 +17,7 @@\n \n #include <config.h>\n #include \"dpif-netdev.h\"\n-#include \"dpif-netdev-lookup.h\"\n+#include \"dpif-netdev-private-dpcls.h\"\n \n #include \"bitmap.h\"\n #include \"cmap.h\"\n@@ -31,7 +31,7 @@\n #include \"packets.h\"\n #include \"pvector.h\"\n \n-VLOG_DEFINE_THIS_MODULE(dpif_lookup_generic);\n+VLOG_DEFINE_THIS_MODULE(dpif_netdev_dpcls);\n \n /* Lookup functions below depends on the internal structure of flowmap. */\n BUILD_ASSERT_DECL(FLOWMAP_UNITS == 2);\n@@ -176,12 +176,12 @@ netdev_rule_matches_key(const struct dpcls_rule *rule,\n  * compiler might decide to not inline, and performance will suffer.\n  */\n static inline uint32_t ALWAYS_INLINE\n-lookup_generic_impl(struct dpcls_subtable *subtable,\n-                    uint32_t keys_map,\n-                    const struct netdev_flow_key *keys[],\n-                    struct dpcls_rule **rules,\n-                    const uint32_t bit_count_u0,\n-                    const uint32_t bit_count_u1)\n+lookup_impl(struct dpcls_subtable *subtable,\n+            uint32_t keys_map,\n+            const struct netdev_flow_key *keys[],\n+            struct dpcls_rule **rules,\n+            const uint32_t bit_count_u0,\n+            const uint32_t bit_count_u1)\n {\n     const uint32_t n_pkts = count_1bits(keys_map);\n     ovs_assert(NETDEV_MAX_BURST >= n_pkts);\n@@ -265,9 +265,9 @@ dpcls_subtable_lookup_generic(struct dpcls_subtable *subtable,\n      * compilers available optimizations, this function has lower performance\n      * than the below specialized functions.\n      */\n-    return lookup_generic_impl(subtable, keys_map, keys, rules,\n-                               subtable->mf_bits_set_unit0,\n-                               subtable->mf_bits_set_unit1);\n+    return lookup_impl(subtable, keys_map, keys, rules,\n+                       subtable->mf_bits_set_unit0,\n+                       subtable->mf_bits_set_unit1);\n }\n \n /* Expand out specialized functions with U0 and U1 bit attributes. */\n@@ -279,7 +279,7 @@ dpcls_subtable_lookup_generic(struct dpcls_subtable *subtable,\n                                          const struct netdev_flow_key *keys[],\\\n                                          struct dpcls_rule **rules)           \\\n     {                                                                         \\\n-        return lookup_generic_impl(subtable, keys_map, keys, rules, U0, U1);  \\\n+        return lookup_impl(subtable, keys_map, keys, rules, U0, U1);          \\\n     }                                                                         \\\n \n DECLARE_OPTIMIZED_LOOKUP_FUNCTION(9, 4)\n@@ -297,14 +297,9 @@ DECLARE_OPTIMIZED_LOOKUP_FUNCTION(4, 0)\n         f = dpcls_subtable_lookup_mf_u0w##U0##_u1w##U1;                       \\\n     }\n \n-/* Probe function to lookup an available specialized function.\n- * If capable to run the requested miniflow fingerprint, this function returns\n- * the most optimal implementation for that miniflow fingerprint.\n- * @retval Non-NULL A valid function to handle the miniflow bit pattern\n- * @retval NULL The requested miniflow is not supported by this implementation.\n- */\n+/* Probe function to lookup an available specialized function. */\n dpcls_subtable_lookup_func\n-dpcls_subtable_generic_probe(uint32_t u0_bits, uint32_t u1_bits)\n+dpcls_subtable_lookup_probe(uint32_t u0_bits, uint32_t u1_bits)\n {\n     dpcls_subtable_lookup_func f = NULL;\n \n@@ -318,10 +313,10 @@ dpcls_subtable_generic_probe(uint32_t u0_bits, uint32_t u1_bits)\n     CHECK_LOOKUP_FUNCTION(4, 0);\n \n     if (f) {\n-        VLOG_DBG(\"Subtable using Generic Optimized for u0 %d, u1 %d\\n\",\n+        VLOG_DBG(\"Subtable using lookup function optimized for u0 %d, u1 %d\\n\",\n                  u0_bits, u1_bits);\n     } else {\n-        /* Always return the generic function. */\n+        /* Return generic function, if there is no specialized variant. */\n         f = dpcls_subtable_lookup_generic;\n     }\n \ndiff --git a/lib/dpif-netdev-private-dpcls.h b/lib/dpif-netdev-private-dpcls.h\nindex bbf28bcdb..7949134bb 100644\n--- a/lib/dpif-netdev-private-dpcls.h\n+++ b/lib/dpif-netdev-private-dpcls.h\n@@ -63,6 +63,12 @@ uint32_t (*dpcls_subtable_lookup_func)(struct dpcls_subtable *subtable,\n                                        const struct netdev_flow_key *keys[],\n                                        struct dpcls_rule **rules);\n \n+/* Probe function to lookup an available specialized lookup function.\n+ * Returns the most optimal implementation for the miniflow fingerprint.\n+ */\n+dpcls_subtable_lookup_func dpcls_subtable_lookup_probe(uint32_t u0_bits,\n+                                                       uint32_t u1_bits);\n+\n /* A set of rules that all have the same fields wildcarded. */\n struct dpcls_subtable {\n     /* The fields are only used by writers. */\n@@ -83,11 +89,8 @@ struct dpcls_subtable {\n     /* The lookup function to use for this subtable. If there is a known\n      * property of the subtable (eg: only 3 bits of miniflow metadata is\n      * used for the lookup) then this can point at an optimized version of\n-     * the lookup function for this particular subtable. The lookup function\n-     * can be used at any time by a PMD thread, so it's declared as an atomic\n-     * here to prevent garbage from being read. */\n-    ATOMIC(dpcls_subtable_lookup_func) lookup_func;\n-    struct dpcls_subtable_lookup_info_t *lookup_func_info;\n+     * the lookup function for this particular subtable. */\n+    dpcls_subtable_lookup_func lookup_func;\n \n     /* Caches the masks to match a packet to, reducing runtime calculations. */\n     uint64_t *mf_masks;\ndiff --git a/lib/dpif-netdev-private-flow.h b/lib/dpif-netdev-private-flow.h\nindex 308c5113f..f05382626 100644\n--- a/lib/dpif-netdev-private-flow.h\n+++ b/lib/dpif-netdev-private-flow.h\n@@ -18,9 +18,6 @@\n #ifndef DPIF_NETDEV_PRIVATE_FLOW_H\n #define DPIF_NETDEV_PRIVATE_FLOW_H 1\n \n-#include \"dpif.h\"\n-#include \"dpif-netdev-private-dpcls.h\"\n-\n #include <stdbool.h>\n #include <stdint.h>\n \ndiff --git a/lib/dpif-netdev-private-thread.h b/lib/dpif-netdev-private-thread.h\nindex bc76c86d2..2ee855ca4 100644\n--- a/lib/dpif-netdev-private-thread.h\n+++ b/lib/dpif-netdev-private-thread.h\n@@ -18,10 +18,6 @@\n #ifndef DPIF_NETDEV_PRIVATE_THREAD_H\n #define DPIF_NETDEV_PRIVATE_THREAD_H 1\n \n-#include \"dpif.h\"\n-#include \"dpif-netdev-perf.h\"\n-#include \"dpif-netdev-private-dfc.h\"\n-\n #include <stdbool.h>\n #include <stdint.h>\n \ndiff --git a/lib/dpif-netdev-private.h b/lib/dpif-netdev-private.h\ndeleted file mode 100644\nindex 029b23a22..000000000\n--- a/lib/dpif-netdev-private.h\n+++ /dev/null\n@@ -1,52 +0,0 @@\n-/*\n- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2015 Nicira, Inc.\n- * Copyright (c) 2019 Intel Corporation.\n- *\n- * Licensed under the Apache License, Version 2.0 (the \"License\");\n- * you may not use this file except in compliance with the License.\n- * You may obtain a copy of the License at:\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-\n-#ifndef DPIF_NETDEV_PRIVATE_H\n-#define DPIF_NETDEV_PRIVATE_H 1\n-\n-/* This header includes the various dpif-netdev components' header\n- * files in the appropriate order. Unfortunately there is a strict\n- * requirement in the include order due to dependences between components.\n- * E.g:\n- *  DFC/EMC/SMC requires the netdev_flow_key struct\n- *  PMD thread requires DFC_flow struct\n- *\n- */\n-#include \"dpif-netdev-private-flow.h\"\n-#include \"dpif-netdev-private-dpcls.h\"\n-#include \"dpif-netdev-private-dfc.h\"\n-#include \"dpif-netdev-private-thread.h\"\n-\n-/* Allow other implementations to lookup the DPCLS instances. */\n-struct dpcls *\n-dp_netdev_pmd_lookup_dpcls(struct dp_netdev_pmd_thread *pmd,\n-                           odp_port_t in_port);\n-\n-/* Allow other implementations to execute actions on a batch. */\n-void\n-dp_netdev_batch_execute(struct dp_netdev_pmd_thread *pmd,\n-                        struct dp_packet_batch *packets,\n-                        struct dpcls_rule *rule,\n-                        uint32_t bytes,\n-                        uint16_t tcp_flags);\n-\n-int\n-dp_netdev_hw_flow(const struct dp_netdev_pmd_thread *pmd,\n-                  struct dp_packet *packet,\n-                  struct dp_netdev_flow **flow);\n-\n-#endif /* dpif-netdev-private.h */\ndiff --git a/lib/dpif-netdev-unixctl.man b/lib/dpif-netdev-unixctl.man\nindex 2b2450884..c78a87550 100644\n--- a/lib/dpif-netdev-unixctl.man\n+++ b/lib/dpif-netdev-unixctl.man\n@@ -229,15 +229,3 @@ recirculation (only in balance-tcp mode).\n When this is the case, the above command prints the load-balancing information\n of the bonds configured in datapath \\fIdp\\fR showing the interface associated\n with each bucket (hash).\n-.\n-.IP \"\\fBdpif-netdev/subtable-lookup-prio-get\\fR\"\n-Lists the DPCLS implementations or lookup functions that are available as well\n-as their priorities.\n-.\n-.IP \"\\fBdpif-netdev/subtable-lookup-prio-set\\fR \\fIlookup_function\\fR \\\n-\\fIprio\\fR\"\n-Sets the priority of a lookup function by name, \\fIlookup_function\\fR, and\n-priority, \\fIprio\\fR, which should be a positive integer value.  The highest\n-priority lookup function is used for classification.\n-\n-The number of affected dpcls ports and subtables is returned.\ndiff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c\nindex 9ae5e960e..d02344637 100644\n--- a/lib/dpif-netdev.c\n+++ b/lib/dpif-netdev.c\n@@ -16,9 +16,6 @@\n \n #include <config.h>\n #include \"dpif-netdev.h\"\n-#include \"dpif-netdev-private.h\"\n-#include \"dpif-netdev-private-dfc.h\"\n-#include \"dpif-offload.h\"\n \n #include <ctype.h>\n #include <errno.h>\n@@ -45,8 +42,12 @@\n #include \"csum.h\"\n #include \"dp-packet.h\"\n #include \"dpif.h\"\n-#include \"dpif-netdev-lookup.h\"\n #include \"dpif-netdev-perf.h\"\n+#include \"dpif-netdev-private-dfc.h\"\n+#include \"dpif-netdev-private-dpcls.h\"\n+#include \"dpif-netdev-private-flow.h\"\n+#include \"dpif-netdev-private-thread.h\"\n+#include \"dpif-offload.h\"\n #include \"dpif-provider.h\"\n #include \"dummy.h\"\n #include \"fat-rwlock.h\"\n@@ -199,7 +200,6 @@ struct dp_packet_flow_map {\n static void dpcls_init(struct dpcls *);\n static void dpcls_destroy(struct dpcls *);\n static void dpcls_sort_subtable_vector(struct dpcls *);\n-static uint32_t dpcls_subtable_lookup_reprobe(struct dpcls *cls);\n static void dpcls_insert(struct dpcls *, struct dpcls_rule *,\n                          const struct netdev_flow_key *mask);\n static void dpcls_remove(struct dpcls *, struct dpcls_rule *);\n@@ -561,9 +561,8 @@ dpif_netdev_xps_revalidate_pmd(const struct dp_netdev_pmd_thread *pmd,\n                                bool purge);\n static int dpif_netdev_xps_get_tx_qid(const struct dp_netdev_pmd_thread *pmd,\n                                       struct tx_port *tx);\n-inline struct dpcls *\n-dp_netdev_pmd_lookup_dpcls(struct dp_netdev_pmd_thread *pmd,\n-                           odp_port_t in_port);\n+static inline struct dpcls * dp_netdev_pmd_lookup_dpcls(\n+    struct dp_netdev_pmd_thread *pmd, odp_port_t in_port);\n \n static void dp_netdev_request_reconfigure(struct dp_netdev *dp);\n static inline bool\n@@ -931,98 +930,6 @@ sorted_poll_thread_list(struct dp_netdev *dp,\n     *n = k;\n }\n \n-static void\n-dpif_netdev_subtable_lookup_get(struct unixctl_conn *conn, int argc OVS_UNUSED,\n-                                const char *argv[] OVS_UNUSED,\n-                                void *aux OVS_UNUSED)\n-{\n-    struct ds reply = DS_EMPTY_INITIALIZER;\n-\n-    dpcls_impl_print_stats(&reply);\n-    unixctl_command_reply(conn, ds_cstr(&reply));\n-    ds_destroy(&reply);\n-}\n-\n-static void\n-dpif_netdev_subtable_lookup_set(struct unixctl_conn *conn, int argc OVS_UNUSED,\n-                                const char *argv[], void *aux OVS_UNUSED)\n-{\n-    /* This function requires 2 parameters (argv[1] and argv[2]) to execute.\n-     *   argv[1] is subtable name\n-     *   argv[2] is priority\n-     */\n-    const char *func_name = argv[1];\n-\n-    errno = 0;\n-    char *err_char;\n-    uint32_t new_prio = strtoul(argv[2], &err_char, 10);\n-    uint32_t lookup_dpcls_changed = 0;\n-    uint32_t lookup_subtable_changed = 0;\n-    struct shash_node *node;\n-    if (errno != 0 || new_prio > UINT8_MAX) {\n-        unixctl_command_reply_error(conn,\n-            \"error converting priority, use integer in range 0-255\\n\");\n-        return;\n-    }\n-\n-    int32_t err = dpcls_subtable_set_prio(func_name, new_prio);\n-    if (err) {\n-        unixctl_command_reply_error(conn,\n-            \"error, subtable lookup function not found\\n\");\n-        return;\n-    }\n-\n-    ovs_mutex_lock(&dp_netdev_mutex);\n-    SHASH_FOR_EACH (node, &dp_netdevs) {\n-        struct dp_netdev *dp = node->data;\n-\n-        /* Get PMD threads list, required to get DPCLS instances. */\n-        size_t n;\n-        struct dp_netdev_pmd_thread **pmd_list;\n-        sorted_poll_thread_list(dp, &pmd_list, &n);\n-\n-        /* take port mutex as HMAP iters over them. */\n-        ovs_rwlock_rdlock(&dp->port_rwlock);\n-\n-        for (size_t i = 0; i < n; i++) {\n-            struct dp_netdev_pmd_thread *pmd = pmd_list[i];\n-            if (pmd->core_id == NON_PMD_CORE_ID) {\n-                continue;\n-            }\n-\n-            struct dp_netdev_port *port = NULL;\n-            HMAP_FOR_EACH (port, node, &dp->ports) {\n-                odp_port_t in_port = port->port_no;\n-                struct dpcls *cls = dp_netdev_pmd_lookup_dpcls(pmd, in_port);\n-                if (!cls) {\n-                    continue;\n-                }\n-                ovs_mutex_lock(&pmd->flow_mutex);\n-                uint32_t subtbl_changes = dpcls_subtable_lookup_reprobe(cls);\n-                ovs_mutex_unlock(&pmd->flow_mutex);\n-                if (subtbl_changes) {\n-                    lookup_dpcls_changed++;\n-                    lookup_subtable_changed += subtbl_changes;\n-                }\n-            }\n-        }\n-\n-        /* release port mutex before netdev mutex. */\n-        ovs_rwlock_unlock(&dp->port_rwlock);\n-        free(pmd_list);\n-    }\n-    ovs_mutex_unlock(&dp_netdev_mutex);\n-\n-    struct ds reply = DS_EMPTY_INITIALIZER;\n-    ds_put_format(&reply,\n-        \"Lookup priority change affected %d dpcls ports and %d subtables.\\n\",\n-        lookup_dpcls_changed, lookup_subtable_changed);\n-    const char *reply_str = ds_cstr(&reply);\n-    unixctl_command_reply(conn, reply_str);\n-    VLOG_INFO(\"%s\", reply_str);\n-    ds_destroy(&reply);\n-}\n-\n static void\n dpif_netdev_pmd_rebalance(struct unixctl_conn *conn, int argc,\n                           const char *argv[], void *aux OVS_UNUSED)\n@@ -1289,16 +1196,6 @@ dpif_netdev_init(void)\n     unixctl_command_register(\"dpif-netdev/bond-show\", \"[dp]\",\n                              0, 1, dpif_netdev_bond_show,\n                              NULL);\n-    unixctl_command_register(\"dpif-netdev/subtable-lookup-prio-set\",\n-                             \"[lookup_func] [prio]\",\n-                             2, 2, dpif_netdev_subtable_lookup_set,\n-                             NULL);\n-    unixctl_command_register(\"dpif-netdev/subtable-lookup-info-get\", \"\",\n-                             0, 0, dpif_netdev_subtable_lookup_get,\n-                             NULL);\n-    unixctl_command_register(\"dpif-netdev/subtable-lookup-prio-get\", NULL,\n-                             0, 0, dpif_netdev_subtable_lookup_get,\n-                             NULL);\n     return 0;\n }\n \n@@ -2049,7 +1946,7 @@ void dp_netdev_flow_unref(struct dp_netdev_flow *flow)\n     }\n }\n \n-inline struct dpcls *\n+static inline struct dpcls *\n dp_netdev_pmd_lookup_dpcls(struct dp_netdev_pmd_thread *pmd,\n                            odp_port_t in_port)\n {\n@@ -7265,24 +7162,6 @@ packet_batch_per_flow_execute(struct packet_batch_per_flow *batch,\n                               actions->actions, actions->size);\n }\n \n-void\n-dp_netdev_batch_execute(struct dp_netdev_pmd_thread *pmd,\n-                        struct dp_packet_batch *packets,\n-                        struct dpcls_rule *rule,\n-                        uint32_t bytes,\n-                        uint16_t tcp_flags)\n-{\n-    /* Gets action* from the rule. */\n-    struct dp_netdev_flow *flow = dp_netdev_flow_cast(rule);\n-    struct dp_netdev_actions *actions = dp_netdev_flow_get_actions(flow);\n-\n-    dp_netdev_flow_used(flow, dp_packet_batch_size(packets), bytes,\n-                        tcp_flags, pmd->ctx.now / 1000);\n-    const uint32_t steal = 1;\n-    dp_netdev_execute_actions(pmd, packets, steal, &flow->flow,\n-                              actions->actions, actions->size);\n-}\n-\n static inline void\n dp_netdev_queue_batches(struct dp_packet *pkt,\n                         struct dp_netdev_flow *flow, uint16_t tcp_flags,\n@@ -7411,7 +7290,7 @@ smc_lookup_single(struct dp_netdev_pmd_thread *pmd,\n     return NULL;\n }\n \n-inline int\n+static inline int\n dp_netdev_hw_flow(const struct dp_netdev_pmd_thread *pmd,\n                   struct dp_packet *packet,\n                   struct dp_netdev_flow **flow)\n@@ -9153,7 +9032,6 @@ dpcls_destroy_subtable(struct dpcls *cls, struct dpcls_subtable *subtable)\n     pvector_remove(&cls->subtables, subtable);\n     cmap_remove(&cls->subtables_map, &subtable->cmap_node,\n                 subtable->mask.hash);\n-    dpcls_info_dec_usage(subtable->lookup_func_info);\n     ovsrcu_postpone(dpcls_subtable_destroy_cb, subtable);\n }\n \n@@ -9199,14 +9077,8 @@ dpcls_create_subtable(struct dpcls *cls, const struct netdev_flow_key *mask)\n \n     /* Get the preferred subtable search function for this (u0,u1) subtable.\n      * The function is guaranteed to always return a valid implementation, and\n-     * possibly an ISA optimized, and/or specialized implementation. Initialize\n-     * the subtable search function atomically to avoid garbage data being read\n-     * by the PMD thread.\n-     */\n-    atomic_init(&subtable->lookup_func,\n-                dpcls_subtable_get_best_impl(unit0, unit1,\n-                                             &subtable->lookup_func_info));\n-    dpcls_info_inc_usage(subtable->lookup_func_info);\n+     * possibly a specialized implementation. */\n+    subtable->lookup_func = dpcls_subtable_lookup_probe(unit0, unit1);\n \n     cmap_insert(&cls->subtables_map, &subtable->cmap_node, mask->hash);\n     /* Add the new subtable at the end of the pvector (with no hits yet) */\n@@ -9232,47 +9104,6 @@ dpcls_find_subtable(struct dpcls *cls, const struct netdev_flow_key *mask)\n     return dpcls_create_subtable(cls, mask);\n }\n \n-/* Checks for the best available implementation for each subtable lookup\n- * function, and assigns it as the lookup function pointer for each subtable.\n- * Returns the number of subtables that have changed lookup implementation.\n- * This function requires holding a flow_mutex when called. This is to make\n- * sure modifications done by this function are not overwritten. This could\n- * happen if dpcls_sort_subtable_vector() is called at the same time as this\n- * function.\n- */\n-static uint32_t\n-dpcls_subtable_lookup_reprobe(struct dpcls *cls)\n-{\n-    struct pvector *pvec = &cls->subtables;\n-    uint32_t subtables_changed = 0;\n-    struct dpcls_subtable *subtable = NULL;\n-\n-    PVECTOR_FOR_EACH (subtable, pvec) {\n-        uint32_t u0_bits = subtable->mf_bits_set_unit0;\n-        uint32_t u1_bits = subtable->mf_bits_set_unit1;\n-        void *old_func = subtable->lookup_func;\n-        struct dpcls_subtable_lookup_info_t *old_info;\n-        old_info = subtable->lookup_func_info;\n-        /* Set the subtable lookup function atomically to avoid garbage data\n-         * being read by the PMD thread. */\n-        atomic_store_relaxed(&subtable->lookup_func,\n-                dpcls_subtable_get_best_impl(u0_bits, u1_bits,\n-                                             &subtable->lookup_func_info));\n-        if (old_func != subtable->lookup_func) {\n-            subtables_changed += 1;\n-        }\n-\n-        if (old_info != subtable->lookup_func_info) {\n-            /* In theory, functions can be shared between implementations, so\n-             * do an explicit check on the function info structures. */\n-            dpcls_info_dec_usage(old_info);\n-            dpcls_info_inc_usage(subtable->lookup_func_info);\n-        }\n-    }\n-\n-    return subtables_changed;\n-}\n-\n /* Periodically sort the dpcls subtable vectors according to hit counts */\n static void\n dpcls_sort_subtable_vector(struct dpcls *cls)\ndiff --git a/m4/openvswitch.m4 b/m4/openvswitch.m4\nindex ca3deec9a..02988aaed 100644\n--- a/m4/openvswitch.m4\n+++ b/m4/openvswitch.m4\n@@ -409,76 +409,6 @@ AC_DEFUN([OVS_CHECK_SPHINX],\n    AC_ARG_VAR([SPHINXBUILD])\n    AM_CONDITIONAL([HAVE_SPHINX], [test \"$SPHINXBUILD\" != none])])\n \n-\n-dnl Checks whether the build system implements the vpopcntdq instruction. The\n-dnl compiler and assembler each separately need to support vpopcntdq. In order\n-dnl to test the assembler with the below code snippet, set the optimization\n-dnl level of the function to \"O0\" so it won't be optimized away by the\n-dnl compiler.\n-AC_DEFUN([OVS_CHECK_AVX512VPOPCNTDQ], [\n-  AC_MSG_CHECKING([whether compiler correctly emits AVX512-VPOPCNTDQ])\n-  AC_COMPILE_IFELSE(\n-    [AC_LANG_PROGRAM([#include <immintrin.h>\n-                     void\n-                     __attribute__((__target__(\"avx512vpopcntdq\")))\n-                     __attribute__((optimize(\"O0\")))\n-                     check_vpopcntdq(void)\n-                     {\n-                         __m512i v_test;\n-                         v_test = _mm512_popcnt_epi64(v_test);\n-                     }],[])],\n-    [AC_MSG_RESULT([yes])\n-    ovs_cv_avx512vpopcntdq_good=yes],\n-    [AC_MSG_RESULT([no])\n-    ovs_cv_avx512vpopcntdq_good=no])\n-   if test \"$ovs_cv_avx512vpopcntdq_good\" = yes; then\n-     AC_DEFINE([HAVE_AVX512VPOPCNTDQ], [1],\n-               [Define to 1 if the build system implements the vpopcntdq\n-                instruction.])\n-   fi\n-   AM_CONDITIONAL([HAVE_AVX512VPOPCNTDQ],\n-                  [test \"$ovs_cv_avx512vpopcntdq_good\" = yes])])\n-\n-dnl Checks for binutils/assembler known issue with AVX512.\n-dnl Due to backports, we probe assembling a reproducer instead of checking\n-dnl binutils version string. More details, including ASM dumps and debug here:\n-dnl   GCC: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90028\n-dnl The checking of binutils funcationality instead of LD version is similar\n-dnl to as how DPDK proposes to solve this issue:\n-dnl   http://patches.dpdk.org/patch/71723/\n-AC_DEFUN([OVS_CHECK_BINUTILS_AVX512],\n-  [OVS_CHECK_CC_OPTION(\n-   [-mavx512f],\n-   [AC_CACHE_CHECK(\n-    [binutils avx512 assembler checks passing],\n-    [ovs_cv_binutils_avx512_good],\n-    [dnl Assemble a short snippet to test for issue in \"build-aux\" dir:\n-     mkdir -p build-aux\n-     OBJFILE=build-aux/binutils_avx512_check.o\n-     GATHER_PARAMS='0x8(,%ymm1,1),%ymm0{%k2}'\n-     if ($CC -dumpmachine | grep x86_64) >/dev/null 2>&1; then\n-       echo \"vpgatherqq $GATHER_PARAMS\" | as --64 -o $OBJFILE -\n-       if (objdump -d  --no-show-raw-insn $OBJFILE | grep -q $GATHER_PARAMS) >/dev/null 2>&1; then\n-         ovs_cv_binutils_avx512_good=yes\n-       else\n-         ovs_cv_binutils_avx512_good=no\n-         dnl Explicitly disallow avx512f to stop compiler auto-vectorizing\n-         dnl and causing zmm usage with buggy binutils versions.\n-         CFLAGS=\"$CFLAGS -mno-avx512f\"\n-       fi\n-       rm $OBJFILE\n-     else\n-       dnl non x86_64 architectures don't have avx512, so not affected\n-       ovs_cv_binutils_avx512_good=no\n-     fi])],\n-    [ovs_cv_binutils_avx512_good=no])\n-   if test \"$ovs_cv_binutils_avx512_good\" = yes; then\n-     AC_DEFINE([HAVE_LD_AVX512_GOOD], [1],\n-               [Define to 1 if binutils correctly supports AVX512.])\n-   fi\n-   AM_CONDITIONAL([HAVE_LD_AVX512_GOOD],\n-                  [test \"$ovs_cv_binutils_avx512_good\" = yes])])\n-\n dnl Checks for dot.\n AC_DEFUN([OVS_CHECK_DOT],\n   [AC_CACHE_CHECK(\ndiff --git a/tests/pmd.at b/tests/pmd.at\nindex 677d0feb1..4f1f7a4e8 100644\n--- a/tests/pmd.at\n+++ b/tests/pmd.at\n@@ -1182,74 +1182,6 @@ AT_CHECK([ovs-appctl dpctl/del-dp dummy@dp0], [0], [dnl\n OVS_VSWITCHD_STOP\n AT_CLEANUP\n \n-AT_SETUP([PMD - dpcls configuration])\n-OVS_VSWITCHD_START([], [], [], [--dummy-numa 0,0])\n-AT_CHECK([ovs-vsctl add-port br0 p1 -- set Interface p1 type=dummy-pmd])\n-\n-AT_CHECK([ovs-vsctl show], [], [stdout])\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-prio-set autovalidator 3], [0], [dnl\n-Lookup priority change affected 0 dpcls ports and 0 subtables.\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-info-get | grep autovalidator], [], [dnl\n-  autovalidator (Use count: 0, Priority: 3)\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-prio-set generic 4], [0], [dnl\n-Lookup priority change affected 0 dpcls ports and 0 subtables.\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-info-get | grep generic], [], [dnl\n-  generic (Use count: 0, Priority: 4)\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-prio-set generic 8], [0], [dnl\n-Lookup priority change affected 0 dpcls ports and 0 subtables.\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-info-get | grep generic], [], [dnl\n-  generic (Use count: 0, Priority: 8)\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-prio-set autovalidator 8], [0], [dnl\n-Lookup priority change affected 0 dpcls ports and 0 subtables.\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-info-get | grep autovalidator], [], [dnl\n-  autovalidator (Use count: 0, Priority: 8)\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-prio-set generic 0], [0], [dnl\n-Lookup priority change affected 0 dpcls ports and 0 subtables.\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-info-get | grep generic], [], [dnl\n-  generic (Use count: 0, Priority: 0)\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-prio-set generic 255], [0], [dnl\n-Lookup priority change affected 0 dpcls ports and 0 subtables.\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-info-get | grep generic], [], [dnl\n-  generic (Use count: 0, Priority: 255)\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-prio-set generic -1], [2],\n-[], [dnl\n-error converting priority, use integer in range 0-255\n-ovs-appctl: ovs-vswitchd: server returned an error\n-])\n-\n-AT_CHECK([ovs-appctl dpif-netdev/subtable-lookup-prio-set generic 300], [2],\n-[], [dnl\n-error converting priority, use integer in range 0-255\n-ovs-appctl: ovs-vswitchd: server returned an error\n-])\n-\n-OVS_VSWITCHD_STOP\n-AT_CLEANUP\n-\n AT_SETUP([PMD - pmd sleep])\n OVS_VSWITCHD_START([add-port br0 p0 -- set Interface p0 type=dummy-pmd options:n_rxq=8 options:numa_id=1], [], [], [--dummy-numa 0,0,0,1,1,8,8])\n \n","prefixes":["ovs-dev","4/6"]}