Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2229661/?format=api
{ "id": 2229661, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2229661/?format=api", "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=api", "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=api", "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=api", "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" ] }