From patchwork Wed Apr 28 09:19:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Amber X-Patchwork-Id: 1471028 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FVYJ10xl3z9sXG for ; Wed, 28 Apr 2021 19:29:52 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 24F248434F; Wed, 28 Apr 2021 09:29:50 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id MvNfgv5HXfZJ; Wed, 28 Apr 2021 09:29:48 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTP id DE8E483F0B; Wed, 28 Apr 2021 09:29:47 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id B513AC0022; Wed, 28 Apr 2021 09:29:47 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2C093C0001 for ; Wed, 28 Apr 2021 09:29:46 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 1AFAB84306 for ; Wed, 28 Apr 2021 09:29:46 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qEdyXJQHt1Yl for ; Wed, 28 Apr 2021 09:29:44 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by smtp1.osuosl.org (Postfix) with ESMTPS id 9130183F0B for ; Wed, 28 Apr 2021 09:29:44 +0000 (UTC) IronPort-SDR: AwkXTjlJq86vxIs25k3k4GU+S7jIfl5YETEX+voQywVSBunXT69CfCxIJV9p0771Mme4oOAXY6 3XPQQz6t5DsA== X-IronPort-AV: E=McAfee;i="6200,9189,9967"; a="260650396" X-IronPort-AV: E=Sophos;i="5.82,257,1613462400"; d="scan'208";a="260650396" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Apr 2021 02:29:44 -0700 IronPort-SDR: hH8Y3isC0mADHDn3xJZkcqAYamo189q0ECF6vlUu5hIjL7Cxju/LaZ6BoSPPCw/vfJagN5qaGQ e/2CK7mawoWg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,257,1613462400"; d="scan'208";a="387644507" Received: from bmca4bf01706bbf.iind.intel.com (HELO localhost.localdomain) ([10.190.213.111]) by orsmga006.jf.intel.com with ESMTP; 28 Apr 2021 02:29:42 -0700 From: Kumar Amber To: dev@openvswitch.org Date: Wed, 28 Apr 2021 14:49:26 +0530 Message-Id: <20210428091931.2090062-2-kumar.amber@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210428091931.2090062-1-kumar.amber@intel.com> References: <20210428075554.2086279-7-kumar.amber@intel.com> <20210428091931.2090062-1-kumar.amber@intel.com> MIME-Version: 1.0 Cc: Kumar Amber , i.maximets@ovn.org Subject: [ovs-dev] [v2 v2 1/6] dpif-netdev: Add command line and function pointer for miniflow extract X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" This patch introduces the mfex function pointers which allows the user to switch between different miniflow extract implementations which are provided by the OVS based on optimized ISA CPU. The user can query for the available minflow extract variants available for that CPU by following commands: $ovs-appctl dpif-netdev/miniflow-parser-get Similarly an user can set the miniflow implementation by the following command : $ ovs-appctl dpif-netdev/miniflow-parser-set name This allow for more performance and flexibility to the user to choose the miniflow implementation according to the needs. Signed-off-by: Kumar Amber Co-authored-by: Harry van Haaren Signed-off-by: Harry van Haaren --- lib/automake.mk | 2 + lib/dpif-netdev-avx512.c | 23 ++++-- lib/dpif-netdev-private-extract.c | 86 ++++++++++++++++++++ lib/dpif-netdev-private-extract.h | 94 ++++++++++++++++++++++ lib/dpif-netdev-private-thread.h | 4 + lib/dpif-netdev.c | 126 +++++++++++++++++++++++++++++- 6 files changed, 328 insertions(+), 7 deletions(-) create mode 100644 lib/dpif-netdev-private-extract.c create mode 100644 lib/dpif-netdev-private-extract.h diff --git a/lib/automake.mk b/lib/automake.mk index 6279662f8..6110cc922 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -117,6 +117,8 @@ lib_libopenvswitch_la_SOURCES = \ lib/dpif-netdev-private-dpcls.h \ lib/dpif-netdev-private-dpif.c \ lib/dpif-netdev-private-dpif.h \ + lib/dpif-netdev-private-extract.c \ + lib/dpif-netdev-private-extract.h \ lib/dpif-netdev-private-flow.h \ lib/dpif-netdev-private-hwol.h \ lib/dpif-netdev-private-thread.h \ diff --git a/lib/dpif-netdev-avx512.c b/lib/dpif-netdev-avx512.c index c23ac0f82..26aee9670 100644 --- a/lib/dpif-netdev-avx512.c +++ b/lib/dpif-netdev-avx512.c @@ -120,7 +120,16 @@ dp_netdev_input_outer_avx512(struct dp_netdev_pmd_thread *pmd, /* A 1 bit in this mask indicates a hit, so no DPCLS lookup on the pkt. */ uint32_t hwol_emc_smc_hitmask = 0; - /* Perform first packet interation. */ + /* Do a batch minfilow extract into keys. */ + /* TODO: v2 will support cleaner integration into packet batch + * loops below. */ + uint32_t mf_mask = 0; + if (pmd->miniflow_extract_opt) { + mf_mask = pmd->miniflow_extract_opt(packets, keys, + batch_size, in_port, + (void *) pmd); + } + /* Perform first packet interation */ uint32_t lookup_pkts_bitmask = (1ULL << batch_size) - 1; uint32_t iter = lookup_pkts_bitmask; while (iter) { @@ -152,11 +161,15 @@ dp_netdev_input_outer_avx512(struct dp_netdev_pmd_thread *pmd, } } - /* Do miniflow extract into keys */ struct netdev_flow_key *key = &keys[i]; - miniflow_extract(packet, &key->mf); - - /* Cache TCP and byte values for all packets. */ + /* Check the minfiflow mask to see if the packet was correctly + * classifed by vector mfex else do a scalar miniflow extract + * for that packet. */ + if (!(mf_mask & (1 << i))) { + /* Do a scalar miniflow extract into keys */ + miniflow_extract(packet, &key->mf); + } + /* Cache TCP and byte values for all packets */ pkt_meta[i].bytes = dp_packet_size(packet); pkt_meta[i].tcp_flags = miniflow_get_tcp_flags(&key->mf); diff --git a/lib/dpif-netdev-private-extract.c b/lib/dpif-netdev-private-extract.c new file mode 100644 index 000000000..fcc56ef26 --- /dev/null +++ b/lib/dpif-netdev-private-extract.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 Intel. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "dp-packet.h" +#include "dpif-netdev-private-dpcls.h" +#include "dpif-netdev-private-extract.h" +#include "dpif-netdev-private-thread.h" +#include "flow.h" +#include "openvswitch/vlog.h" +#include "ovs-thread.h" +#include "util.h" + +VLOG_DEFINE_THIS_MODULE(dpif_netdev_extract); + +/* Implementations of available extract options. */ +static struct dpif_miniflow_extract_impl mfex_impls[] = { + { + .probe = NULL, + .extract_func = NULL, + .name = "disable", + }, +}; + +BUILD_ASSERT_DECL(MFEX_IMPLS_MAX_SIZE > ARRAY_SIZE(mfex_impls)); + +int32_t +dpif_miniflow_extract_opt_get(const char *name, + struct dpif_miniflow_extract_impl **opt) +{ + ovs_assert(opt); + ovs_assert(name); + + uint32_t i; + for (i = 0; i < ARRAY_SIZE(mfex_impls); i++) { + if (strcmp(name, mfex_impls[i].name) == 0) { + *opt = &mfex_impls[i]; + return 0; + } + } + return -ENOTSUP; +} + +void +dpif_miniflow_extract_init(void) +{ + /* Call probe on each impl, and cache the result. */ + uint32_t i; + for (i = 0; i < ARRAY_SIZE(mfex_impls); i++) { + int avail = 1; + if (mfex_impls[i].probe) { + /* Return zero is success, non-zero means error. */ + avail = (mfex_impls[i].probe() == 0); + } + VLOG_INFO("Miniflow Extract implementation %s (available: %s)\n", + mfex_impls[i].name, avail ? "True" : "False"); + mfex_impls[i].available = avail; + } +} + +int32_t +dpif_miniflow_extract_info_get(struct dpif_miniflow_extract_impl **out_ptr) +{ + if (out_ptr == NULL) { + return -EINVAL; + } + *out_ptr = mfex_impls; + return ARRAY_SIZE(mfex_impls); +} diff --git a/lib/dpif-netdev-private-extract.h b/lib/dpif-netdev-private-extract.h new file mode 100644 index 000000000..b7b0b2be4 --- /dev/null +++ b/lib/dpif-netdev-private-extract.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2021 Intel. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DPIF_NETDEV_AVX512_EXTRACT +#define DPIF_NETDEV_AVX512_EXTRACT 1 + +#include + +#include "openvswitch/types.h" + +/* Max size of dpif_miniflow_extract_impl array. */ +#define MFEX_IMPLS_MAX_SIZE (16) + +/* Forward declarations. */ +struct dp_packet; +struct miniflow; +struct dp_netdev_pmd_thread; +struct dp_packet_batch; +struct netdev_flow_key; + +/* Function pointer prototype to be implemented in the optimized miniflow + * extract code. + * returns the hitmask of the processed packets on success. + * returns zero on failure. + */ +typedef uint32_t (*miniflow_extract_func)(struct dp_packet_batch *batch, + struct netdev_flow_key *keys, + uint32_t keys_size, + odp_port_t in_port, + void *pmd_handle); + +/* Probe function is used to detect if this CPU has the ISA required + * to run the optimized miniflow implementation. + * returns one on successful probe. + * returns zero on failure. + */ +typedef int32_t (*miniflow_extract_probe)(void); + +/* Structure representing the attributes of an optimized implementation. */ +struct dpif_miniflow_extract_impl { + /* When non-zero, this impl has passed the probe() checks. */ + uint8_t available; + + /* Probe function is used to detect if this CPU has the ISA required + * to run the optimized miniflow implementation. + */ + miniflow_extract_probe probe; + + /* Function to call to extract miniflows for a burst of packets. */ + miniflow_extract_func extract_func; + + /* Name of the optimized implementation. */ + char *name; +}; + +/* Retrieve the opt structure for the requested implementation by name. + * Returns zero on success, and opt points to a valid struct, or + * returns a negative failure status. + * -ENOTSUP : invalid name requested + */ +int32_t +dpif_miniflow_extract_opt_get(const char *name, + struct dpif_miniflow_extract_impl **opt); + +/* Initializes the available miniflow extract implementations by probing for + * the CPU ISA requirements. As the runtime available CPU ISA does not change + * and the required ISA of the implementation also does not change, it is safe + * to cache the probe() results, and not call probe() at runtime. + */ +void +dpif_miniflow_extract_init(void); + +/* Retrieve the array of miniflow implementations for iteration. + * On error, returns a negative number. + * On success, returns the size of the arrays pointed to by the out parameter. + */ +int32_t +dpif_miniflow_extract_info_get(struct dpif_miniflow_extract_impl **out_ptr); + + +#endif /* DPIF_NETDEV_AVX512_EXTRACT */ diff --git a/lib/dpif-netdev-private-thread.h b/lib/dpif-netdev-private-thread.h index 19ce99f4e..6d6e37a87 100644 --- a/lib/dpif-netdev-private-thread.h +++ b/lib/dpif-netdev-private-thread.h @@ -29,6 +29,7 @@ #include "openvswitch/thread.h" #include "dpif-netdev-private-dpif.h" +#include "dpif-netdev-private-extract.h" #ifdef __cplusplus extern "C" { @@ -110,6 +111,9 @@ struct dp_netdev_pmd_thread { /* Pointer for per-DPIF implementation scratch space. */ void *netdev_input_func_userdata; + /* Function pointer to call for miniflow_extract() functionality. */ + miniflow_extract_func miniflow_extract_opt; + struct seq *reload_seq; uint64_t last_reload_seq; diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 3d05a23a4..ebdaf33aa 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -46,6 +46,7 @@ #include "dpif-netdev-lookup.h" #include "dpif-netdev-perf.h" #include "dpif-netdev-private-dfc.h" +#include "dpif-netdev-private-extract.h" #include "dpif-provider.h" #include "dummy.h" #include "fat-rwlock.h" @@ -1089,6 +1090,102 @@ dpif_netdev_impl_set(struct unixctl_conn *conn, int argc, ds_destroy(&reply); } +static void +dpif_miniflow_extract_impl_get(struct unixctl_conn *conn, int argc OVS_UNUSED, + const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) +{ + struct dpif_miniflow_extract_impl *mfex_impls; + uint32_t count = dpif_miniflow_extract_info_get(&mfex_impls); + if (count == 0) { + unixctl_command_reply_error(conn, "error getting mfex names"); + return; + } + + /* Add all mfex functions to reply string. */ + struct ds reply = DS_EMPTY_INITIALIZER; + ds_put_cstr(&reply, "Available Optimized Miniflow Extracts:\n"); + for (uint32_t i = 0; i < count; i++) { + ds_put_format(&reply, " %s (available: %s)\n", + mfex_impls[i].name, mfex_impls[i].available ? + "True" : "False"); + } + unixctl_command_reply(conn, ds_cstr(&reply)); + ds_destroy(&reply); +} + +static void +dpif_miniflow_extract_impl_set(struct unixctl_conn *conn, int argc, + const char *argv[], void *aux OVS_UNUSED) +{ + /* This function requires just one parameter, the miniflow name. + * A second optional parameter can identify the datapath instance. + */ + const char *mfex_name = argv[1]; + + static const char *error_description[2] = { + "Unknown miniflow implementation", + "implementation doesn't exist", + }; + struct dpif_miniflow_extract_impl *opt; + miniflow_extract_func new_func; + int32_t err = dpif_miniflow_extract_opt_get(mfex_name, &opt); + if (err) { + struct ds reply = DS_EMPTY_INITIALIZER; + ds_put_format(&reply, + "Miniflow implementation not available: %s %s.\n", + error_description[ (err == -ENOTSUP) ], mfex_name); + const char *reply_str = ds_cstr(&reply); + unixctl_command_reply(conn, reply_str); + VLOG_INFO("%s", reply_str); + ds_destroy(&reply); + return; + } + new_func = opt->extract_func; + /* argv[2] is optional datapath instance. If no datapath name is provided. + * and only one datapath exists, the one existing datapath is reprobed. + */ + ovs_mutex_lock(&dp_netdev_mutex); + struct dp_netdev *dp = NULL; + + if (argc == 3) { + dp = shash_find_data(&dp_netdevs, argv[2]); + } else if (shash_count(&dp_netdevs) == 1) { + dp = shash_first(&dp_netdevs)->data; + } + + if (!dp) { + ovs_mutex_unlock(&dp_netdev_mutex); + unixctl_command_reply_error(conn, + "please specify an existing datapath"); + return; + } + + /* Get PMD threads list. */ + size_t n; + struct dp_netdev_pmd_thread **pmd_list; + sorted_poll_thread_list(dp, &pmd_list, &n); + + for (size_t i = 0; i < n; i++) { + struct dp_netdev_pmd_thread *pmd = pmd_list[i]; + if (pmd->core_id == NON_PMD_CORE_ID) { + continue; + } + + /* Set PMD threads miniflow implementation to requested one. */ + pmd->miniflow_extract_opt = *new_func; + }; + + ovs_mutex_unlock(&dp_netdev_mutex); + + /* Reply with success to command. */ + struct ds reply = DS_EMPTY_INITIALIZER; + ds_put_format(&reply, "Miniflow implementation set to %s.\n", mfex_name); + const char *reply_str = ds_cstr(&reply); + unixctl_command_reply(conn, reply_str); + VLOG_INFO("%s", reply_str); + ds_destroy(&reply); +} + static void dpif_netdev_pmd_rebalance(struct unixctl_conn *conn, int argc, const char *argv[], void *aux OVS_UNUSED) @@ -1315,9 +1412,16 @@ dpif_netdev_init(void) "dpif_implementation_name [dp]", 1, 2, dpif_netdev_impl_set, NULL); + unixctl_command_register("dpif-netdev/miniflow-parser-set", + "miniflow implementation name [dp]", + 1, 2, dpif_miniflow_extract_impl_set, + NULL); unixctl_command_register("dpif-netdev/dpif-get", "", 0, 0, dpif_netdev_impl_get, NULL); + unixctl_command_register("dpif-netdev/miniflow-parser-get", "", + 0, 0, dpif_miniflow_extract_impl_get, + NULL); return 0; } @@ -1461,6 +1565,8 @@ create_dp_netdev(const char *name, const struct dpif_class *class, dp->conntrack = conntrack_init(); + dpif_miniflow_extract_init(); + atomic_init(&dp->emc_insert_min, DEFAULT_EM_FLOW_INSERT_MIN); atomic_init(&dp->tx_flush_interval, DEFAULT_TX_FLUSH_INTERVAL); @@ -6144,6 +6250,9 @@ dp_netdev_configure_pmd(struct dp_netdev_pmd_thread *pmd, struct dp_netdev *dp, /* Initialize DPIF function pointer to the default configured version. */ pmd->netdev_input_func = dp_netdev_impl_get_default(); + /*Init default miniflow_extract function */ + pmd->miniflow_extract_opt = NULL; + /* init the 'flow_cache' since there is no * actual thread created for NON_PMD_CORE_ID. */ if (core_id == NON_PMD_CORE_ID) { @@ -6697,11 +6806,13 @@ dfc_processing(struct dp_netdev_pmd_thread *pmd, bool md_is_valid, odp_port_t port_no) { struct netdev_flow_key *key = &keys[0]; + struct dp_packet_batch single_packet; size_t n_missed = 0, n_emc_hit = 0; struct dfc_cache *cache = &pmd->flow_cache; struct dp_packet *packet; const size_t cnt = dp_packet_batch_size(packets_); uint32_t cur_min = pmd->ctx.emc_insert_min; + int mf_ret; int i; uint16_t tcp_flags; bool smc_enable_db; @@ -6753,8 +6864,19 @@ dfc_processing(struct dp_netdev_pmd_thread *pmd, continue; } } - - miniflow_extract(packet, &key->mf); + /* Set the count and packet for miniflow_opt with batch_size 1. */ + if ((pmd->miniflow_extract_opt) && (!md_is_valid)) { + single_packet.count = 1; + single_packet.packets[0] = packet; + mf_ret = pmd->miniflow_extract_opt(&single_packet, key, 1, + port_no, (void *) pmd); + /* Fallback to original miniflow_extract if there is a miss. */ + if (!mf_ret) { + miniflow_extract(packet, &key->mf); + } + } else { + miniflow_extract(packet, &key->mf); + } key->len = 0; /* Not computed yet. */ key->hash = (md_is_valid == false) From patchwork Wed Apr 28 09:19:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Amber X-Patchwork-Id: 1471030 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FVYJ565hwz9sXG for ; Wed, 28 Apr 2021 19:29:57 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 09E904058C; Wed, 28 Apr 2021 09:29:54 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id p63uzSeVzXZo; Wed, 28 Apr 2021 09:29:52 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTP id D6B724057E; Wed, 28 Apr 2021 09:29:50 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 149BAC002B; Wed, 28 Apr 2021 09:29:50 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2F765C0026 for ; Wed, 28 Apr 2021 09:29:48 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id D7DB384306 for ; Wed, 28 Apr 2021 09:29:47 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Ub_pn-tzAlwL for ; Wed, 28 Apr 2021 09:29:46 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by smtp1.osuosl.org (Postfix) with ESMTPS id B9B8D83F0B for ; Wed, 28 Apr 2021 09:29:46 +0000 (UTC) IronPort-SDR: AbR8pwiMuK5VowlpOOkYricPALmJecBivsZBPk+JYIynzVxdoiyWPkh6ykP1YuawLsp8AALvef mDgfKver7Sww== X-IronPort-AV: E=McAfee;i="6200,9189,9967"; a="260650399" X-IronPort-AV: E=Sophos;i="5.82,257,1613462400"; d="scan'208";a="260650399" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Apr 2021 02:29:46 -0700 IronPort-SDR: kVJ2GI7DvuLz3nLT8wDPZaxUq4XJtICmp+L5+pZxsuZR6swSsTFfRTn7aWdVZRcMP0C03PAb5d bFpQYxvWrfNA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,257,1613462400"; d="scan'208";a="387644511" Received: from bmca4bf01706bbf.iind.intel.com (HELO localhost.localdomain) ([10.190.213.111]) by orsmga006.jf.intel.com with ESMTP; 28 Apr 2021 02:29:44 -0700 From: Kumar Amber To: dev@openvswitch.org Date: Wed, 28 Apr 2021 14:49:27 +0530 Message-Id: <20210428091931.2090062-3-kumar.amber@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210428091931.2090062-1-kumar.amber@intel.com> References: <20210428075554.2086279-7-kumar.amber@intel.com> <20210428091931.2090062-1-kumar.amber@intel.com> MIME-Version: 1.0 Cc: Kumar Amber , i.maximets@ovn.org Subject: [ovs-dev] [v2 v2 2/6] dpif-netdev: Add auto validation function for miniflow extract X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" This patch introduced the auto-validation function which allows users to compare the batch of packets obtained from different miniflow implementations against the linear miniflow extract and return a hitmask. The autovaidator function can be triggered at runtime using the following command: $ ovs-appctl dpif-netdev/miniflow-parser-set autovalidator Signed-off-by: Kumar Amber Co-authored-by: Harry van Haaren Signed-off-by: Harry van Haaren --- lib/dpif-netdev-private-extract.c | 79 +++++++++++++++++++++++++++++++ lib/dpif-netdev-private-extract.h | 15 ++++++ 2 files changed, 94 insertions(+) diff --git a/lib/dpif-netdev-private-extract.c b/lib/dpif-netdev-private-extract.c index fcc56ef26..9a53d4985 100644 --- a/lib/dpif-netdev-private-extract.c +++ b/lib/dpif-netdev-private-extract.c @@ -32,6 +32,11 @@ VLOG_DEFINE_THIS_MODULE(dpif_netdev_extract); /* Implementations of available extract options. */ static struct dpif_miniflow_extract_impl mfex_impls[] = { + { + .probe = NULL, + .extract_func = dpif_miniflow_extract_autovalidator, + .name = "autovalidator", + }, { .probe = NULL, .extract_func = NULL, @@ -84,3 +89,77 @@ dpif_miniflow_extract_info_get(struct dpif_miniflow_extract_impl **out_ptr) *out_ptr = mfex_impls; return ARRAY_SIZE(mfex_impls); } + +uint32_t +dpif_miniflow_extract_autovalidator(struct dp_packet_batch *packets, + struct netdev_flow_key *keys, + uint32_t keys_size, odp_port_t in_port, + void *pmd_handle) +{ + const size_t cnt = dp_packet_batch_size(packets); + uint16_t good_l2_5_ofs[cnt]; + uint16_t good_l3_ofs[cnt]; + uint16_t good_l4_ofs[cnt]; + uint16_t good_l2_pad_size[cnt]; + struct dp_packet *packet; + struct dp_netdev_pmd_thread *pmd = pmd_handle; + struct dpif_miniflow_extract_impl *miniflow_funcs; + + int32_t mfunc_count = dpif_miniflow_extract_info_get(&miniflow_funcs); + if (mfunc_count < 0) { + pmd->miniflow_extract_opt = NULL; + VLOG_ERR("failed to get miniflow extract function implementations\n"); + return 0; + } + ovs_assert(keys_size >= cnt); + struct netdev_flow_key test_keys[keys_size]; + + /* Run scalar miniflow_extract to get default result. */ + DP_PACKET_BATCH_FOR_EACH (i, packet, packets) { + pkt_metadata_init(&packet->md, in_port); + miniflow_extract(packet, &keys[i].mf); + /* Store good offsets for comparisons with optimized offsets. */ + good_l2_5_ofs[i] = packet->l2_5_ofs; + good_l3_ofs[i] = packet->l3_ofs; + good_l4_ofs[i] = packet->l4_ofs; + good_l2_pad_size[i] = packet->l2_pad_size; + } + + /* Iterate through each version of miniflow implementations. */ + for (int j = MFEX_IMPL_START_IDX; j < mfunc_count; j++) { + if (!mfex_impls[j].available) { + continue; + } + memset(test_keys, 0, keys_size * sizeof(struct netdev_flow_key)); + /* Call optimized miniflow for each batch of packet. */ + uint32_t hit_mask = mfex_impls[j].extract_func(packets, test_keys, + keys_size, in_port, pmd_handle); + + /* Do a miniflow compare for bits, blocks and offsets for all the + * classified packets in the hitmask marked by set bits. */ + while (hit_mask) { + /* Index for the set bit. */ + uint32_t i = __builtin_ctz(hit_mask); + /* Set the index in hitmask to Zero. */ + hit_mask &= (hit_mask - 1); + if (!miniflow_equal(&keys[i].mf, &test_keys[i].mf) || + (packets->packets[i]->l2_5_ofs != good_l2_5_ofs[i]) || + (packets->packets[i]->l3_ofs != good_l3_ofs[i]) || + (packets->packets[i]->l4_ofs != good_l4_ofs[i]) || + (packets->packets[i]->l2_pad_size != good_l2_pad_size[i])) { + + uint32_t block_size = netdev_flow_key_size( + miniflow_n_values(&keys[i].mf)); + VLOG_ERR("Autovalidation fails for mfex implementation %s" + " hitmask 0x%x index: %d\n", mfex_impls[j].name, + hit_mask, i); + VLOG_ERR("Good scalar Miniflow data hexdump : \n"); + ovs_hex_dump(stdout, &keys[i].mf, block_size, 0, true); + VLOG_ERR("Vector bad Miniflow data hexdump : \n"); + ovs_hex_dump(stdout, &test_keys[i].mf, block_size, 0, true); + } + } + } + /* Always return full hitmask as scalar mfex will always work. */ + return (1ULL << cnt) - 1; +} diff --git a/lib/dpif-netdev-private-extract.h b/lib/dpif-netdev-private-extract.h index b7b0b2be4..455a7b590 100644 --- a/lib/dpif-netdev-private-extract.h +++ b/lib/dpif-netdev-private-extract.h @@ -24,6 +24,11 @@ /* Max size of dpif_miniflow_extract_impl array. */ #define MFEX_IMPLS_MAX_SIZE (16) +/* Skip the autovalidator study and null when iterating all available + * miniflow implementations. + */ +#define MFEX_IMPL_START_IDX (1) + /* Forward declarations. */ struct dp_packet; struct miniflow; @@ -90,5 +95,15 @@ dpif_miniflow_extract_init(void); int32_t dpif_miniflow_extract_info_get(struct dpif_miniflow_extract_impl **out_ptr); +/* Retrieve the hitmask of the batch of pakcets which is obtained by comparing + * different miniflow implementations with linear miniflow extract. + * On error, returns a zero. + * On success, returns the number of packets in the batch compared. + */ +uint32_t +dpif_miniflow_extract_autovalidator(struct dp_packet_batch *batch, + struct netdev_flow_key *keys, + uint32_t keys_size, odp_port_t in_port, + void *pmd_handle); #endif /* DPIF_NETDEV_AVX512_EXTRACT */ From patchwork Wed Apr 28 09:19:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Amber X-Patchwork-Id: 1471031 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FVYJ700tnz9sXG for ; Wed, 28 Apr 2021 19:29:58 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id F23A360C17; Wed, 28 Apr 2021 09:29:56 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id W6ajOj6hmJ2a; Wed, 28 Apr 2021 09:29:55 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTP id DA5AF60BF5; Wed, 28 Apr 2021 09:29:54 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id B71A5C0023; Wed, 28 Apr 2021 09:29:54 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5B088C0022 for ; Wed, 28 Apr 2021 09:29:52 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 326AD84377 for ; Wed, 28 Apr 2021 09:29:52 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VtxqzhPbsWlC for ; Wed, 28 Apr 2021 09:29:50 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by smtp1.osuosl.org (Postfix) with ESMTPS id A57B584357 for ; Wed, 28 Apr 2021 09:29:50 +0000 (UTC) IronPort-SDR: aIc2JDeG57Kyg9AXC7SXuGdVciDaUP6TmkFsKACX8n1eGU9t7nYPeJ7SZp+tNiRlgLlQganLKr oNqq9tcW0x0g== X-IronPort-AV: E=McAfee;i="6200,9189,9967"; a="260650403" X-IronPort-AV: E=Sophos;i="5.82,257,1613462400"; d="scan'208";a="260650403" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Apr 2021 02:29:49 -0700 IronPort-SDR: k1zz9P1qOpqwG8qrk15NqVt8EKwIe6WhiTk0e1E8umxPsKnryU3npGqQg65GnHu7qUSAzApqjR gr2pLV+6W7rA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,257,1613462400"; d="scan'208";a="387644530" Received: from bmca4bf01706bbf.iind.intel.com (HELO localhost.localdomain) ([10.190.213.111]) by orsmga006.jf.intel.com with ESMTP; 28 Apr 2021 02:29:46 -0700 From: Kumar Amber To: dev@openvswitch.org Date: Wed, 28 Apr 2021 14:49:28 +0530 Message-Id: <20210428091931.2090062-4-kumar.amber@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210428091931.2090062-1-kumar.amber@intel.com> References: <20210428075554.2086279-7-kumar.amber@intel.com> <20210428091931.2090062-1-kumar.amber@intel.com> MIME-Version: 1.0 Cc: Kumar Amber , i.maximets@ovn.org Subject: [ovs-dev] [v2 v2 3/6] dpif-netdev: Add study function to select the best mfex function X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" The study function runs all the available implementations of miniflow_extract and makes a choice whose hitmask has maximum hits and sets the mfex to that function. Study can be run at runtime using the following command: $ ovs-appctl dpif-netdev/miniflow-parser-set study Signed-off-by: Kumar Amber Co-authored-by: Harry van Haaren Signed-off-by: Harry van Haaren --- lib/automake.mk | 1 + lib/dpif-netdev-extract-study.c | 120 ++++++++++++++++++++++++++++++ lib/dpif-netdev-private-extract.c | 5 ++ lib/dpif-netdev-private-extract.h | 14 +++- 4 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 lib/dpif-netdev-extract-study.c diff --git a/lib/automake.mk b/lib/automake.mk index 6110cc922..b04fd672f 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -113,6 +113,7 @@ lib_libopenvswitch_la_SOURCES = \ lib/dpif-netdev-lookup-generic.c \ lib/dpif-netdev.c \ lib/dpif-netdev.h \ + lib/dpif-netdev-extract-study.c \ lib/dpif-netdev-private-dfc.h \ lib/dpif-netdev-private-dpcls.h \ lib/dpif-netdev-private-dpif.c \ diff --git a/lib/dpif-netdev-extract-study.c b/lib/dpif-netdev-extract-study.c new file mode 100644 index 000000000..8c0910393 --- /dev/null +++ b/lib/dpif-netdev-extract-study.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2021 Intel. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "dpif-netdev-private-extract.h" +#include "dpif-netdev-private-thread.h" +#include "openvswitch/vlog.h" +#include "ovs-thread.h" + +VLOG_DEFINE_THIS_MODULE(dpif_mfex_extract_study); + +/* Max size of packets to be compared. */ +#define MFEX_MAX_COUNT (128) + +/* This value is the threshold for the amount of packets that + * must hit on the optimized miniflow extract before it will be + * accepted and used in the datapath after the study phase. */ +#define MFEX_MIN_HIT_COUNT_FOR_USE (MFEX_MAX_COUNT / 2) + +/* Struct to hold miniflow study stats. */ +struct study_stats { + uint32_t pkt_count; + uint32_t impl_hitcount[MFEX_IMPLS_MAX_SIZE]; +}; + +/* Define per thread data to hold the study stats. */ +DEFINE_PER_THREAD_MALLOCED_DATA(struct study_stats *, study_stats); + +/* Allocate per thread PMD pointer space for study_stats. */ +static inline struct study_stats * +get_study_stats(void) +{ + struct study_stats *stats = study_stats_get(); + if (OVS_UNLIKELY(!stats)) { + stats = xzalloc(sizeof *stats); + study_stats_set_unsafe(stats); + } + return stats; +} + +uint32_t +mfex_study_traffic(struct dp_packet_batch *packets, + struct netdev_flow_key *keys, + uint32_t keys_size, odp_port_t in_port, + void *pmd_handle) +{ + uint32_t hitmask = 0; + uint32_t mask = 0; + struct dp_packet *packet; + struct dp_netdev_pmd_thread *pmd = pmd_handle; + struct dpif_miniflow_extract_impl *miniflow_funcs; + uint32_t impl_count = dpif_miniflow_extract_info_get(&miniflow_funcs); + struct study_stats *stats = get_study_stats(); + + /* Run traffic optimized miniflow_extract to collect the hitmask + * to be compared after certain packets have been hit to choose + * the best miniflow_extract version for that traffic. */ + for (int i = MFEX_IMPL_START_IDX; i < impl_count; i++) { + if (miniflow_funcs[i].available) { + hitmask = miniflow_funcs[i].extract_func(packets, keys, keys_size, + in_port, pmd_handle); + stats->impl_hitcount[i] += count_1bits(hitmask); + + /* If traffic is not classified than we dont overwrite the keys + * array in minfiflow implementations so its safe to create a + * mask for all those packets whose miniflow have been created. */ + mask |= hitmask; + } + } + stats->pkt_count += dp_packet_batch_size(packets); + + /* Choose the best implementation after a minimum packets have been + * processed. */ + if (stats->pkt_count >= MFEX_MAX_COUNT) { + uint32_t best_func_index = MFEX_IMPL_START_IDX; + uint32_t max_hits = 0; + for (int i = MFEX_IMPL_START_IDX; i < impl_count; i++) { + if (stats->impl_hitcount[i] > max_hits) { + max_hits = stats->impl_hitcount[i]; + best_func_index = i; + } + } + + if (max_hits >= MFEX_MIN_HIT_COUNT_FOR_USE) { + /* Set the implementation to index with max_hits. */ + pmd->miniflow_extract_opt = + miniflow_funcs[best_func_index].extract_func; + VLOG_INFO("MFEX study chose impl %s: (hits %d/%d pkts)\n", + miniflow_funcs[best_func_index].name, max_hits, + stats->pkt_count); + } else { + /* Set the implementation to null for default miniflow. */ + pmd->miniflow_extract_opt = NULL; + VLOG_INFO("Not enough packets matched (%d/%d), disabling" + " optimized MFEX.\n", max_hits, stats->pkt_count); + } + /* Reset stats so that study function can be called again + * for next traffic type and optimal function ptr can be + * choosen. */ + memset(stats, 0, sizeof(struct study_stats)); + } + return mask; +} diff --git a/lib/dpif-netdev-private-extract.c b/lib/dpif-netdev-private-extract.c index 9a53d4985..76c24c2f8 100644 --- a/lib/dpif-netdev-private-extract.c +++ b/lib/dpif-netdev-private-extract.c @@ -42,6 +42,11 @@ static struct dpif_miniflow_extract_impl mfex_impls[] = { .extract_func = NULL, .name = "disable", }, + { + .probe = NULL, + .extract_func = mfex_study_traffic, + .name = "study", + }, }; BUILD_ASSERT_DECL(MFEX_IMPLS_MAX_SIZE > ARRAY_SIZE(mfex_impls)); diff --git a/lib/dpif-netdev-private-extract.h b/lib/dpif-netdev-private-extract.h index 455a7b590..3ada413bb 100644 --- a/lib/dpif-netdev-private-extract.h +++ b/lib/dpif-netdev-private-extract.h @@ -27,7 +27,7 @@ /* Skip the autovalidator study and null when iterating all available * miniflow implementations. */ -#define MFEX_IMPL_START_IDX (1) +#define MFEX_IMPL_START_IDX (3) /* Forward declarations. */ struct dp_packet; @@ -106,4 +106,16 @@ dpif_miniflow_extract_autovalidator(struct dp_packet_batch *batch, uint32_t keys_size, odp_port_t in_port, void *pmd_handle); +/* Retrieve the number of packets by studying packets using different miniflow + * implementations to choose the best implementation using the maximum hitmask + * count. + * On error, returns a zero for no packets. + * On success, returns mask of the packets hit. + */ +uint32_t +mfex_study_traffic(struct dp_packet_batch *packets, + struct netdev_flow_key *keys, + uint32_t keys_size, odp_port_t in_port, + void *pmd_handle); + #endif /* DPIF_NETDEV_AVX512_EXTRACT */ From patchwork Wed Apr 28 09:19:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Amber X-Patchwork-Id: 1471032 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FVYJC4Jndz9sXG for ; Wed, 28 Apr 2021 19:30:03 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 08D6E4012B; Wed, 28 Apr 2021 09:30:02 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id S96SML93GMUU; Wed, 28 Apr 2021 09:30:00 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTP id CD71840551; Wed, 28 Apr 2021 09:29:59 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id A7E2FC0022; Wed, 28 Apr 2021 09:29:59 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 05E54C0022 for ; Wed, 28 Apr 2021 09:29:59 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id EB72E84307 for ; Wed, 28 Apr 2021 09:29:55 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cgMpDi5K4k4U for ; Wed, 28 Apr 2021 09:29:53 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by smtp1.osuosl.org (Postfix) with ESMTPS id 4FC3084357 for ; Wed, 28 Apr 2021 09:29:52 +0000 (UTC) IronPort-SDR: 1m4HZyLljII1szMvwBZnIQBUoOtwKQl+U2xTx6jh1exFSFLtbAcuqluAEml6hbUk7xTHEZImSW WEb9BIQ2zzeg== X-IronPort-AV: E=McAfee;i="6200,9189,9967"; a="260650414" X-IronPort-AV: E=Sophos;i="5.82,257,1613462400"; d="scan'208";a="260650414" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Apr 2021 02:29:52 -0700 IronPort-SDR: M6K/agCV4nZWQ082IlyvB8ZmVGhX8lfZERaIOZOu6kSHLoI7la0VIokbFUGKbG5bPHPUEAkga9 jTHBfpbtkvlw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,257,1613462400"; d="scan'208";a="387644539" Received: from bmca4bf01706bbf.iind.intel.com (HELO localhost.localdomain) ([10.190.213.111]) by orsmga006.jf.intel.com with ESMTP; 28 Apr 2021 02:29:49 -0700 From: Kumar Amber To: dev@openvswitch.org Date: Wed, 28 Apr 2021 14:49:29 +0530 Message-Id: <20210428091931.2090062-5-kumar.amber@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210428091931.2090062-1-kumar.amber@intel.com> References: <20210428075554.2086279-7-kumar.amber@intel.com> <20210428091931.2090062-1-kumar.amber@intel.com> MIME-Version: 1.0 Cc: Kumar Amber , i.maximets@ovn.org Subject: [ovs-dev] [v2 v2 4/6] dpif-netdev: add avx512 miniflow extract for traffic ip/udp X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" This patch introduces avx512 optimized function pointer for IP/UDP traffic type and supporting functions in dpif-netdev-extract-avx512. Signed-off-by: Harry van Haaren Co-authored-by: Kumar Amber Signed-off-by: Kumar Amber --- lib/automake.mk | 1 + lib/dpdk.c | 1 + lib/dpif-netdev-extract-avx512.c | 218 ++++++++++++++++++++++++++++++ lib/dpif-netdev-private-extract.c | 5 + lib/dpif-netdev-private-extract.h | 11 ++ 5 files changed, 236 insertions(+) create mode 100644 lib/dpif-netdev-extract-avx512.c diff --git a/lib/automake.mk b/lib/automake.mk index b04fd672f..f3412352a 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -113,6 +113,7 @@ lib_libopenvswitch_la_SOURCES = \ lib/dpif-netdev-lookup-generic.c \ lib/dpif-netdev.c \ lib/dpif-netdev.h \ + lib/dpif-netdev-extract-avx512.c \ lib/dpif-netdev-extract-study.c \ lib/dpif-netdev-private-dfc.h \ lib/dpif-netdev-private-dpcls.h \ diff --git a/lib/dpdk.c b/lib/dpdk.c index a9494a40f..e0c76abe3 100644 --- a/lib/dpdk.c +++ b/lib/dpdk.c @@ -657,6 +657,7 @@ dpdk_get_cpu_has_isa(const char *arch, const char *feature) CHECK_CPU_FEATURE(feature, "avx512f", RTE_CPUFLAG_AVX512F); CHECK_CPU_FEATURE(feature, "avx512vpopcntdq", RTE_CPUFLAG_AVX512VPOPCNTDQ); CHECK_CPU_FEATURE(feature, "bmi2", RTE_CPUFLAG_BMI2); + CHECK_CPU_FEATURE(feature, "avx512bw", RTE_CPUFLAG_AVX512BW); #endif VLOG_WARN("Unknown CPU arch,feature: %s,%s. Returning not supported.\n", diff --git a/lib/dpif-netdev-extract-avx512.c b/lib/dpif-netdev-extract-avx512.c new file mode 100644 index 000000000..169775f4b --- /dev/null +++ b/lib/dpif-netdev-extract-avx512.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2021 Intel. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include + +#include "dpdk.h" +#include "dpif-netdev-private-dpcls.h" +#include "dpif-netdev-private-extract.h" +#include "flow.h" + +/* This file contains optimized implementations of miniflow_extract() + * for specific common traffic patterns. The optimizations allow for + * quick probing of a specific packet type, and if a match with a specific + * type is found, a shuffle like proceedure builds up the required miniflow. + * + * The functionality here can be easily auto-validated and tested against the + * scalar miniflow_extract() function. As such, manual review of the code by + * the community (although welcome) is not required. Confidence in the + * correctness of the code can be had from the autovalidation. + */ + +/* Generator for EtherType masks and values. */ +#define PATTERN_ETHERTYPE_GEN(type_b0, type_b1) \ + 0, 0, 0, 0, 0, 0, /* Ether MAC DST */ \ + 0, 0, 0, 0, 0, 0, /* Ether MAC SRC */ \ + type_b0, type_b1, /* EtherType */ + +#define PATTERN_ETHERTYPE_MASK PATTERN_ETHERTYPE_GEN(0xFF, 0xFF) +#define PATTERN_ETHERTYPE_IPV4 PATTERN_ETHERTYPE_GEN(0x08, 0x00) + +/* Generator for checking IPv4 ver, ihl, and proto */ +#define PATTERN_IPV4_GEN(VER_IHL, FLAG_OFF_B0, FLAG_OFF_B1, PROTO) \ + VER_IHL, /* Version and IHL */ \ + 0, 0, 0, /* DSCP, ECN, Total Lenght */ \ + 0, 0, /* Identification */ \ + /* Flags/Fragment offset: don't match MoreFrag (MF) or FragOffset */ \ + FLAG_OFF_B0, FLAG_OFF_B1, \ + 0, /* TTL */ \ + PROTO, /* Protocol */ \ + 0, 0, /* Header checksum */ \ + 0, 0, 0, 0, /* Src IP */ \ + 0, 0, 0, 0, /* Dst IP */ + +#define PATTERN_IPV4_MASK PATTERN_IPV4_GEN(0xFF, 0xFE, 0xFF, 0xFF) +#define PATTERN_IPV4_UDP PATTERN_IPV4_GEN(0x45, 0, 0, 0x11) + +#define NU 0 +#define PATTERN_IPV4_UDP_SHUFFLE \ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, NU, NU, /* Ether */ \ + 26, 27, 28, 29, 30, 31, 32, 33, NU, NU, NU, NU, 20, 15, 22, 23, /* IPv4 */ \ + 34, 35, 36, 37, NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, /* UDP */ + +/* Masks for Ether()/IP()/UDP() traffic */ +static const uint8_t eth_ip_udp_mask[64] = { + PATTERN_ETHERTYPE_MASK PATTERN_IPV4_MASK +}; +static const uint8_t eth_ip_udp_values[64] = { + PATTERN_ETHERTYPE_IPV4 PATTERN_IPV4_UDP +}; +static const uint8_t eth_ip_udp_shuf[64] = { + PATTERN_IPV4_UDP_SHUFFLE +}; + +static inline __m512i +__attribute__((target("avx512bw"))) +_mm512_maskz_permutex2var_epi8_skx(__mmask64 k_mask, + __m512i v_data_0, + __m512i v_shuf_idxs, + __m512i v_data_1) +{ + /* Manipulate shuffle indexes for u16 size. */ + __mmask64 k_mask_odd_lanes = 0xAAAAAAAAAAAAAAAA; + /* clear away ODD lane bytes. Cannot be done above due to no u8 shift */ + __m512i v_shuf_idx_evn = _mm512_mask_blend_epi8(k_mask_odd_lanes, + v_shuf_idxs, _mm512_setzero_si512()); + v_shuf_idx_evn = _mm512_srli_epi16(v_shuf_idx_evn, 1); + + __m512i v_shuf_idx_odd = _mm512_srli_epi16(v_shuf_idxs, 9); + + /* Shuffle each half at 16-bit width */ + __m512i v_shuf1 = _mm512_permutex2var_epi16(v_data_0, v_shuf_idx_evn, + v_data_1); + __m512i v_shuf2 = _mm512_permutex2var_epi16(v_data_0, v_shuf_idx_odd, + v_data_1); + + /* Find if the shuffle index was odd, via mask and compare */ + uint16_t index_odd_mask = 0x1; + const __m512i v_index_mask_u16 = _mm512_set1_epi16(index_odd_mask); + + /* EVEN lanes, find if u8 index was odd, result as u16 bitmask */ + __m512i v_idx_even_masked = _mm512_and_si512(v_shuf_idxs, + v_index_mask_u16); + __mmask32 evn_rotate_mask = _mm512_cmpeq_epi16_mask(v_idx_even_masked, + v_index_mask_u16); + + /* ODD lanes, find if u8 index was odd, result as u16 bitmask */ + __m512i v_shuf_idx_srli8 = _mm512_srli_epi16(v_shuf_idxs, 8); + __m512i v_idx_odd_masked = _mm512_and_si512(v_shuf_idx_srli8, + v_index_mask_u16); + __mmask32 odd_rotate_mask = _mm512_cmpeq_epi16_mask(v_idx_odd_masked, + v_index_mask_u16); + odd_rotate_mask = ~odd_rotate_mask; + + /* Rotate and blend results from each index */ + __m512i v_shuf_res_evn = _mm512_mask_srli_epi16(v_shuf1, evn_rotate_mask, + v_shuf1, 8); + __m512i v_shuf_res_odd = _mm512_mask_slli_epi16(v_shuf2, odd_rotate_mask, + v_shuf2, 8); + + /* If shuffle index was odd, blend shifted version */ + __m512i v_shuf_result = _mm512_mask_blend_epi8(k_mask_odd_lanes, + v_shuf_res_evn, v_shuf_res_odd); + + __m512i v_zeros = _mm512_setzero_si512(); + __m512i v_result_kmskd = _mm512_mask_blend_epi8(k_mask, v_zeros, + v_shuf_result); + + return v_result_kmskd; +} + +static inline void +__attribute__((target("avx512bw"))) +avx512_ipv4_udp_store(const uint8_t *pkt, struct miniflow *mf, + uint32_t in_port) +{ + int64_t u0b = 0x18a0000000000000; + int64_t u1b = 0x0000000000040401; + __m128i v_bits = {u0b, u1b}; + + /* Store mf Bits */ + uint64_t *bits = (void *)&mf->map.bits[0]; + uint64_t *blocks = miniflow_values(mf); + _mm_storeu_si128((void *) bits, v_bits); + + /* Load packet and shuffle */ + __m512i v_pkt0 = _mm512_loadu_si512(&pkt[0]); + __m512i v_eth_ip_udp_shuf = _mm512_loadu_si512(eth_ip_udp_shuf); + + /* Shuffle pkt and store blocks */ + __mmask64 k_shufzero = 0b0000111111110000111111110011111111111111; + __m512i v_zeros = _mm512_setzero_si512(); + __m512i v_blk0 = _mm512_maskz_permutex2var_epi8_skx(k_shufzero, + v_pkt0, v_eth_ip_udp_shuf, v_zeros); + + _mm512_storeu_si512(&blocks[2], v_blk0); + + uint64_t inp = ((uint64_t) in_port) << 32; + blocks[0] = inp; +} + +static inline uint32_t +__attribute__((target("avx512bw"))) +avx512_ipv4_udp_probe(const uint8_t *pkt, uint32_t len) +{ + /* Packet data is masked to known IPv4/UDP parse length. */ + uint64_t klen = UINT64_MAX; + if (len < 64) { + klen = (1ULL << len) - 1; + } + + __m512i v_pkt0 = _mm512_maskz_loadu_epi8(klen, &pkt[0]); + __m512i v_eth_ip_udp_mask = _mm512_loadu_si512(eth_ip_udp_mask); + __m512i v_eth_ip_udp_vals = _mm512_loadu_si512(eth_ip_udp_values); + __m512i v_pkt0_masked = _mm512_and_si512(v_pkt0, v_eth_ip_udp_mask); + __mmask64 k_cmp = _mm512_cmpeq_epi8_mask(v_pkt0_masked, v_eth_ip_udp_vals); + + return (k_cmp == -1); +} + +uint32_t +__attribute__((target("avx512bw"))) +mfex_avx512_ipv4_udp(struct dp_packet_batch *packets, + struct netdev_flow_key *keys, + uint32_t keys_size OVS_UNUSED, odp_port_t in_port, + void *pmd_handle OVS_UNUSED) +{ + uint32_t hitmask = 0; + struct dp_packet *packet; + DP_PACKET_BATCH_FOR_EACH (i, packet, packets) { + const uint32_t size = dp_packet_size(packet); + const uint8_t *pkt = dp_packet_data(packet); + uint32_t match = avx512_ipv4_udp_probe(pkt, size); + if (match) { + avx512_ipv4_udp_store(pkt, &keys[i].mf, in_port); + hitmask |= 1 << i; + } + } + return hitmask; +} + +int32_t +mfex_avx512_probe(void) +{ + int avx512f_available = dpdk_get_cpu_has_isa("x86_64", "avx512f"); + int bmi2_available = dpdk_get_cpu_has_isa("x86_64", "bmi2"); + int avx512bw_available = dpdk_get_cpu_has_isa("x86_64", "avx512bw"); + if (!avx512f_available || !avx512bw_available || !bmi2_available) { + return -ENOTSUP; + } + + return 0; +} diff --git a/lib/dpif-netdev-private-extract.c b/lib/dpif-netdev-private-extract.c index 76c24c2f8..060c1939a 100644 --- a/lib/dpif-netdev-private-extract.c +++ b/lib/dpif-netdev-private-extract.c @@ -47,6 +47,11 @@ static struct dpif_miniflow_extract_impl mfex_impls[] = { .extract_func = mfex_study_traffic, .name = "study", }, + { + .probe = mfex_avx512_probe, + .extract_func = mfex_avx512_ipv4_udp, + .name = "avx512_ip_udp", + }, }; BUILD_ASSERT_DECL(MFEX_IMPLS_MAX_SIZE > ARRAY_SIZE(mfex_impls)); diff --git a/lib/dpif-netdev-private-extract.h b/lib/dpif-netdev-private-extract.h index 3ada413bb..e7b45c2b1 100644 --- a/lib/dpif-netdev-private-extract.h +++ b/lib/dpif-netdev-private-extract.h @@ -118,4 +118,15 @@ mfex_study_traffic(struct dp_packet_batch *packets, uint32_t keys_size, odp_port_t in_port, void *pmd_handle); +/* Probe function to detect CPU ISA for SKX. */ +int32_t +mfex_avx512_probe(void); + +/* Traffic specific AVX512 Eth/Ipv4/Udp traffic type for SKX. */ +uint32_t +mfex_avx512_ipv4_udp(struct dp_packet_batch *packets, + struct netdev_flow_key *keys, + uint32_t keys_size, odp_port_t in_port, + void *pmd_handle); + #endif /* DPIF_NETDEV_AVX512_EXTRACT */ From patchwork Wed Apr 28 09:19:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Amber X-Patchwork-Id: 1471033 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FVYJR4wxrz9sXG for ; Wed, 28 Apr 2021 19:30:15 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 8BD9D8438F; Wed, 28 Apr 2021 09:30:13 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ViYXjw22DR_m; Wed, 28 Apr 2021 09:30:11 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTP id 164AE84440; Wed, 28 Apr 2021 09:30:09 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id E1361C0022; Wed, 28 Apr 2021 09:30:08 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 14C64C0022 for ; Wed, 28 Apr 2021 09:30:08 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id E429E84374 for ; Wed, 28 Apr 2021 09:29:57 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vLyeUKzviQUy for ; Wed, 28 Apr 2021 09:29:55 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by smtp1.osuosl.org (Postfix) with ESMTPS id 781D284345 for ; Wed, 28 Apr 2021 09:29:54 +0000 (UTC) IronPort-SDR: Rl2xuebOFGf+JBH2gVt4Z5i+ITH2XodULn8AId+D9m2HvwLDYdzeWi7A2BszNxXnTNkLxlrKcT WIVHEqtlz8BA== X-IronPort-AV: E=McAfee;i="6200,9189,9967"; a="260650415" X-IronPort-AV: E=Sophos;i="5.82,257,1613462400"; d="scan'208";a="260650415" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Apr 2021 02:29:54 -0700 IronPort-SDR: MhOrxm3ujrM2IeQUohuTXF2iknytTrzWpU1kx+dKdMjv3POLEquNQH5WgRE608p1ww1yY+9Fcb oZm+iFI6Mjog== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,257,1613462400"; d="scan'208";a="387644547" Received: from bmca4bf01706bbf.iind.intel.com (HELO localhost.localdomain) ([10.190.213.111]) by orsmga006.jf.intel.com with ESMTP; 28 Apr 2021 02:29:52 -0700 From: Kumar Amber To: dev@openvswitch.org Date: Wed, 28 Apr 2021 14:49:30 +0530 Message-Id: <20210428091931.2090062-6-kumar.amber@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210428091931.2090062-1-kumar.amber@intel.com> References: <20210428075554.2086279-7-kumar.amber@intel.com> <20210428091931.2090062-1-kumar.amber@intel.com> MIME-Version: 1.0 Cc: Kumar Amber , i.maximets@ovn.org Subject: [ovs-dev] [v2 v2 5/6] docs/dpdk/bridge: add miniflow extract section. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" This commit adds a section to the dpdk/bridge.rst netdev documentation, detailing the added miniflow functionality. The newly added commands are documented, and sample output is provided. The use of auto-validator and special study function is also described in detail as well as running fuzzy tests. Signed-off-by: Kumar Amber Co-authored-by: Cian Ferriter Signed-off-by: Cian Ferriter --- Documentation/topics/dpdk/bridge.rst | 80 ++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/Documentation/topics/dpdk/bridge.rst b/Documentation/topics/dpdk/bridge.rst index ca90d7bdb..92fc3594f 100644 --- a/Documentation/topics/dpdk/bridge.rst +++ b/Documentation/topics/dpdk/bridge.rst @@ -251,3 +251,83 @@ available in order to test it with the OVS unit test suite. When building with a CPU that supports AVX512, use the following configure option :: $ ./configure --enable-dpif-default-avx512 + +Miniflow Extract +---------------- + +Miniflow extract (MFEX) performs parsing of the raw packets and extracts the +important header information into a compressed miniflow. This miniflow is +composed of bits and blocks where the bits signify which blocks are set or +have values where as the blocks hold the metadata, ip, udp, vlan, etc. These +values are used by the datapath for switching decisions later. + +Most modern CPUs are have SIMD capabilities. These SIMD instructions are able +to process a vector rather than act on one single data. OVS provides multiple +implementations of miniflow extract. This allows the user to take advantage +of SIMD instructions like AVX512 to gain additional performance. + +A list of implementations can be obtained by the following command. The +command also shows whether the CPU supports each implementation :: + + $ ovs-appctl dpif-netdev/miniflow-parser-get + Available Optimized Miniflow Extracts: + autovalidator (available: True) + disable (available: True) + study (available: True) + avx512_ip_udp (available: True) + +An implementation can be selected manually by the following command :: + + $ ovs-appctl dpif-netdev/miniflow-parser-set study + +Also user can select the study implementation which studies the traffic for +a specific number of packets by applying all availbale implementaions of +miniflow extract and than chooses the one with most optimal result for that +traffic pattern. + +Miniflow Extract Validation +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As multiple versions of miniflow extract can co-exist, each with different +CPU ISA optimizations, it is important to validate that they all give the +exact same results. To easily test all miniflow implementations, an +``autovalidator`` implementation of the miniflow exists. This implementation +runs all other available miniflow extract implementations, and verifies that +the results are identical. + +Running the OVS unit tests with the autovalidator enabled ensures all +implementations provide the same results. + +To set the Miniflow autovalidator, use this command :: + + $ ovs-appctl dpif-netdev/miniflow-parser-set autovalidator + +Running Fuzzy test with Autovalidator ++++++++++++++++++++++++++++++++++++++ + +Fuzzy tests can also be done on minfilow extract with the help of +auto-validator and Scapy. The steps below describes the steps to +reproduce the setup with IP being fuzzed to generate packets. + +Scapy is used to create fuzzy IP packets and save them into a PCAP :: + + l1 = Ether() + l2 = fuzz(IP()) + l3 = UDP() + pkt = l1/l2/l3 + +Set the miniflow extract to autovalidator using :: + + $ ovs-appctl dpif-netdev/miniflow-parser-set autovalidator + +OVS is configured to receive the generated packets :: + + $ ovs-vsctl add-port br0 pcap0 -- \ + set Interface pcap0 type=dpdk options:dpdk-devargs=net_pcap0 + "rx_pcap=fuzzy.pcap" + +With this workflow, the autovalidator will ensure that all MFEX +implementations are classifying each packet in exactly the same way. +If an optimized MFEX implementation causes a different miniflow to be +generated, the autovalidator has ovs_assert and logging statements that +will inform about the issue. From patchwork Wed Apr 28 09:19:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Amber X-Patchwork-Id: 1471034 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FVYJY1Ffvz9sXN for ; Wed, 28 Apr 2021 19:30:20 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 5609640E9D; Wed, 28 Apr 2021 09:30:19 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Hq0U1YG1EwBD; Wed, 28 Apr 2021 09:30:17 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp4.osuosl.org (Postfix) with ESMTP id 96AAE40EE3; Wed, 28 Apr 2021 09:30:15 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 50968C0001; Wed, 28 Apr 2021 09:30:15 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 4047DC0001 for ; Wed, 28 Apr 2021 09:30:14 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 3DD4984307 for ; Wed, 28 Apr 2021 09:29:59 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id tN6UDJ6KzD0h for ; Wed, 28 Apr 2021 09:29:57 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by smtp1.osuosl.org (Postfix) with ESMTPS id B558284396 for ; Wed, 28 Apr 2021 09:29:56 +0000 (UTC) IronPort-SDR: Aqbzb4mnR4zC8rKdYxynUQYPnLl8XMo5/MnLK1VkhO8Qe7Zs+I42mCcHvpxit8wnKPMgw9xMp1 wWOH/6cT3PEw== X-IronPort-AV: E=McAfee;i="6200,9189,9967"; a="260650422" X-IronPort-AV: E=Sophos;i="5.82,257,1613462400"; d="scan'208";a="260650422" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Apr 2021 02:29:56 -0700 IronPort-SDR: BY6rq44KTy53MrfPBJLCArYGUD9ZRWJLbRJ4gRvVwJEz3V255bAk3LkBKRIXj6+rBMTiENODzE IOgkMlu/XAZA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,257,1613462400"; d="scan'208";a="387644559" Received: from bmca4bf01706bbf.iind.intel.com (HELO localhost.localdomain) ([10.190.213.111]) by orsmga006.jf.intel.com with ESMTP; 28 Apr 2021 02:29:54 -0700 From: Kumar Amber To: dev@openvswitch.org Date: Wed, 28 Apr 2021 14:49:31 +0530 Message-Id: <20210428091931.2090062-7-kumar.amber@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210428091931.2090062-1-kumar.amber@intel.com> References: <20210428075554.2086279-7-kumar.amber@intel.com> <20210428091931.2090062-1-kumar.amber@intel.com> MIME-Version: 1.0 Cc: Kumar Amber , i.maximets@ovn.org Subject: [ovs-dev] [v2 v2 6/6] dpif-netdev: Add configure to enable autovalidator at build time. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" This commit adds a new command to allow the user to enable autovalidatior by default at build time thus allowing for runnig unit test by default. $ ./configure --enable-mfex-default-autovalidator Signed-off-by: Kumar Amber Co-authored-by: Harry van Haaren Signed-off-by: Harry van Haaren --- Documentation/topics/dpdk/bridge.rst | 5 +++++ NEWS | 10 ++++++++++ acinclude.m4 | 16 ++++++++++++++++ configure.ac | 1 + lib/dpif-netdev-private-extract.c | 15 +++++++++++++++ lib/dpif-netdev-private-extract.h | 5 +++++ lib/dpif-netdev.c | 4 ++-- 7 files changed, 54 insertions(+), 2 deletions(-) diff --git a/Documentation/topics/dpdk/bridge.rst b/Documentation/topics/dpdk/bridge.rst index 92fc3594f..3dc21666b 100644 --- a/Documentation/topics/dpdk/bridge.rst +++ b/Documentation/topics/dpdk/bridge.rst @@ -302,6 +302,11 @@ To set the Miniflow autovalidator, use this command :: $ ovs-appctl dpif-netdev/miniflow-parser-set autovalidator +A compile time option is available in order to test it with the OVS unit +test suite. Use the following configure option :: + + $ ./configure --enable-mfex-default-autovalidator + Running Fuzzy test with Autovalidator +++++++++++++++++++++++++++++++++++++ diff --git a/NEWS b/NEWS index 34a42250a..e3a547d91 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,16 @@ Post-v2.15.0 * Optimize dp_netdev_output by enhancing compiler optimization potential. * Optimize netdev sending by assuming the happy case, and using fallback for if the netdev doesnt meet the required HWOL needs of a packet. + * Add command line option to switch between mfex function pointers. + * Add miniflow extract auto-validator function to compare different + miniflow extract implementations against default implementation. + * Add study function to miniflow function table which studies packet + and automatically chooses the best miniflow implementation for that + traffic. + * Add AVX512 based optimized miniflow extract function for traffic type + IP/UDP. + * Add build time configure command to enable auto-validatior as default + miniflow implementation at build time. v2.15.0 - 15 Feb 2021 diff --git a/acinclude.m4 b/acinclude.m4 index 5fbcd9872..e2704cfda 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -14,6 +14,22 @@ # See the License for the specific language governing permissions and # limitations under the License. +dnl Set OVS MFEX Autovalidator as default miniflow extract at compile time? +dnl This enables automatically running all unit tests with all MFEX +dnl implementations. +AC_DEFUN([OVS_CHECK_MFEX_AUTOVALIDATOR], [ + AC_ARG_ENABLE([mfex-default-autovalidator], + [AC_HELP_STRING([--enable-mfex-default-autovalidator], [Enable MFEX autovalidator as default miniflow_extract implementation.])], + [autovalidator=yes],[autovalidator=no]) + AC_MSG_CHECKING([whether MFEX Autovalidator is default implementation]) + if test "$autovalidator" != yes; then + AC_MSG_RESULT([no]) + else + OVS_CFLAGS="$OVS_CFLAGS -DMFEX_AUTOVALIDATOR_DEFAULT" + AC_MSG_RESULT([yes]) + fi +]) + dnl Set OVS DPCLS Autovalidator as default subtable search at compile time? dnl This enables automatically running all unit tests with all DPCLS dnl implementations. diff --git a/configure.ac b/configure.ac index e45685a6c..46c402892 100644 --- a/configure.ac +++ b/configure.ac @@ -186,6 +186,7 @@ OVS_ENABLE_SPARSE OVS_CTAGS_IDENTIFIERS OVS_CHECK_DPCLS_AUTOVALIDATOR OVS_CHECK_DPIF_AVX512_DEFAULT +OVS_CHECK_MFEX_AUTOVALIDATOR OVS_CHECK_BINUTILS_AVX512 AC_ARG_VAR(KARCH, [Kernel Architecture String]) diff --git a/lib/dpif-netdev-private-extract.c b/lib/dpif-netdev-private-extract.c index 060c1939a..e88c6fb77 100644 --- a/lib/dpif-netdev-private-extract.c +++ b/lib/dpif-netdev-private-extract.c @@ -173,3 +173,18 @@ dpif_miniflow_extract_autovalidator(struct dp_packet_batch *packets, /* Always return full hitmask as scalar mfex will always work. */ return (1ULL << cnt) - 1; } + +miniflow_extract_func +dpif_miniflow_extract_get_default(void) +{ + +#ifdef MFEX_AUTOVALIDATOR_DEFAULT + ovs_assert(mfex_impls[0].extract_func == + dpif_miniflow_extract_autovalidator); + VLOG_INFO("Default miniflow Extract implementation %s \n", + mfex_impls[0].name); + return mfex_impls[0].extract_func; +#else + return NULL; +#endif +} diff --git a/lib/dpif-netdev-private-extract.h b/lib/dpif-netdev-private-extract.h index e7b45c2b1..967dc10e7 100644 --- a/lib/dpif-netdev-private-extract.h +++ b/lib/dpif-netdev-private-extract.h @@ -129,4 +129,9 @@ mfex_avx512_ipv4_udp(struct dp_packet_batch *packets, uint32_t keys_size, odp_port_t in_port, void *pmd_handle); +/* Retrieve the default miniflow extract or auto-validator + * based upon build time configuration choosen by the user. */ +miniflow_extract_func +dpif_miniflow_extract_get_default(void); + #endif /* DPIF_NETDEV_AVX512_EXTRACT */ diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index ebdaf33aa..41fc6c09e 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -6250,8 +6250,8 @@ dp_netdev_configure_pmd(struct dp_netdev_pmd_thread *pmd, struct dp_netdev *dp, /* Initialize DPIF function pointer to the default configured version. */ pmd->netdev_input_func = dp_netdev_impl_get_default(); - /*Init default miniflow_extract function */ - pmd->miniflow_extract_opt = NULL; + /* Init default miniflow_extract function */ + pmd->miniflow_extract_opt = dpif_miniflow_extract_get_default(); /* init the 'flow_cache' since there is no * actual thread created for NON_PMD_CORE_ID. */