From patchwork Tue Mar 27 07:54:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shahaf Shuler X-Patchwork-Id: 891412 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=Mellanox.com header.i=@Mellanox.com header.b="vyiMTp7P"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 409Ncj5Qbpz9ryG for ; Tue, 27 Mar 2018 18:56:21 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id C2CD81557; Tue, 27 Mar 2018 07:55:50 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 45C57DDF for ; Tue, 27 Mar 2018 07:55:48 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-db5eur01on0088.outbound.protection.outlook.com [104.47.2.88]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 9AF1851F for ; Tue, 27 Mar 2018 07:55:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=YpsDy4rbS+in2ecW3Ui9jhP+Jh9jtxJ+WnWksFDPD3M=; b=vyiMTp7PKi+gEpux6++UeWxBBwSUBsWvGCnG8t71E+Ke6NYLzJLkIGM1edAUkjppzehgHNYkaiTrGwHXktlZnnHbOmdkPhUtwK5FLIYenMaFLEQrdQLxOvfKBa5RZIsDkhnIr5tYqKNlHkCk0Ylag1cFleh/hf1xbl0+aBTBE3M= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=shahafs@mellanox.com; Received: from mellanox.com (141.226.120.58) by AM0PR05MB4418.eurprd05.prod.outlook.com (2603:10a6:208:5a::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.609.10; Tue, 27 Mar 2018 07:55:42 +0000 From: Shahaf Shuler To: fc@napatech.com, ian.stokes@intel.com Date: Tue, 27 Mar 2018 10:54:42 +0300 Message-Id: X-Mailer: git-send-email 2.12.0 In-Reply-To: References: <1517209188-16608-2-git-send-email-yliu@fridaylinux.org> MIME-Version: 1.0 X-Originating-IP: [141.226.120.58] X-ClientProxiedBy: DB6PR1001CA0041.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:4:55::27) To AM0PR05MB4418.eurprd05.prod.outlook.com (2603:10a6:208:5a::15) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 913d296c-f1d2-49c5-2c47-08d593b823f5 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(4604075)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:AM0PR05MB4418; X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 3:a69PslQq66PJG/xmJqNuS5wQ1uHXzXPXxNWybuai4YbESvWAS++gb/+5BCx/GixwdZswSzrRzBCrZLgwH8XLoZQcod4UwLrlsRgCAgSa9sDxBMI5nBPHs5xSAYMKq1AhKwdoqAMYbQfTsoW6KWasvdsDVc/r4Mcm3hsOd0b7xEw5OEBIa1RB3k0zccgkNc/LvAOzATZ7Dyj0a7XaV/y8unlHJ7KPDFO67wpuB0JsyhM+qbJ92zuU3Raun5M2sQpU; 25:IEALR0FO13jbcVbWyIEni15eHpHwatoOfyCQ3p4Uw5mamCRc5aCc03rZP75cxLl5X/iU/URvl8jbxexAGBRw/AekWl55iwBx50BbQW7rSzN4IXJe/z1dDCBqfvoR8Fo85L5cHCjo9QX8XSez7sVAhufW4TVgkJ1Ag3qRj0yD4BOU4uGBowWXqdq7i0ULsfnG0r9ebKbgUlyk4xs6xOt3rDSxs1RaDz0Ha6VRT6wLVVE+eUbJimR5LGOBSOkO6FJLDQGlNzZ/vntoskZ9w2JkFFw+ZJlMPEeX5vUZ2KRBrxwpuWUYcPegvIQOo2IvQ1Rp1zTK/l8reqm474yVjGxFcg==; 31:+tPKd3x9rXApWwipV++2rx4Ez+yKXMtdqkb/NuKLfuMeDGRIfjwf6V3WtlQGMvlXWbvtsg3EpLnatvyTAl7O8hnsPVaIr/9IfUo5Rn8m6ei1Dz7iLk302tySEZOmXWFF1phhe7UsRxOdaGsMN0/8KGZlPPNob0TxulcWh/h5UW7EdZPa8lprlQvZafOzOFfDfGga+YdmDUXeD+eb3jwcoGHCRNB0pAuwj0JNbBwL/iI= X-MS-TrafficTypeDiagnostic: AM0PR05MB4418: X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 20:Me2lcO+ucejL7ut5TadbA9eJ/9qIB7VVksG6mMKykr5iujnPX3F2z0dh2ILTiWfFVK/7xzZRmh17cMITfr9jGb4db4NxE3ulBcxMNYDRb2y0d3LyPosi+DWWj0EVdl7N8a4mEcB8OXZtZJE2u3DMW4EEHNZDWjBXtUrWYU9MtNV8vP0mMiAUefOsOEPxgSC2sWr6ssAYoZhrmMthXNxYbloBRiXsd80vkKBlAXuT98i4TLH5j2BoExBwjgHLVroi60aXBF/ICafyPoTT3hGJ0BY3VtvZ6xoy5nrL/EY667hJzExr1xpYC1VhErvKOiF4U+Q4/KpPIZRV+IZhKbMV1MNGHsHyFWZUDuQ9WkNWEosTDd/2ZxoMmqxofxAW+JGZVawdfZm0qhAMIrlbvkmxdt/iwECgUBTijsNhXg7nz3gL0u/kasWaXCoBGKoXH75BKQeAOvd2TVtBHhp4+KARLBp3qNa11X8eU9m1NxjlFeQlrvZyC/L8IYXVzphSVnll; 4:Zh0RNtwtIORLZT340zpck9FZvGVOb3pyV/k14uvSnFJJmFylrM8YYzjtYeyfowoqQVNPi+5DphJcXsd2ldeCWKEqjrJ0xGN5JxPrki7PLMzGKnlAppqCjnzWlfzd1jmehXrL3OUHPj/sXBNbCSrQAYaGVjcuk7L6LBj5XUgVh94F+G6mdoyfgi3WEM1lHb7DlST8l28y6JR+gnPhAyS7JJkWz35LolCI0s5tmucUCPHhQ/JMgJalHLoSToGy8JUy13KZjyngnr9O40RRQS1KaQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3002001)(3231221)(944501327)(52105095)(6055026)(6041310)(20161123564045)(20161123558120)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM0PR05MB4418; BCL:0; PCL:0; RULEID:; SRVR:AM0PR05MB4418; X-Forefront-PRVS: 0624A2429E X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(366004)(39380400002)(376002)(396003)(199004)(189003)(50226002)(7736002)(68736007)(3846002)(36756003)(6116002)(7696005)(50466002)(51416003)(21086003)(52116002)(59450400001)(386003)(76176011)(118296001)(16586007)(97736004)(8936002)(486005)(956004)(486005)(478600001)(305945005)(39060400002)(8676002)(25786009)(4326008)(48376002)(186003)(86362001)(26005)(316002)(106356001)(69596002)(16526019)(81156014)(55016002)(2906002)(81166006)(66066001)(105586002)(5660300001)(11346002)(2616005)(53936002)(47776003)(476003)(446003); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR05MB4418; H:mellanox.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM0PR05MB4418; 23:YgZv+o0KwYsGFhWY/o0q+LnsJNRATt9jprzS06xro?= iDvS0LmCGE1Wm5xKtUteDiHQryXdPJjHUw2PMkP5Dyp7oTxELaPvl72alqomLZJ4AJbITzHAaEHB8FoEyGB1kdK1rA++4N/pz0wMwSFc60sJHSOgTQIhGmL4VVA5MMqt/HgC7izGA6/7YbfgxmxlyyIA7TqzBtbQK1xSEeR7PYYk+KKgXNI9bm+Nn/mqvmkFS6BGa1jaMKasInW2HbG/i/J77OD5yctTb8ZvGo1Jw9g6uTWqbZ5mWwZz/ZK5BRgwVphTuBiuRRS+zH6Z8U4YyykAwhmSjklXKzf9Um05cLeRPTRD8L15m6opCH3g5m6G/YAzJlNU9Si8Hz3v6UbfudaTk8gQdIBqIrQYkO3Djqx1JCXnbLmQPZVgRZGMAoDqRYpf/uwb/Ba8lwPWCTofycPTd/BYchBtkvKKeMenxeIgKLq7pEVZVIgy/8xvDRmHgxm3ezd05ihhL3Mv5xDnIkgutEuxXj6a7Pg6/5iOhEK9DXjLvUZHdLFJAdNIm4pTIzX48mmAAlH0FqWsApT9O91LonUraN7lXJJd38oT5N9pHvurHwbXb+8ZC4vzIKvWsXJTlcV6yEBkFRjFt4utUrt7j6LWYOFR+kWH37jZ8XdRLiyWrbIZ39ApAP+sScpr5VvtVc4aTTgovnfLI9N+ytHJhxDkHsqQ/n7qMc9+STdXQ1YUgRVsJQcPOsGjImjH56V51iWeO6nhCwhmWh+7SGuRUkwujwvYUeeNbfPuL5ApKiuP37mZB6sggj5KLlcmv/qzjV0fjlXLkrVKGeUhgEsasq9M0McQRcJM8ZSyPtib1erujGtHUIvfTwBQGK1vrUcAcJPfBQlPi1JdOCjOwqBqVyJauuu7ZsAPvXIHZ3L1Z1m8e8qbed3e+ziOsOGdG4ru0snYxg1zezjcxg8Rmm5Oj17rhSSP5OZ0Vt//XL3KU+XM+YdBtZ5YZQ+KEZ8wPl2U3ppd9gNrQcOcwcak+icx7vrUzPouXLSdHDSjk4YBgZ4h8/PAwYNneVRcGdrnCOPm7b2jrLQLSGzwu66x9jHYvnxuF9cYC9p0w6etKDiLYtxC5nj55bAKXScAqNJ0fBCwPmC3wV6z10Hoa9AG3/avug6p8a22qnml7HlqBztCn99ZQFzildDDmwZA7+Jl8MuLwtNGKXtI54Hb7B9CI2rE52e204SEVF9ddRSrf5PzZqW1effryi+1ZxnOn7sPnE= X-Microsoft-Antispam-Message-Info: kxw5ktoNjLxuvryYdrVFUlFKynwFCed9ddarL63sbww93v5kT9xKxEucH/Gi/wq/redADAZ8mIl8hIGQyLRPmId9o8uNao9hGvzSNgf8l+3qF7/6ijMXWaJuc8PkWfSZwQ1L1aQHsajiFM+aDq3PNa0OyJbC+Q9l5rXiuDi57CIlhL3iJ2hwr5RfjT9KUVTg X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 6:pizSx89hyNKfaoXKGwLhBb1Nc6nLU/qUO0Gs84hRo2MjGSQ6lWzaO8T/Bm/mWXjHt2hcOP1VQJ+qydjbVGCSaPb67NrJ/bFFwTOjnhkuisIws+ESY8KV7NcOjp3INTAyh3oLBCp1c0pW4mG4BZ0gYUrbnfJBoHZDeWt7sfVpgHbityUosWCR6xpeuSGBxqbKr62czp+WyPNzfTzqg/QUvdSXucXGJq0eQMQ1n6ppJbPdYnrHqs3CXkk8COUUK4RmOEP+im+itTnuFICrD6rmAFxo6+uoEgCQ2KQ0zTG+thW4Bpb5lSblJFeI72AQMWuPjXI5Quon5QR5UlvzrQpOMxmZOmTHjCRFQLyHY5McbJrav/NJz+Qr5Ym5wUgjXQWKhIGzwnxuoYJPXih+iuOW+YC4Vd7yFkF4InQqNEbUbgV79lQJaxs3leC4fHh6scXwr5D+tjO1ZOaP1xoJceRRUQ==; 5:Angw03ujE8PQ8tlZi/UQ5smyF3idR7+wlQv7megFfEhZqwXmr6SJS1JSsSPXacYfKWYD2+HloAwieLzkuCKVk3fPJZGM2FkFuXgU/80LkGbSvHFOjMJyJJPWD0gROrb/gTib4kVdPkTpTSXCPwwyGZkuSDyGCfCYNBAQH1OI/kA=; 24:zAZZ1Z4kKfGyDqS7fKyk+jScO0I4qWNQP0JMC2wbIKz3aVNxJcUeSSlYQiia/2aKmCNjOMhdUcyu+bL62GzXydl0ppYIS7tvmaReaEw5/i4= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 7:xCS+jCp3bpdDG8Nstcu9rBHOHJEV4V0cpXLg/SryKdNkM50cmnLXxlcRswPf/CVYPT9ts2AX/RRgyMRZnIBmYNATxEFH89EBlnFdU2/DctZ2T9GYEz4LLnTWjm3C7vpWTvfQzn7NjGnctdXV+dq/U8sE1kJV4oZ+1930BrWsQjNmgXnW0dqCdyS0/pWZNkBJD9soixc1ZSV4+NYAPJnBDMXJJYKVFuHWtooIqLD7+qDXpTAGT4kWk5x1c8ZYWjsl X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Mar 2018 07:55:42.0266 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 913d296c-f1d2-49c5-2c47-08d593b823f5 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4418 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: simon.horman@netronome.com, ovs-dev@openvswitch.org Subject: [ovs-dev] [PATCH v8 1/6] dpif-netdev: associate flow with a mark id X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Yuanhan Liu Most modern NICs have the ability to bind a flow with a mark, so that every packet matches such flow will have that mark present in its descriptor. The basic idea of doing that is, when we receives packets later, we could directly get the flow from the mark. That could avoid some very costly CPU operations, including (but not limiting to) miniflow_extract, emc lookup, dpcls lookup, etc. Thus, performance could be greatly improved. Thus, the major work of this patch is to associate a flow with a mark id (an uint32_t number). The association in netdev datapath is done by CMAP, while in hardware it's done by the rte_flow MARK action. One tricky thing in OVS-DPDK is, the flow tables is per-PMD. For the case there is only one phys port but with 2 queues, there could be 2 PMDs. In other words, even for a single mega flow (i.e. udp,tp_src=1000), there could be 2 different dp_netdev flows, one for each PMD. That could results to the same mega flow being offloaded twice in the hardware, worse, we may get 2 different marks and only the last one will work. To avoid that, a megaflow_to_mark CMAP is created. An entry will be added for the first PMD that wants to offload a flow. For later PMDs, it will see such megaflow is already offloaded, then the flow will not be offloaded to HW twice. Meanwhile, the mark to flow mapping becomes to 1:N mapping. That is what the mark_to_flow CMAP is for. When the first PMD wants to offload a flow, it allocates a new mark and performs the flow offload by reusing the ->flow_put method. When it succeeds, a "mark to flow" entry will be added. For later PMDs, it will get the corresponding mark by above megaflow_to_mark CMAP. Then, another "mark to flow" entry will be added. Co-authored-by: Finn Christensen Signed-off-by: Yuanhan Liu Signed-off-by: Finn Christensen Signed-off-by: Shahaf Shuler --- lib/dpif-netdev.c | 285 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/netdev.h | 6 ++ 2 files changed, 291 insertions(+) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index b07fc6b..2fdb6ef 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -75,6 +75,7 @@ #include "tnl-ports.h" #include "unixctl.h" #include "util.h" +#include "uuid.h" VLOG_DEFINE_THIS_MODULE(dpif_netdev); @@ -430,7 +431,9 @@ struct dp_netdev_flow { /* Hash table index by unmasked flow. */ const struct cmap_node node; /* In owning dp_netdev_pmd_thread's */ /* 'flow_table'. */ + const struct cmap_node mark_node; /* In owning flow_mark's mark_to_flow */ const ovs_u128 ufid; /* Unique flow identifier. */ + const ovs_u128 mega_ufid; /* Unique mega flow identifier. */ const unsigned pmd_id; /* The 'core_id' of pmd thread owning this */ /* flow. */ @@ -441,6 +444,7 @@ struct dp_netdev_flow { struct ovs_refcount ref_cnt; bool dead; + uint32_t mark; /* Unique flow mark assigned to a flow */ /* Statistics. */ struct dp_netdev_flow_stats stats; @@ -1837,6 +1841,180 @@ dp_netdev_pmd_find_dpcls(struct dp_netdev_pmd_thread *pmd, return cls; } +#define MAX_FLOW_MARK (UINT32_MAX - 1) +#define INVALID_FLOW_MARK (UINT32_MAX) + +struct megaflow_to_mark_data { + const struct cmap_node node; + ovs_u128 mega_ufid; + uint32_t mark; +}; + +struct flow_mark { + struct cmap megaflow_to_mark; + struct cmap mark_to_flow; + struct id_pool *pool; + struct ovs_mutex mutex; +}; + +static struct flow_mark flow_mark = { + .megaflow_to_mark = CMAP_INITIALIZER, + .mark_to_flow = CMAP_INITIALIZER, + .mutex = OVS_MUTEX_INITIALIZER, +}; + +static uint32_t +flow_mark_alloc(void) +{ + uint32_t mark; + + if (!flow_mark.pool) { + /* Haven't initiated yet, do it here */ + flow_mark.pool = id_pool_create(0, MAX_FLOW_MARK); + } + + if (id_pool_alloc_id(flow_mark.pool, &mark)) { + return mark; + } + + return INVALID_FLOW_MARK; +} + +static void +flow_mark_free(uint32_t mark) +{ + id_pool_free_id(flow_mark.pool, mark); +} + +/* associate megaflow with a mark, which is a 1:1 mapping */ +static void +megaflow_to_mark_associate(const ovs_u128 *mega_ufid, uint32_t mark) +{ + size_t hash = dp_netdev_flow_hash(mega_ufid); + struct megaflow_to_mark_data *data = xzalloc(sizeof(*data)); + + data->mega_ufid = *mega_ufid; + data->mark = mark; + + cmap_insert(&flow_mark.megaflow_to_mark, + CONST_CAST(struct cmap_node *, &data->node), hash); +} + +/* disassociate meagaflow with a mark */ +static void +megaflow_to_mark_disassociate(const ovs_u128 *mega_ufid) +{ + size_t hash = dp_netdev_flow_hash(mega_ufid); + struct megaflow_to_mark_data *data; + + CMAP_FOR_EACH_WITH_HASH (data, node, hash, &flow_mark.megaflow_to_mark) { + if (ovs_u128_equals(*mega_ufid, data->mega_ufid)) { + cmap_remove(&flow_mark.megaflow_to_mark, + CONST_CAST(struct cmap_node *, &data->node), hash); + free(data); + return; + } + } + + VLOG_WARN("Masked ufid "UUID_FMT" is not associated with a mark?\n", + UUID_ARGS((struct uuid *)mega_ufid)); +} + +static inline uint32_t +megaflow_to_mark_find(const ovs_u128 *mega_ufid) +{ + size_t hash = dp_netdev_flow_hash(mega_ufid); + struct megaflow_to_mark_data *data; + + CMAP_FOR_EACH_WITH_HASH (data, node, hash, &flow_mark.megaflow_to_mark) { + if (ovs_u128_equals(*mega_ufid, data->mega_ufid)) { + return data->mark; + } + } + + VLOG_WARN("Mark id for ufid "UUID_FMT" was not found\n", + UUID_ARGS((struct uuid *)mega_ufid)); + return INVALID_FLOW_MARK; +} + +/* associate mark with a flow, which is 1:N mapping */ +static void +mark_to_flow_associate(const uint32_t mark, struct dp_netdev_flow *flow) +{ + dp_netdev_flow_ref(flow); + + cmap_insert(&flow_mark.mark_to_flow, + CONST_CAST(struct cmap_node *, &flow->mark_node), + hash_int(mark, 0)); + flow->mark = mark; + + VLOG_DBG("Associated dp_netdev flow %p with mark %u\n", flow, mark); +} + +static bool +flow_mark_has_no_ref(uint32_t mark) +{ + struct dp_netdev_flow *flow; + + CMAP_FOR_EACH_WITH_HASH (flow, mark_node, hash_int(mark, 0), + &flow_mark.mark_to_flow) { + if (flow->mark == mark) { + return false; + } + } + + return true; +} + +static int +mark_to_flow_disassociate(struct dp_netdev_pmd_thread *pmd, + struct dp_netdev_flow *flow) +{ + int ret = 0; + uint32_t mark = flow->mark; + struct cmap_node *mark_node = CONST_CAST(struct cmap_node *, + &flow->mark_node); + + cmap_remove(&flow_mark.mark_to_flow, mark_node, hash_int(mark, 0)); + flow->mark = INVALID_FLOW_MARK; + + /* + * no flow is referencing the mark any more? If so, let's + * remove the flow from hardware and free the mark. + */ + if (flow_mark_has_no_ref(mark)) { + struct dp_netdev_port *port; + odp_port_t in_port = flow->flow.in_port.odp_port; + + ovs_mutex_lock(&pmd->dp->port_mutex); + port = dp_netdev_lookup_port(pmd->dp, in_port); + if (port) { + ret = netdev_flow_del(port->netdev, &flow->mega_ufid, NULL); + } + ovs_mutex_unlock(&pmd->dp->port_mutex); + + flow_mark_free(mark); + VLOG_DBG("Freed flow mark %u\n", mark); + + megaflow_to_mark_disassociate(&flow->mega_ufid); + } + dp_netdev_flow_unref(flow); + + return ret; +} + +static void +flow_mark_flush(struct dp_netdev_pmd_thread *pmd) +{ + struct dp_netdev_flow *flow; + + CMAP_FOR_EACH (flow, mark_node, &flow_mark.mark_to_flow) { + if (flow->pmd_id == pmd->core_id) { + mark_to_flow_disassociate(pmd, flow); + } + } +} + static void dp_netdev_pmd_remove_flow(struct dp_netdev_pmd_thread *pmd, struct dp_netdev_flow *flow) @@ -1850,6 +2028,9 @@ dp_netdev_pmd_remove_flow(struct dp_netdev_pmd_thread *pmd, ovs_assert(cls != NULL); dpcls_remove(cls, &flow->cr); cmap_remove(&pmd->flow_table, node, dp_netdev_flow_hash(&flow->ufid)); + if (flow->mark != INVALID_FLOW_MARK) { + mark_to_flow_disassociate(pmd, flow); + } flow->dead = true; dp_netdev_flow_unref(flow); @@ -2429,6 +2610,101 @@ out: return error; } +/* + * There are two flow offload operations here: addition and modification. + * + * For flow addition, this function does: + * - allocate a new flow mark id + * - perform hardware flow offload + * - associate the flow mark with flow and mega flow + * + * For flow modification, both flow mark and the associations are still + * valid, thus only item 2 needed. + */ +static void +try_netdev_flow_put(struct dp_netdev_pmd_thread *pmd, odp_port_t in_port, + struct dp_netdev_flow *flow, struct match *match, + const struct nlattr *actions, size_t actions_len) +{ + struct offload_info info; + struct dp_netdev_port *port; + bool modification = flow->mark != INVALID_FLOW_MARK; + const char *op = modification ? "modify" : "add"; + uint32_t mark; + int ret; + + ovs_mutex_lock(&flow_mark.mutex); + + if (modification) { + mark = flow->mark; + } else { + if (!netdev_is_flow_api_enabled()) { + goto out; + } + + /* + * If a mega flow has already been offloaded (from other PMD + * instances), do not offload it again. + */ + mark = megaflow_to_mark_find(&flow->mega_ufid); + if (mark != INVALID_FLOW_MARK) { + VLOG_DBG("Flow has already been offloaded with mark %u\n", mark); + mark_to_flow_associate(mark, flow); + goto out; + } + + mark = flow_mark_alloc(); + if (mark == INVALID_FLOW_MARK) { + VLOG_ERR("Failed to allocate flow mark!\n"); + goto out; + } + } + info.flow_mark = mark; + + ovs_mutex_lock(&pmd->dp->port_mutex); + port = dp_netdev_lookup_port(pmd->dp, in_port); + if (!port) { + ovs_mutex_unlock(&pmd->dp->port_mutex); + goto out; + } + ret = netdev_flow_put(port->netdev, match, + CONST_CAST(struct nlattr *, actions), + actions_len, &flow->mega_ufid, &info, NULL); + ovs_mutex_unlock(&pmd->dp->port_mutex); + + if (ret) { + VLOG_ERR("Failed to %s netdev flow with mark %u\n", op, mark); + if (!modification) { + flow_mark_free(mark); + } else { + mark_to_flow_disassociate(pmd, flow); + } + goto out; + } + + if (!modification) { + megaflow_to_mark_associate(&flow->mega_ufid, mark); + mark_to_flow_associate(mark, flow); + } + VLOG_DBG("Succeed to %s netdev flow with mark %u\n", op, mark); + +out: + ovs_mutex_unlock(&flow_mark.mutex); +} + +static void +dp_netdev_get_mega_ufid(const struct match *match, ovs_u128 *mega_ufid) +{ + struct flow masked_flow; + size_t i; + + for (i = 0; i < sizeof(struct flow); i++) { + ((uint8_t *)&masked_flow)[i] = ((uint8_t *)&match->flow)[i] & + ((uint8_t *)&match->wc)[i]; + } + dpif_flow_hash(NULL, &masked_flow, sizeof(struct flow), mega_ufid); +} + static struct dp_netdev_flow * dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, struct match *match, const ovs_u128 *ufid, @@ -2464,12 +2740,14 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, memset(&flow->stats, 0, sizeof flow->stats); flow->dead = false; flow->batch = NULL; + flow->mark = INVALID_FLOW_MARK; *CONST_CAST(unsigned *, &flow->pmd_id) = pmd->core_id; *CONST_CAST(struct flow *, &flow->flow) = match->flow; *CONST_CAST(ovs_u128 *, &flow->ufid) = *ufid; ovs_refcount_init(&flow->ref_cnt); ovsrcu_set(&flow->actions, dp_netdev_actions_create(actions, actions_len)); + dp_netdev_get_mega_ufid(match, CONST_CAST(ovs_u128 *, &flow->mega_ufid)); netdev_flow_key_init_masked(&flow->cr.flow, &match->flow, &mask); /* Select dpcls for in_port. Relies on in_port to be exact match. */ @@ -2479,6 +2757,8 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, cmap_insert(&pmd->flow_table, CONST_CAST(struct cmap_node *, &flow->node), dp_netdev_flow_hash(&flow->ufid)); + try_netdev_flow_put(pmd, in_port, flow, match, actions, actions_len); + if (OVS_UNLIKELY(!VLOG_DROP_DBG((&upcall_rl)))) { struct ds ds = DS_EMPTY_INITIALIZER; struct ofpbuf key_buf, mask_buf; @@ -2559,6 +2839,7 @@ flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd, if (put->flags & DPIF_FP_MODIFY) { struct dp_netdev_actions *new_actions; struct dp_netdev_actions *old_actions; + odp_port_t in_port = netdev_flow->flow.in_port.odp_port; new_actions = dp_netdev_actions_create(put->actions, put->actions_len); @@ -2566,6 +2847,9 @@ flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd, old_actions = dp_netdev_flow_get_actions(netdev_flow); ovsrcu_set(&netdev_flow->actions, new_actions); + try_netdev_flow_put(pmd, in_port, netdev_flow, match, + put->actions, put->actions_len); + if (stats) { get_dpif_flow_stats(netdev_flow, stats); } @@ -3635,6 +3919,7 @@ reload_affected_pmds(struct dp_netdev *dp) CMAP_FOR_EACH (pmd, node, &dp->poll_threads) { if (pmd->need_reload) { + flow_mark_flush(pmd); dp_netdev_reload_pmd__(pmd); pmd->need_reload = false; } diff --git a/lib/netdev.h b/lib/netdev.h index ff1b604..9ee3092 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -188,6 +188,12 @@ void netdev_send_wait(struct netdev *, int qid); struct offload_info { const struct dpif_class *dpif_class; ovs_be16 tp_dst_port; /* Destination port for tunnel in SET action */ + + /* + * The flow mark id assigened to the flow. If any pkts hit the flow, + * it will be in the pkt meta data. + */ + uint32_t flow_mark; }; struct dpif_class; struct netdev_flow_dump; From patchwork Tue Mar 27 07:54:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shahaf Shuler X-Patchwork-Id: 891413 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=Mellanox.com header.i=@Mellanox.com header.b="tsoNNRzo"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 409NdK2TGtz9ryG for ; Tue, 27 Mar 2018 18:56:53 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id EB94F1667; Tue, 27 Mar 2018 07:55:51 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 92A381326 for ; Tue, 27 Mar 2018 07:55:49 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-db5eur01on0088.outbound.protection.outlook.com [104.47.2.88]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 6D3CB51F for ; Tue, 27 Mar 2018 07:55:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=lt1o8aNVsajZOwoeYqTuWNFZT5HcN/OeVFU+5pebyGs=; b=tsoNNRzokQPhfYaDW8q+qbRJ2a91UEeRWLZYlOiakfeLiUcXn4ymUA5fNiM3mBrUfTMSxaqmsny1sBIVdYLk/eTt6h96yO4DVeNKMRhwBpeWy+4t6ZnfRtv2MMjFNuURuXGbl5FVeIG1DtHgt40o3VsX1ECA3+BUMiOcccBTQY0= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=shahafs@mellanox.com; Received: from mellanox.com (141.226.120.58) by AM0PR05MB4418.eurprd05.prod.outlook.com (2603:10a6:208:5a::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.609.10; Tue, 27 Mar 2018 07:55:43 +0000 From: Shahaf Shuler To: fc@napatech.com, ian.stokes@intel.com Date: Tue, 27 Mar 2018 10:54:43 +0300 Message-Id: X-Mailer: git-send-email 2.12.0 In-Reply-To: References: <1517209188-16608-2-git-send-email-yliu@fridaylinux.org> MIME-Version: 1.0 X-Originating-IP: [141.226.120.58] X-ClientProxiedBy: DB6PR1001CA0041.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:4:55::27) To AM0PR05MB4418.eurprd05.prod.outlook.com (2603:10a6:208:5a::15) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: d9fc0925-44f0-4c89-0fd8-08d593b824bb X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(4604075)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:AM0PR05MB4418; X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 3:lWuH0qXCcTIy+j89q4VcZn14Uu5P95hLO5mEV4SrSMi0Hw+RFF2DBS6REWQC70V8DyFBM629iLLU8hkCbfokT31yWe6E9j/iOQFubrqcUVFdHOWH+0+YSrz/5Jnkz6gR1Y1fxgfVhRpQLyTK0Jxem+1pIB6pDvZGLIqeUpNVcC3gpus+p3ohsa+kzwQgHi2lfyw4hPPOGWvF105uX+UW2IPDxUcTriI9H+B9ClDATDIqOgrrDHHRvdph27F5oq9d; 25:+rnPCGgQWcuSID4MZPAhIHlE8ctBh711Nq8q93l2IOUkr+67MmSfjaEHRRpMee4fFBE2DSJWzfVXOfBM9Kt1ikId9LCwh6X1wTZ2lYSIXkKPmLemm/axwNioS56l+mSQqYI8vo5BZepYO2dy6slhxomk2Xqv//ck63TP2wwZevkgsW3mUMBmJ0kHHAqQGjSrw22Njd4B9+V+BAydjXMFlVBfkcxHY119yGp/VmZru2lSgJbkc0EUVjwSdHua9qSMxZHi2ZDmIjwaQyiFsjd522gf+OygL+q1ARDXd1al35faZx0Q0p+eDISRp655/6F956T/KHY7xJzZiO3L4lUkmA==; 31:b2mqHvW952DvWQfDPqA3mdKACkpfNKU3z4LPV5iXSz+O9/qf+MnK4Q+LhLoKQ7CaoP6M/SBprwQr5oTYYW6zft68x9iBTCyYsXnfIPs+mVEGsr/uO5BBAiLu5EnjrJ3gvjbzXfQ3fUlkiX3gqkeR1trilENqqZSUW/kfYLSeFM3nAlrHRDufo3T+lQ81I+C6rkYK561IbkPLIkboohjYxpZ1MD0z3xkP+lK3xcqP71E= X-MS-TrafficTypeDiagnostic: AM0PR05MB4418: X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 20:s/r2ZzM+QFVBPUwCocjM2V/bodoq2uE5oTFcLb2au9K0LtFDNB5inzUfVwsiulgcH4gfOYdUpNgzdsfiJaSjmel/fnaRVpEDBE7cQ6nqrSQDqn2ZM8ztu/B0zjVWLbzvqzjQAk4nOlMPbhP/1rvKFV+jkJ6n/aqebuoj87oYJCaX661TSHLSxlU/4WDZPVuTlPxyvE1iUIMPTOoOpNTeA2T34WLx6dgitMOmBM3BmNMczlDP8eLBeypWBTp31Nxyb7+9AWK2cxV4P35f5HNlbN65gcxKoGhcYvj8Qy81Wm7zRDQm0SdLtMzv2gLFbb53dG46n1BQ5tebORcHdpq7O6f25sRxNIoT9wkB8VTdzwFjyGtaICVzIA9sygyb3IWO4AGSrx4MApOxxRjvG6fUqXa5AL1B0UZOSD0sqF0N2Qyd6hGhup847dcktL0BeJh49rIK3GoIakerszR+A/ztU8Tx7ppBcY8/sbmJRU5IDVk1pzPhBk2YaAufT1XLnmhn; 4:9scBURBaBM3MUuNwu97DH8rwTm6a+9+zSBfL751LrzfbUXwZ/IisvwC0BYp6VKeNypdde2tXiwmMV2KoVrtv3/fgmOb85xvsE6RZf8DB0UuJfb9XJQ6RTwdeGr+MzLr433IC3iIfnLP8Rl3OyEoLYFwQXQOMDFzpbPPP/hsLGhIQhzPprS5JVQa0GmXwe05KXwfJbF4qGdtuKsvyHL9i0xInRL0vH+ivU5vHd1lhBgRYCIq8e32Pivr9xVd+6t0N62WGZZP7NiQDKU57Uwr1BQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3002001)(3231221)(944501327)(52105095)(6055026)(6041310)(20161123564045)(20161123558120)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM0PR05MB4418; BCL:0; PCL:0; RULEID:; SRVR:AM0PR05MB4418; X-Forefront-PRVS: 0624A2429E X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(366004)(39380400002)(376002)(396003)(199004)(189003)(50226002)(7736002)(68736007)(3846002)(36756003)(6116002)(7696005)(50466002)(51416003)(21086003)(52116002)(59450400001)(386003)(76176011)(118296001)(16586007)(97736004)(8936002)(486005)(956004)(486005)(478600001)(305945005)(39060400002)(8676002)(25786009)(4326008)(48376002)(186003)(86362001)(26005)(316002)(106356001)(69596002)(16526019)(81156014)(55016002)(2906002)(81166006)(66066001)(105586002)(5660300001)(11346002)(2616005)(53936002)(47776003)(476003)(446003); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR05MB4418; H:mellanox.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM0PR05MB4418; 23:jTGgPRAJelgr9dZaDZG25wMB9fkyCG8ePuDasCyIg?= qhZDmrstn9qS/XSOVJzBvWc4j7LKWnvECs3BfDIfrRWI7ZNhpI4RyIiO7dUYU9Hso99xRwsUtCs+hBD7Ko6vfAk0cslnrsePF4pF/xjkFb76xY9xTQoWwgUTcHHBol78jXfyISH6e64iYsU8v4zjLsMvOsPPZI+sPXwc78VbJuVP+/gQ3uE2KfsMCEqBf6IGskqDKNJBJu6EM6Fkdk5ZLaSmnJikLTtI02DhaSr65J8hv+7FfwqbsgkUEPgX9VO+kksNpEqCl4Ax6FLa/ZDSpXgzC8P6J8wxQaHR0LhTxV/jk+PesNKmri9hdZQ8pcaenKocrbs7FHsucLySPlShohUzrzAkXiZ12LRmWjUR8ANIfnjJOh1/mjqSxZRPzRcq37aeDlq4h1Z1Ti4O8WO6fJqVsYEzFhWmo5PdZSnFRPVumzjNyVdmoRRpcrmggCKdIq2LoNjWtgJZMy3ljxpme4DOz1bo+W8O6+Vt6AsR8Lt6tkYqiDjsmzUdvTAs8m6afoU7VrTLX1BCRFcbFjSdmjzC6BJHKNN7m53A7oVagiYXY6yCgSsePJZtHDuPdMhSTLgLMBRxmEnFqHQ9ZlNIR/1QkZU1iDB3maqJNxb7yoLS18S/8Qf53zgKGYiLoQ7eDLzCkZm7at5ujyJp850ynkLcT4ps/eJIBxKN746wDqbo3sbwZAWtG45ijDAbuhCqMABqLOimgCvEcfpVBFMOO1qebuMeZgQe5AqNR30h9O4rxKTw4e7UES52uVCxtzSStDEfdyL1jlQ07rNnNb6/aVvIlO88dGZa2gSfhpW1m0yBua4FXs0jfQuapHC0CkM5fShjmUuHZ+3LXYF7KUV61IRYcc6OClerPWE7KKmX01YtZZ2iDjeo75LkrByM5EZLvEXGdr8c/CoxkYlvUcrgp7TmXfehsqs1zvQbs05x8SSRb/Iycu3kNPLSjOwuc/8N1oOrGuWGEjxAPy7TL/vzl0w6aLV/dDopu+GEU8b/gD7ajirJ0LCfcAZ0rxkNVB+BIxnDxh/WZE7YBIgrXIp6viJH9+6/g829+AjZ2vylZLsoDy0S9YFHgvTrV9yQ/BRi7q/DIQnbXR1iiXnLwcXVXiqwBIC7x80DAYMXsPjymnCp365KsZLKJSwXw/LDqzSYRK8VLyKZTu6DTWWjKIL062F+m2lmpMsbzy6lppGspUm0ZMHHm/m80h+vulmFAjvFq4= X-Microsoft-Antispam-Message-Info: 9LAG30AV7ekrJIGOAtvs4+i+9LDb13b6kmxAB0nRVgura9UEannBqrlqIoBcbRT0d9XoYnva7hWXbho3VW9R6HEgjV4NfYjcbNLBFOn5a6+N/nQiRtAoOb9B+HC3Kg9daSctzzhplbLieVDSfWHTDzmve4gN4svWn+mfd/eUpLAu9yng582ZnVEDjRpBr4rX X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 6:8pdJDdB0h2KkvExeciPN/ZR4lDE12ATtxdSywdD5pYufJDGrINnMBlTW9sZR9//O+yJdTD0YEtyoDU1U6DISJ8pcCRgieecc6S3MMgFBywAQAMvdEpEkyzaRlPi3P56y3OSoJXcmQ0k471CdFbldLeSvAPiYmKFDa3Zh3rN61DrTu80IjGmnBn7kBuWJRBR6ajp4kUFeWequwpUR1wWRgaPoSu3r3yfi0vaHUwU0OdDB4maq2VYDz2QWw/OEnYlPXaZ5jZdeJMYWTxTKhy1ftp15XeKvPZ+CmQ1YxJ+tQOitYYsCEHYlGiPgN2iHrcN6Hlcgzy1gt9ii4GJDWG0V9DWOGzb5QmWYEpSsnQfTH+THKsA39d+beXrwq76kqxCx07iOoRf0sBsl/JiVelgMH9/me6JJEtKTbL1CcR7+kgHyj69bWwSpW9UZ5Ti6rfM3c/Pk5NkbhpkhvEbx5SVIsA==; 5:SMmi+rkDwXU1P0dTeQPHEy3pWKTBxqLBdloJaknz1T2PJ2GGrDCAKxXWpuGqOIKu9tufYxctFef6do1QsyARLO01bvhLhREslkLjRoMQxhpjntBJa0W+ZNweArj5o7/cRU6RQSrB+E75smobG85JpXuPN9g55jXmL6hWCesPf3c=; 24:Lr6Gqd2y3CSYcLVWAHtoA0q0eOnfL6RTMmj1SNxL8+PZebekpJTAZ9/ZU2Nd03XHJdJXqCAnp8eoWlE8qYIB8CM/ZVTcQY/iKRZIXPUP2Ac= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 7:xPMt1sGUqB90W8Heh4PiZegRxAVNJ783XlFPSQHzx4+GGI1LjupadbIg7AxKnTcVqCBhny4xGu2BEIBTtTFqwvFBftFNsu+GIQBv008a62rhe4U6u7GMrDS0Bqvj8Kw+TRlw3lf/kUUQJhoLf2FgSpoe0KFSfIhGxw5B5m7U3UXuG5KPFvPD31pcgDNsuAk4gfhQRKaK/XPQkyfC+qcIVjOpi+lz2D9q2qYhM7ul6DWKyt0u1UAfSPwcUmtcv3+O X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Mar 2018 07:55:43.3235 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d9fc0925-44f0-4c89-0fd8-08d593b824bb X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4418 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: simon.horman@netronome.com, ovs-dev@openvswitch.org Subject: [ovs-dev] [PATCH v8 2/6] dpif-netdev: retrieve flow directly from the flow mark X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Yuanhan Liu So that we could skip some very costly CPU operations, including but not limiting to miniflow_extract, emc lookup, dpcls lookup, etc. Thus, performance could be greatly improved. A PHY-PHY forwarding with 1000 mega flows (udp,tp_src=1000-1999) and 1 million streams (tp_src=1000-1999, tp_dst=2000-2999) show more that 260% performance boost. Note that though the heavy miniflow_extract is skipped, we still have to do per packet checking, due to we have to check the tcp_flags. Co-authored-by: Finn Christensen Signed-off-by: Yuanhan Liu Signed-off-by: Finn Christensen Signed-off-by: Shahaf Shuler --- lib/dp-packet.h | 13 +++++ lib/dpif-netdev.c | 44 ++++++++++++-- lib/flow.c | 155 +++++++++++++++++++++++++++++++++++++++---------- lib/flow.h | 1 + 4 files changed, 175 insertions(+), 38 deletions(-) diff --git a/lib/dp-packet.h b/lib/dp-packet.h index 21c8ca5..dd3f17b 100644 --- a/lib/dp-packet.h +++ b/lib/dp-packet.h @@ -691,6 +691,19 @@ reset_dp_packet_checksum_ol_flags(struct dp_packet *p) #define reset_dp_packet_checksum_ol_flags(arg) #endif +static inline bool +dp_packet_has_flow_mark(struct dp_packet *p OVS_UNUSED, + uint32_t *mark OVS_UNUSED) +{ +#ifdef DPDK_NETDEV + if (p->mbuf.ol_flags & PKT_RX_FDIR_ID) { + *mark = p->mbuf.hash.fdir.hi; + return true; + } +#endif + return false; +} + enum { NETDEV_MAX_BURST = 32 }; /* Maximum number packets in a batch. */ struct dp_packet_batch { diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 2fdb6ef..7489a2f 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -2015,6 +2015,23 @@ flow_mark_flush(struct dp_netdev_pmd_thread *pmd) } } +static struct dp_netdev_flow * +mark_to_flow_find(const struct dp_netdev_pmd_thread *pmd, + const uint32_t mark) +{ + struct dp_netdev_flow *flow; + + CMAP_FOR_EACH_WITH_HASH (flow, mark_node, hash_int(mark, 0), + &flow_mark.mark_to_flow) { + if (flow->mark == mark && flow->pmd_id == pmd->core_id && + flow->dead == false) { + return flow; + } + } + + return NULL; +} + static void dp_netdev_pmd_remove_flow(struct dp_netdev_pmd_thread *pmd, struct dp_netdev_flow *flow) @@ -5204,10 +5221,10 @@ struct packet_batch_per_flow { static inline void packet_batch_per_flow_update(struct packet_batch_per_flow *batch, struct dp_packet *packet, - const struct miniflow *mf) + uint16_t tcp_flags) { batch->byte_count += dp_packet_size(packet); - batch->tcp_flags |= miniflow_get_tcp_flags(mf); + batch->tcp_flags |= tcp_flags; batch->array.packets[batch->array.count++] = packet; } @@ -5241,7 +5258,7 @@ packet_batch_per_flow_execute(struct packet_batch_per_flow *batch, static inline void dp_netdev_queue_batches(struct dp_packet *pkt, - struct dp_netdev_flow *flow, const struct miniflow *mf, + struct dp_netdev_flow *flow, uint16_t tcp_flags, struct packet_batch_per_flow *batches, size_t *n_batches) { @@ -5252,7 +5269,7 @@ dp_netdev_queue_batches(struct dp_packet *pkt, packet_batch_per_flow_init(batch, flow); } - packet_batch_per_flow_update(batch, pkt, mf); + packet_batch_per_flow_update(batch, pkt, tcp_flags); } /* Try to process all ('cnt') the 'packets' using only the exact match cache @@ -5283,6 +5300,7 @@ emc_processing(struct dp_netdev_pmd_thread *pmd, const size_t cnt = dp_packet_batch_size(packets_); uint32_t cur_min; int i; + uint16_t tcp_flags; atomic_read_relaxed(&pmd->dp->emc_insert_min, &cur_min); pmd_perf_update_counter(&pmd->perf_stats, @@ -5291,6 +5309,7 @@ emc_processing(struct dp_netdev_pmd_thread *pmd, DP_PACKET_BATCH_REFILL_FOR_EACH (i, cnt, packet, packets_) { struct dp_netdev_flow *flow; + uint32_t mark; if (OVS_UNLIKELY(dp_packet_size(packet) < ETH_HEADER_LEN)) { dp_packet_delete(packet); @@ -5298,6 +5317,16 @@ emc_processing(struct dp_netdev_pmd_thread *pmd, continue; } + if (dp_packet_has_flow_mark(packet, &mark)) { + flow = mark_to_flow_find(pmd, mark); + if (flow) { + tcp_flags = parse_tcp_flags(packet); + dp_netdev_queue_batches(packet, flow, tcp_flags, batches, + n_batches); + continue; + } + } + if (i != cnt - 1) { struct dp_packet **packets = packets_->packets; /* Prefetch next packet data and metadata. */ @@ -5323,7 +5352,8 @@ emc_processing(struct dp_netdev_pmd_thread *pmd, flow = NULL; } if (OVS_LIKELY(flow)) { - dp_netdev_queue_batches(packet, flow, &key->mf, batches, + tcp_flags = miniflow_get_tcp_flags(&key->mf); + dp_netdev_queue_batches(packet, flow, tcp_flags, batches, n_batches); } else { /* Exact match cache missed. Group missed packets together at @@ -5501,7 +5531,9 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd, flow = dp_netdev_flow_cast(rules[i]); emc_probabilistic_insert(pmd, &keys[i], flow); - dp_netdev_queue_batches(packet, flow, &keys[i].mf, batches, n_batches); + dp_netdev_queue_batches(packet, flow, + miniflow_get_tcp_flags(&keys[i].mf), + batches, n_batches); } pmd_perf_update_counter(&pmd->perf_stats, PMD_STAT_MASKED_HIT, diff --git a/lib/flow.c b/lib/flow.c index 38ff29c..6c74dd3 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -624,6 +624,70 @@ flow_extract(struct dp_packet *packet, struct flow *flow) miniflow_expand(&m.mf, flow); } +static inline bool +ipv4_sanity_check(const struct ip_header *nh, size_t size, + int *ip_lenp, uint16_t *tot_lenp) +{ + int ip_len; + uint16_t tot_len; + + if (OVS_UNLIKELY(size < IP_HEADER_LEN)) { + return false; + } + ip_len = IP_IHL(nh->ip_ihl_ver) * 4; + + if (OVS_UNLIKELY(ip_len < IP_HEADER_LEN || size < ip_len)) { + return false; + } + + tot_len = ntohs(nh->ip_tot_len); + if (OVS_UNLIKELY(tot_len > size || ip_len > tot_len || + size - tot_len > UINT8_MAX)) { + return false; + } + + *ip_lenp = ip_len; + *tot_lenp = tot_len; + + return true; +} + +static inline uint8_t +ipv4_get_nw_frag(const struct ip_header *nh) +{ + uint8_t nw_frag = 0; + + if (OVS_UNLIKELY(IP_IS_FRAGMENT(nh->ip_frag_off))) { + nw_frag = FLOW_NW_FRAG_ANY; + if (nh->ip_frag_off & htons(IP_FRAG_OFF_MASK)) { + nw_frag |= FLOW_NW_FRAG_LATER; + } + } + + return nw_frag; +} + +static inline bool +ipv6_sanity_check(const struct ovs_16aligned_ip6_hdr *nh, size_t size) +{ + uint16_t plen; + + if (OVS_UNLIKELY(size < sizeof *nh)) { + return false; + } + + plen = ntohs(nh->ip6_plen); + if (OVS_UNLIKELY(plen > size)) { + return false; + } + /* Jumbo Payload option not supported yet. */ + if (OVS_UNLIKELY(size - plen > UINT8_MAX)) { + return false; + } + + return true; +} + /* Caller is responsible for initializing 'dst' with enough storage for * FLOW_U64S * 8 bytes. */ void @@ -748,22 +812,7 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) int ip_len; uint16_t tot_len; - if (OVS_UNLIKELY(size < IP_HEADER_LEN)) { - goto out; - } - ip_len = IP_IHL(nh->ip_ihl_ver) * 4; - - if (OVS_UNLIKELY(ip_len < IP_HEADER_LEN)) { - goto out; - } - if (OVS_UNLIKELY(size < ip_len)) { - goto out; - } - tot_len = ntohs(nh->ip_tot_len); - if (OVS_UNLIKELY(tot_len > size || ip_len > tot_len)) { - goto out; - } - if (OVS_UNLIKELY(size - tot_len > UINT8_MAX)) { + if (OVS_UNLIKELY(!ipv4_sanity_check(nh, size, &ip_len, &tot_len))) { goto out; } dp_packet_set_l2_pad_size(packet, size - tot_len); @@ -786,31 +835,19 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) nw_tos = nh->ip_tos; nw_ttl = nh->ip_ttl; nw_proto = nh->ip_proto; - if (OVS_UNLIKELY(IP_IS_FRAGMENT(nh->ip_frag_off))) { - nw_frag = FLOW_NW_FRAG_ANY; - if (nh->ip_frag_off & htons(IP_FRAG_OFF_MASK)) { - nw_frag |= FLOW_NW_FRAG_LATER; - } - } + nw_frag = ipv4_get_nw_frag(nh); data_pull(&data, &size, ip_len); } else if (dl_type == htons(ETH_TYPE_IPV6)) { - const struct ovs_16aligned_ip6_hdr *nh; + const struct ovs_16aligned_ip6_hdr *nh = data; ovs_be32 tc_flow; uint16_t plen; - if (OVS_UNLIKELY(size < sizeof *nh)) { + if (OVS_UNLIKELY(!ipv6_sanity_check(nh, size))) { goto out; } - nh = data_pull(&data, &size, sizeof *nh); + data_pull(&data, &size, sizeof *nh); plen = ntohs(nh->ip6_plen); - if (OVS_UNLIKELY(plen > size)) { - goto out; - } - /* Jumbo Payload option not supported yet. */ - if (OVS_UNLIKELY(size - plen > UINT8_MAX)) { - goto out; - } dp_packet_set_l2_pad_size(packet, size - plen); size = plen; /* Never pull padding. */ @@ -982,6 +1019,60 @@ parse_dl_type(const struct eth_header *data_, size_t size) return parse_ethertype(&data, &size); } +uint16_t +parse_tcp_flags(struct dp_packet *packet) +{ + const void *data = dp_packet_data(packet); + size_t size = dp_packet_size(packet); + ovs_be16 dl_type; + uint8_t nw_frag = 0, nw_proto = 0; + + if (packet->packet_type != htonl(PT_ETH)) { + return 0; + } + + data_pull(&data, &size, ETH_ADDR_LEN * 2); + dl_type = parse_ethertype(&data, &size); + if (OVS_LIKELY(dl_type == htons(ETH_TYPE_IP))) { + const struct ip_header *nh = data; + int ip_len; + uint16_t tot_len; + + if (OVS_UNLIKELY(!ipv4_sanity_check(nh, size, &ip_len, &tot_len))) { + return 0; + } + nw_proto = nh->ip_proto; + nw_frag = ipv4_get_nw_frag(nh); + + size = tot_len; /* Never pull padding. */ + data_pull(&data, &size, ip_len); + } else if (dl_type == htons(ETH_TYPE_IPV6)) { + const struct ovs_16aligned_ip6_hdr *nh = data; + + if (OVS_UNLIKELY(!ipv6_sanity_check(nh, size))) { + return 0; + } + data_pull(&data, &size, sizeof *nh); + + size = ntohs(nh->ip6_plen); /* Never pull padding. */ + if (!parse_ipv6_ext_hdrs__(&data, &size, &nw_proto, &nw_frag)) { + return 0; + } + nw_proto = nh->ip6_nxt; + } else { + return 0; + } + + if (!(nw_frag & FLOW_NW_FRAG_LATER) && nw_proto == IPPROTO_TCP && + size >= TCP_HEADER_LEN) { + const struct tcp_header *tcp = data; + + return TCP_FLAGS_BE32(tcp->tcp_ctl); + } + + return 0; +} + /* For every bit of a field that is wildcarded in 'wildcards', sets the * corresponding bit in 'flow' to zero. */ void diff --git a/lib/flow.h b/lib/flow.h index 770a07a..0adecbf 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -132,6 +132,7 @@ bool parse_ipv6_ext_hdrs(const void **datap, size_t *sizep, uint8_t *nw_proto, uint8_t *nw_frag); ovs_be16 parse_dl_type(const struct eth_header *data_, size_t size); bool parse_nsh(const void **datap, size_t *sizep, struct ovs_key_nsh *key); +uint16_t parse_tcp_flags(struct dp_packet *packet); static inline uint64_t flow_get_xreg(const struct flow *flow, int idx) From patchwork Tue Mar 27 07:54:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shahaf Shuler X-Patchwork-Id: 891414 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=Mellanox.com header.i=@Mellanox.com header.b="HHNNScSp"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 409NfL2cj5z9ryG for ; Tue, 27 Mar 2018 18:57:46 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 4135F1678; Tue, 27 Mar 2018 07:55:54 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id C2E911661 for ; Tue, 27 Mar 2018 07:55:51 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-db5eur01on0088.outbound.protection.outlook.com [104.47.2.88]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id BAE7D51F for ; Tue, 27 Mar 2018 07:55:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=JglIRQ1LHCRXwPDDLR5mD3vbjulpfC5DimKqLfWqlew=; b=HHNNScSpvq9w3DTK0IOABQKiKKxlHAy6Rx3uslcdrtjR+B8IPq7GB2QAECCNYMSn2LiWvJ9OPdoTDWFkkauZL+kPFLhLFiWCaKpM6tRtrx1LUlHpYP2AhWTboizj+zXGWRkAKlAqXudVv6fc2Gk4/yYb03mqGkv287U1qyV7jVk= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=shahafs@mellanox.com; Received: from mellanox.com (141.226.120.58) by AM0PR05MB4418.eurprd05.prod.outlook.com (2603:10a6:208:5a::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.609.10; Tue, 27 Mar 2018 07:55:44 +0000 From: Shahaf Shuler To: fc@napatech.com, ian.stokes@intel.com Date: Tue, 27 Mar 2018 10:54:44 +0300 Message-Id: X-Mailer: git-send-email 2.12.0 In-Reply-To: References: <1517209188-16608-2-git-send-email-yliu@fridaylinux.org> MIME-Version: 1.0 X-Originating-IP: [141.226.120.58] X-ClientProxiedBy: DB6PR1001CA0041.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:4:55::27) To AM0PR05MB4418.eurprd05.prod.outlook.com (2603:10a6:208:5a::15) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 1f8d68f2-ae90-450e-a3e1-08d593b82591 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(4604075)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:AM0PR05MB4418; X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 3:iYOEZB4+jKLqdrmOqaPuC+7i8CR8lsoFsxAfuHI+rb+NwUniMjae4h0zPfblP3XYDWhIw9gvmlGkgOX7gcd7xB9t74x2wwivVlZoysu+tQ/SN+NMSH4XCHLz1jD7lU1lEzVDVNEGm3qfhqApZkKjSdoIU5rRD+oYFn32CwmL48LmY0GTL9cDANPmt2Y5dVuyBqPVQYttR+7gblxIbqBHTZFOxZvu1xNbw3OzTS2eLXObhMs52caTWbKmToGK3IOT; 25:xkHJT25G4a7fXaHVSIl6ur2kSaTxXZWIjTn5/8HNUkELTrRmSsv/K/989gsxBSXwuHdyuIq+5ZBBB0DENC/KdV3gfWqPMoR/K3CtoBpA/Or8xxL9mqBItXXlz9qe5hVM/p2sBdWBiwr070f7jwsDnO5mLzhkHFOdbGzRkUcnPqiI8/0REkw4WBm9RI3njHcRFzDHsyTuk1838zXVarOq5POIBMgzkIt82etplsgGdM24/I5kMpqsF8hv2DC+AmGdRBl0wVYYP/p8Giq4MV7Q7evyLWi9NwvXuXN+EohYIQbGm2iyIdGkTuFjdgJfZFs4sbK5dXwb1KrreiCEyzuT9w==; 31:eYAFqltFVA2HD2DWG2CClbzQw/gKRP1pP1F5cOOp/tRDaxMQfNaPOleI/Oxvg0FK5q6PaBRpYv7tc6jaM8fXHIkOfrwFsj2WngD/YElT3uM6NHBXpAYLemUrUBoeHrho9zLMwOUAziH/5/NxY6oOlRGPCYd5wwIamB1m37c9wyC0jgZ4tLjkZsX45nSXnB9GdH41gODf4xTkLF7xhm3bgoFsfE6kYnUcnrk+TtdBBAM= X-MS-TrafficTypeDiagnostic: AM0PR05MB4418: X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 20:YMSBwYkLn71mcKhAYgIA4W3XACwaeuwZOs0rahOMZIHJbhaVGsCOxFzq/j3xRoc9z7SwcbClRji8XSK/uUrtPIsvd9slHoIOm7py5dOEJrn8/Rl3YCJ3U9DCEkygXwwvP8nvovueQpe9DEkGO0Pp+xzz1PATMp6UD9256xv5kjLg622IhP764yTvHmjB242P89vrAvMhp31BxERgr2+MAgbE+RSyAwODHEdMYVaOJHdxzAs62viNPRMBLcTo5dq/HaRyAGfhhXWETCowjrQ3ou99KevuiH/75WT3d1hzVHPG750RIvY7uc1YFH9zuKE5s50wG0A3qmfa0+sPHGrssHPYEmt1a4+0Lxm3PxrnfewNfXpmz5nTzDB9qBfSB1obdZ7zwgfsmavIFGA9NoUFnUfykoGwTnZrIKaFZ3pMNKsOldzQVFhGZ9jU2dgcuChPeFR1IzrYWtRDT9ZGPjKX/Awb7cY+FlakzjQbksz639WZd3SncxXHNIvhvjbkxm75; 4:jYmBq95jWQAk5oWfjH7K+gI2dDdpsn9mTi0mC1B3gcx+19lbiV1heT8MbAkXl3zorotg9KsWuVo2VmN+9fS6n7xjitw1Z1JWcCuIeDOVHHnghcJ3GmKHpOPISQ84K8Pjng3p7eiFvUlhsV+bINxTeG+LkRiGwZvS5PoU7xgv0vbP38mSTdwX5tNGwI8tjxRZ2YPDdp4EcqGWde0xqRukB+mgKXExBbboAI6Lhvxmxv7dSe0vr8nOhk78Dc5JjyOhiUQAL0IB2l6AMyp1tetpsA== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3002001)(3231221)(944501327)(52105095)(6055026)(6041310)(20161123564045)(20161123558120)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM0PR05MB4418; BCL:0; PCL:0; RULEID:; SRVR:AM0PR05MB4418; X-Forefront-PRVS: 0624A2429E X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(366004)(39380400002)(376002)(396003)(199004)(189003)(50226002)(7736002)(68736007)(3846002)(36756003)(6116002)(7696005)(50466002)(51416003)(21086003)(52116002)(59450400001)(386003)(76176011)(118296001)(16586007)(97736004)(8936002)(486005)(956004)(486005)(478600001)(305945005)(39060400002)(8676002)(25786009)(4326008)(48376002)(186003)(86362001)(26005)(316002)(106356001)(69596002)(16526019)(81156014)(55016002)(2906002)(81166006)(66066001)(105586002)(5660300001)(11346002)(2616005)(53936002)(47776003)(476003)(446003); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR05MB4418; H:mellanox.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM0PR05MB4418; 23:WEkdxu0Jt9GFgb/PMqJTvpFaagGg+fa3yZVQWelKW?= 1t5BMRgaFtPc8eXY49gkD3KgW5aISmC4LLq+0hDqjtkRQZ1LYq2VDV5UtQm+uBM/LwN9WDPcorzPfgO8+GobWvPljcl2/CKcL8cXtfzmxXcckSSRlZfseSsSg/Ydt0eBzIFAGTAU9a2e46yTF+YWxo22htsrkRKmSc5A0RUXgOtm2YkePyapNtjaaj+4I4yfuGVg0AhhenbDKfvxX82mBlkMg4NYz1SGGhTHnOMNcQz+3O2+TbTa3SaHIatU6LQqf9OYV42Fi6hZ6xpCVK7ZyEfBoNEppSkOT+/9A/Q72A/32+pXKPxbDHxeH9/9IEHd5Bkv3ICc3nzXCtWRtZH7vx8SPppf3nJTwx7QEW5v81RrMz+3qa6sZWeUcKUg5DiGo+aGJoeWJ21kXPwWmcOx2RMDYHlXDRROol0Fp7pODso7wdYMjzdKqQTf8D02D1mOx3vKaCxYlPGupWeVK4AMMxxhBGP6si3ZzHfPDWLbLT0ZWxm0xidXpS+bvh2zrz99eGsUhohyXKI+pX+Vq1FU6v93QB494T0MubNLMfnX6E0ZiTkVh7KQRG5do3fmPLVB0UD6sCvJxNF6j79j6ssadbRWSVBWdWY2tVA0wm4UDGCIlshGfz+MhLfRg5lUeQD0vn3Uxyz111iONn0+FGU8BQTqN4JQfDa/w1/aer7MDgsyZpS9uib5hDDbqwf8LHxqetzS2Hec12RIjox7n6fJMpDSYfEOdN7owJ6fB/h5r+kBaTum+S2jnAkc6U1EWvdhUIe1GMWsk96A5tTXlkYxnO8F3QkRgZrRPyLfyoVDmM8moV52fCb8LDKwbLJ3QQ/CGhNH7x1WOoQRaxYqb6mDDo/EfTlwR8ErtcjJSZAajh9w7hlPRoUEjNEZBj9Hspc8TJT0f07DBarHsaLVw9brn/0mlXyZDckibEJec16lLyKQFKSsl47liEN1OFJUdM6bqKhMtHhSlqrZv2pxvg+BUbFsE9zlPwMLZIAaiFL7sJpqRP9zWsVGeqv8y50gc1YocBm8MOZxXI9N/caGs1X1CxSLqYen278xlpRLNBLD9NZD7UsHbCJubCcIaaJ4m+awxdswMiEPfqZhC6JWMSbsLmFQb2iXu6cu3USpeM/kcVj34pJqP1bAgh/3lOWHBSMrrA3/GFEoUTKHLIAjNQpts2pNFlatVi/+58UAXPe29vTyOH/EMvAa7soWAy61EOpbSQ= X-Microsoft-Antispam-Message-Info: Ymf5eaGm05j7wp6DdrS/nydT08bZI4Q5koq4IHerDOxDxJ5FHkf/iKJd7GB/Fpmw/SAGcECWNmdWVjAhy/wMNgzzhlEJMlSK54u6rMpnSakZneGJvczHUolGRhHQrxppSoVzYK2XwW1MkeEZXZQlUd0w2FVi/mBwLJiC30daHCdmplLJlFctTTKzWsLJJy6o X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 6:or6NhGjWqXDabcMR8x4KcmGs7PqLb7vVvdydKGBTDYdkS6TvZfOXawOUdWdTqHjNBhM+NcsGH34gT7z0BOQpBV71LCnZfV6FmRy+MVNQUiBL30ae2VVQTcxldcxdyXl9Bt4VuwQQ83rJCZ/1PrYwKS4fIlJkvTlt5DiX0QWwBIIhaJUUv/81wpVCIzJ6bxoBDkhHDhm0iLVF+Vpr+T8AN4udPiiNd+m7F7Rc59Y4REbD2RIUvL8PuTTm19SuxTEMdatY0sMUhRSFW+wsx+s9khg2nUN7zq7Kq3wZ+x6lszD4n1OD4gXHYNFxvpIQ/bm6e4jLvpSVjTgAqTZomuqzEyp5r5Q0dOtytllFv+CNXpRctftgw3kvoMFRb0T2pjpJWEp63FyyQRxLsNEAIF0Yh4C/vTTNDfBuiQtxAJQMNqGpBXPLq0B7GGtpu+R8WI2MbLLoTB9Pl//4OW1bf+K6hA==; 5:I43A6dXD31ZEhnOsJYGznZcFoD5Tv1OL+TDw/KBlx7NQjoJUd5EQpzxhXgquNSClX8L3yah3IlBH7X0g+yUQuSINnte0TC/uN7BTiHD+SHK8KcjxCVP3yD6oCCrmJ2iFUET8sjPa8kL+p6wnlQQvjV2vatWrFjqPgLD+nqnA8jM=; 24:xqbs0yRzDpRVDpkaaH5s8gvoZoc/WpKVhqX6S9jL34DNer1vfQ7yO4mX6TmMRGWJ+5gpUWPifelr47bmDJLlaYKbxaXix7Sxja8yzaJ5UpA= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 7:3ISPixD3kag8Ym8xZCaDqjuhrjgF1c/fPNS1g121XNOgOzQ1aHT1NFQ30N0yd3wSjA9aDBhYYao9T5DFI8DAMUEPRwudD1Uf28vYFYVMdcyyl8cVLwJezmEAC12JvynliRESf3lwWd4VHaWOeOE3C0E1s1tbH83BUAOklNNOWE0jYfJXkMn8XcokJc4LOOvf4xEXAgaANYu1cxct5yjJ1GRXd2c356t/3Ts2rB+BOJHWG1u6BGWAMblDk/F9aFsN X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Mar 2018 07:55:44.7297 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 1f8d68f2-ae90-450e-a3e1-08d593b82591 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4418 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: simon.horman@netronome.com, ovs-dev@openvswitch.org Subject: [ovs-dev] [PATCH v8 3/6] netdev-dpdk: implement flow offload with rte flow X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Finn Christensen The basic yet the major part of this patch is to translate the "match" to rte flow patterns. And then, we create a rte flow with MARK + RSS actions. Afterwards, all packets match the flow will have the mark id in the mbuf. The reason RSS is needed is, for most NICs, a MARK only action is not allowed. It has to be used together with some other actions, such as QUEUE, RSS, etc. However, QUEUE action can specify one queue only, which may break the rss. Likely, RSS action is currently the best we could now. Thus, RSS action is choosen. For any unsupported flows, such as MPLS, -1 is returned, meaning the flow offload is failed and then skipped. Co-authored-by: Yuanhan Liu Signed-off-by: Finn Christensen Signed-off-by: Yuanhan Liu Signed-off-by: Shahaf Shuler --- lib/netdev-dpdk.c | 563 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 562 insertions(+), 1 deletion(-) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index af9843a..df4d480 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -38,7 +38,9 @@ #include #include #include +#include +#include "cmap.h" #include "dirs.h" #include "dp-packet.h" #include "dpdk.h" @@ -51,6 +53,7 @@ #include "openvswitch/list.h" #include "openvswitch/ofp-print.h" #include "openvswitch/vlog.h" +#include "openvswitch/match.h" #include "ovs-numa.h" #include "ovs-thread.h" #include "ovs-rcu.h" @@ -60,6 +63,7 @@ #include "sset.h" #include "unaligned.h" #include "timeval.h" +#include "uuid.h" #include "unixctl.h" enum {VIRTIO_RXQ, VIRTIO_TXQ, VIRTIO_QNUM}; @@ -170,6 +174,17 @@ static const struct rte_eth_conf port_conf = { }; /* + * A mapping from ufid to dpdk rte_flow. + */ +static struct cmap ufid_to_rte_flow = CMAP_INITIALIZER; + +struct ufid_to_rte_flow_data { + struct cmap_node node; + ovs_u128 ufid; + struct rte_flow *rte_flow; +}; + +/* * These callbacks allow virtio-net devices to be added to vhost ports when * configuration has been fully completed. */ @@ -3709,6 +3724,552 @@ unlock: return err; } + +/* Find rte_flow with @ufid */ +static struct rte_flow * +ufid_to_rte_flow_find(const ovs_u128 *ufid) { + size_t hash = hash_bytes(ufid, sizeof(*ufid), 0); + struct ufid_to_rte_flow_data *data; + + CMAP_FOR_EACH_WITH_HASH (data, node, hash, &ufid_to_rte_flow) { + if (ovs_u128_equals(*ufid, data->ufid)) { + return data->rte_flow; + } + } + + return NULL; +} + +static inline void +ufid_to_rte_flow_associate(const ovs_u128 *ufid, + struct rte_flow *rte_flow) { + size_t hash = hash_bytes(ufid, sizeof(*ufid), 0); + struct ufid_to_rte_flow_data *data = xzalloc(sizeof(*data)); + + /* + * We should not simply overwrite an existing rte flow. + * We should have deleted it first before re-adding it. + * Thus, if following assert triggers, something is wrong: + * the rte_flow is not destroyed. + */ + ovs_assert(ufid_to_rte_flow_find(ufid) == NULL); + + data->ufid = *ufid; + data->rte_flow = rte_flow; + + cmap_insert(&ufid_to_rte_flow, + CONST_CAST(struct cmap_node *, &data->node), hash); +} + +static inline void +ufid_to_rte_flow_disassociate(const ovs_u128 *ufid) { + size_t hash = hash_bytes(ufid, sizeof(*ufid), 0); + struct ufid_to_rte_flow_data *data; + + CMAP_FOR_EACH_WITH_HASH (data, node, hash, &ufid_to_rte_flow) { + if (ovs_u128_equals(*ufid, data->ufid)) { + cmap_remove(&ufid_to_rte_flow, + CONST_CAST(struct cmap_node *, &data->node), hash); + free(data); + return; + } + } + + VLOG_WARN("ufid "UUID_FMT" is not associated with an rte flow\n", + UUID_ARGS((struct uuid *)ufid)); +} + +/* + * To avoid individual xrealloc calls for each new element, a 'curent_max' + * is used to keep track of current allocated number of elements. Starts + * by 8 and doubles on each xrealloc call + */ +struct flow_patterns { + struct rte_flow_item *items; + int cnt; + int current_max; +}; + +struct flow_actions { + struct rte_flow_action *actions; + int cnt; + int current_max; +}; + +static void +add_flow_pattern(struct flow_patterns *patterns, enum rte_flow_item_type type, + const void *spec, const void *mask) { + int cnt = patterns->cnt; + + if (cnt == 0) { + patterns->current_max = 8; + patterns->items = xcalloc(patterns->current_max, sizeof(struct rte_flow_item)); + } else if (cnt == patterns->current_max) { + patterns->current_max *= 2; + patterns->items = xrealloc(patterns->items, patterns->current_max * + sizeof(struct rte_flow_item)); + } + + patterns->items[cnt].type = type; + patterns->items[cnt].spec = spec; + patterns->items[cnt].mask = mask; + patterns->items[cnt].last = NULL; + patterns->cnt++; +} + +static void +add_flow_action(struct flow_actions *actions, enum rte_flow_action_type type, + const void *conf) +{ + int cnt = actions->cnt; + + if (cnt == 0) { + actions->current_max = 8; + actions->actions = xcalloc(actions->current_max, + sizeof(struct rte_flow_action)); + } else if (cnt == actions->current_max) { + actions->current_max *= 2; + actions->actions = xrealloc(actions->actions, actions->current_max * + sizeof(struct rte_flow_action)); + } + + actions->actions[cnt].type = type; + actions->actions[cnt].conf = conf; + actions->cnt++; +} + +static struct rte_flow_action_rss * +add_flow_rss_action(struct flow_actions *actions, + struct netdev *netdev) { + int i; + struct rte_flow_action_rss *rss; + + rss = xmalloc(sizeof(*rss) + sizeof(uint16_t) * netdev->n_rxq); + /* + * Setting it to NULL will let the driver use the default RSS + * configuration we have set: &port_conf.rx_adv_conf.rss_conf. + */ + rss->rss_conf = NULL; + rss->num = netdev->n_rxq; + + for (i = 0; i < rss->num; i++) { + rss->queue[i] = i; + } + + add_flow_action(actions, RTE_FLOW_ACTION_TYPE_RSS, rss); + + return rss; +} + +static int +netdev_dpdk_add_rte_flow_offload(struct netdev *netdev, + const struct match *match, + struct nlattr *nl_actions OVS_UNUSED, + size_t actions_len OVS_UNUSED, + const ovs_u128 *ufid, + struct offload_info *info) { + struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + const struct rte_flow_attr flow_attr = { + .group = 0, + .priority = 0, + .ingress = 1, + .egress = 0 + }; + struct flow_patterns patterns = { .items = NULL, .cnt = 0 }; + struct flow_actions actions = { .actions = NULL, .cnt = 0 }; + struct rte_flow *flow; + struct rte_flow_error error; + uint8_t *ipv4_next_proto_mask = NULL; + int ret = 0; + + /* Eth */ + struct rte_flow_item_eth eth_spec; + struct rte_flow_item_eth eth_mask; + memset(ð_spec, 0, sizeof(eth_spec)); + memset(ð_mask, 0, sizeof(eth_mask)); + if (!eth_addr_is_zero(match->wc.masks.dl_src) || + !eth_addr_is_zero(match->wc.masks.dl_dst)) { + rte_memcpy(ð_spec.dst, &match->flow.dl_dst, sizeof(eth_spec.dst)); + rte_memcpy(ð_spec.src, &match->flow.dl_src, sizeof(eth_spec.src)); + eth_spec.type = match->flow.dl_type; + + rte_memcpy(ð_mask.dst, &match->wc.masks.dl_dst, + sizeof(eth_mask.dst)); + rte_memcpy(ð_mask.src, &match->wc.masks.dl_src, + sizeof(eth_mask.src)); + eth_mask.type = match->wc.masks.dl_type; + + add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_ETH, + ð_spec, ð_mask); + } else { + /* + * If user specifies a flow (like UDP flow) without L2 patterns, + * OVS will at least set the dl_type. Normally, it's enough to + * create an eth pattern just with it. Unluckily, some Intel's + * NIC (such as XL710) doesn't support that. Below is a workaround, + * which simply matches any L2 pkts. + */ + add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_ETH, NULL, NULL); + } + + /* VLAN */ + struct rte_flow_item_vlan vlan_spec; + struct rte_flow_item_vlan vlan_mask; + memset(&vlan_spec, 0, sizeof(vlan_spec)); + memset(&vlan_mask, 0, sizeof(vlan_mask)); + if (match->wc.masks.vlans[0].tci && match->flow.vlans[0].tci) { + vlan_spec.tci = match->flow.vlans[0].tci; + vlan_mask.tci = match->wc.masks.vlans[0].tci; + + /* match any protocols */ + vlan_mask.tpid = 0; + + add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_VLAN, + &vlan_spec, &vlan_mask); + } + + /* IP v4 */ + uint8_t proto = 0; + struct rte_flow_item_ipv4 ipv4_spec; + struct rte_flow_item_ipv4 ipv4_mask; + memset(&ipv4_spec, 0, sizeof(ipv4_spec)); + memset(&ipv4_mask, 0, sizeof(ipv4_mask)); + if (match->flow.dl_type == ntohs(ETH_TYPE_IP) && + (match->wc.masks.nw_src || match->wc.masks.nw_dst || + match->wc.masks.nw_tos || match->wc.masks.nw_ttl || + match->wc.masks.nw_proto)) { + ipv4_spec.hdr.type_of_service = match->flow.nw_tos; + ipv4_spec.hdr.time_to_live = match->flow.nw_ttl; + ipv4_spec.hdr.next_proto_id = match->flow.nw_proto; + ipv4_spec.hdr.src_addr = match->flow.nw_src; + ipv4_spec.hdr.dst_addr = match->flow.nw_dst; + + ipv4_mask.hdr.type_of_service = match->wc.masks.nw_tos; + ipv4_mask.hdr.time_to_live = match->wc.masks.nw_ttl; + ipv4_mask.hdr.next_proto_id = match->wc.masks.nw_proto; + ipv4_mask.hdr.src_addr = match->wc.masks.nw_src; + ipv4_mask.hdr.dst_addr = match->wc.masks.nw_dst; + + add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_IPV4, + &ipv4_spec, &ipv4_mask); + + /* Save proto for L4 protocol setup */ + proto = ipv4_spec.hdr.next_proto_id & + ipv4_mask.hdr.next_proto_id; + + /* Remember proto mask address for later modification */ + ipv4_next_proto_mask = &ipv4_mask.hdr.next_proto_id; + } + + if (proto != IPPROTO_ICMP && proto != IPPROTO_UDP && + proto != IPPROTO_SCTP && proto != IPPROTO_TCP && + (match->wc.masks.tp_src || + match->wc.masks.tp_dst || + match->wc.masks.tcp_flags)) { + VLOG_DBG("L4 Protocol (%u) not supported", proto); + ret = -1; + goto out; + } + + if ((match->wc.masks.tp_src && match->wc.masks.tp_src != 0xffff) || + (match->wc.masks.tp_dst && match->wc.masks.tp_dst != 0xffff)) { + ret = -1; + goto out; + } + + struct rte_flow_item_tcp tcp_spec; + struct rte_flow_item_tcp tcp_mask; + memset(&tcp_spec, 0, sizeof(tcp_spec)); + memset(&tcp_mask, 0, sizeof(tcp_mask)); + if (proto == IPPROTO_TCP && + (match->wc.masks.tp_src || + match->wc.masks.tp_dst || + match->wc.masks.tcp_flags)) { + tcp_spec.hdr.src_port = match->flow.tp_src; + tcp_spec.hdr.dst_port = match->flow.tp_dst; + tcp_spec.hdr.data_off = ntohs(match->flow.tcp_flags) >> 8; + tcp_spec.hdr.tcp_flags = ntohs(match->flow.tcp_flags) & 0xff; + + tcp_mask.hdr.src_port = match->wc.masks.tp_src; + tcp_mask.hdr.dst_port = match->wc.masks.tp_dst; + tcp_mask.hdr.data_off = ntohs(match->wc.masks.tcp_flags) >> 8; + tcp_mask.hdr.tcp_flags = ntohs(match->wc.masks.tcp_flags) & 0xff; + + add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_TCP, + &tcp_spec, &tcp_mask); + + /* proto == TCP and ITEM_TYPE_TCP, thus no need for proto match */ + if (ipv4_next_proto_mask) { + *ipv4_next_proto_mask = 0; + } + goto end_proto_check; + } + + struct rte_flow_item_udp udp_spec; + struct rte_flow_item_udp udp_mask; + memset(&udp_spec, 0, sizeof(udp_spec)); + memset(&udp_mask, 0, sizeof(udp_mask)); + if (proto == IPPROTO_UDP && + (match->wc.masks.tp_src || match->wc.masks.tp_dst)) { + udp_spec.hdr.src_port = match->flow.tp_src; + udp_spec.hdr.dst_port = match->flow.tp_dst; + + udp_mask.hdr.src_port = match->wc.masks.tp_src; + udp_mask.hdr.dst_port = match->wc.masks.tp_dst; + + add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_UDP, + &udp_spec, &udp_mask); + + /* proto == UDP and ITEM_TYPE_UDP, thus no need for proto match */ + if (ipv4_next_proto_mask) { + *ipv4_next_proto_mask = 0; + } + goto end_proto_check; + } + + struct rte_flow_item_sctp sctp_spec; + struct rte_flow_item_sctp sctp_mask; + memset(&sctp_spec, 0, sizeof(sctp_spec)); + memset(&sctp_mask, 0, sizeof(sctp_mask)); + if (proto == IPPROTO_SCTP && + (match->wc.masks.tp_src || match->wc.masks.tp_dst)) { + sctp_spec.hdr.src_port = match->flow.tp_src; + sctp_spec.hdr.dst_port = match->flow.tp_dst; + + sctp_mask.hdr.src_port = match->wc.masks.tp_src; + sctp_mask.hdr.dst_port = match->wc.masks.tp_dst; + + add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_SCTP, + &sctp_spec, &sctp_mask); + + /* proto == SCTP and ITEM_TYPE_SCTP, thus no need for proto match */ + if (ipv4_next_proto_mask) { + *ipv4_next_proto_mask = 0; + } + goto end_proto_check; + } + + struct rte_flow_item_icmp icmp_spec; + struct rte_flow_item_icmp icmp_mask; + memset(&icmp_spec, 0, sizeof(icmp_spec)); + memset(&icmp_mask, 0, sizeof(icmp_mask)); + if (proto == IPPROTO_ICMP && + (match->wc.masks.tp_src || match->wc.masks.tp_dst)) { + icmp_spec.hdr.icmp_type = (uint8_t)ntohs(match->flow.tp_src); + icmp_spec.hdr.icmp_code = (uint8_t)ntohs(match->flow.tp_dst); + + icmp_mask.hdr.icmp_type = (uint8_t)ntohs(match->wc.masks.tp_src); + icmp_mask.hdr.icmp_code = (uint8_t)ntohs(match->wc.masks.tp_dst); + + add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_ICMP, + &icmp_spec, &icmp_mask); + + /* proto == ICMP and ITEM_TYPE_ICMP, thus no need for proto match */ + if (ipv4_next_proto_mask) { + *ipv4_next_proto_mask = 0; + } + goto end_proto_check; + } + +end_proto_check: + + add_flow_pattern(&patterns, RTE_FLOW_ITEM_TYPE_END, NULL, NULL); + + struct rte_flow_action_mark mark; + mark.id = info->flow_mark; + add_flow_action(&actions, RTE_FLOW_ACTION_TYPE_MARK, &mark); + + struct rte_flow_action_rss *rss; + rss = add_flow_rss_action(&actions, netdev); + add_flow_action(&actions, RTE_FLOW_ACTION_TYPE_END, NULL); + + flow = rte_flow_create(dev->port_id, &flow_attr, patterns.items, + actions.actions, &error); + free(rss); + if (!flow) { + VLOG_ERR("rte flow creat error: %u : message : %s\n", + error.type, error.message); + ret = -1; + goto out; + } + ufid_to_rte_flow_associate(ufid, flow); + VLOG_DBG("installed flow %p by ufid "UUID_FMT"\n", + flow, UUID_ARGS((struct uuid *)ufid)); + +out: + free(patterns.items); + free(actions.actions); + return ret; +} + +static bool +is_all_zero(const void *addr, size_t n) { + size_t i = 0; + const uint8_t *p = (uint8_t *)addr; + + for (i = 0; i < n; i++) { + if (p[i] != 0) { + return false; + } + } + + return true; +} + +/* + * Check if any unsupported flow patterns are specified. + */ +static int +netdev_dpdk_validate_flow(const struct match *match) { + struct match match_zero_wc; + + /* Create a wc-zeroed version of flow */ + match_init(&match_zero_wc, &match->flow, &match->wc); + + if (!is_all_zero(&match_zero_wc.flow.tunnel, + sizeof(match_zero_wc.flow.tunnel))) { + goto err; + } + + if (match->wc.masks.metadata || + match->wc.masks.skb_priority || + match->wc.masks.pkt_mark || + match->wc.masks.dp_hash) { + goto err; + } + + /* recirc id must be zero */ + if (match_zero_wc.flow.recirc_id) { + goto err; + } + + if (match->wc.masks.ct_state || + match->wc.masks.ct_nw_proto || + match->wc.masks.ct_zone || + match->wc.masks.ct_mark || + match->wc.masks.ct_label.u64.hi || + match->wc.masks.ct_label.u64.lo) { + goto err; + } + + if (match->wc.masks.conj_id || + match->wc.masks.actset_output) { + goto err; + } + + /* unsupported L2 */ + if (!is_all_zero(&match->wc.masks.mpls_lse, + sizeof(match_zero_wc.flow.mpls_lse))) { + goto err; + } + + /* unsupported L3 */ + if (match->wc.masks.ipv6_label || + match->wc.masks.ct_nw_src || + match->wc.masks.ct_nw_dst || + !is_all_zero(&match->wc.masks.ipv6_src, sizeof(struct in6_addr)) || + !is_all_zero(&match->wc.masks.ipv6_dst, sizeof(struct in6_addr)) || + !is_all_zero(&match->wc.masks.ct_ipv6_src, sizeof(struct in6_addr)) || + !is_all_zero(&match->wc.masks.ct_ipv6_dst, sizeof(struct in6_addr)) || + !is_all_zero(&match->wc.masks.nd_target, sizeof(struct in6_addr)) || + !is_all_zero(&match->wc.masks.nsh, sizeof(struct ovs_key_nsh)) || + !is_all_zero(&match->wc.masks.arp_sha, sizeof(struct eth_addr)) || + !is_all_zero(&match->wc.masks.arp_tha, sizeof(struct eth_addr))) { + goto err; + } + + /* If fragmented, then don't HW accelerate - for now */ + if (match_zero_wc.flow.nw_frag) { + goto err; + } + + /* unsupported L4 */ + if (match->wc.masks.igmp_group_ip4 || + match->wc.masks.ct_tp_src || + match->wc.masks.ct_tp_dst) { + goto err; + } + + return 0; + +err: + VLOG_ERR("cannot HW accelerate this flow due to unsupported protocols"); + return -1; +} + +static int +netdev_dpdk_destroy_rte_flow(struct netdev_dpdk *dev, + const ovs_u128 *ufid, + struct rte_flow *rte_flow) { + struct rte_flow_error error; + int ret; + + ret = rte_flow_destroy(dev->port_id, rte_flow, &error); + if (ret == 0) { + ufid_to_rte_flow_disassociate(ufid); + VLOG_DBG("removed rte flow %p associated with ufid " UUID_FMT "\n", + rte_flow, UUID_ARGS((struct uuid *)ufid)); + } else { + VLOG_ERR("rte flow destroy error: %u : message : %s\n", + error.type, error.message); + } + + return ret; +} + +static int +netdev_dpdk_flow_put(struct netdev *netdev, struct match *match, + struct nlattr *actions, size_t actions_len, + const ovs_u128 *ufid, struct offload_info *info, + struct dpif_flow_stats *stats OVS_UNUSED) { + struct rte_flow *rte_flow; + int ret; + + /* + * If an old rte_flow exists, it means it's a flow modification. + * Here destroy the old rte flow first before adding a new one. + */ + rte_flow = ufid_to_rte_flow_find(ufid); + if (rte_flow) { + ret = netdev_dpdk_destroy_rte_flow(netdev_dpdk_cast(netdev), + ufid, rte_flow); + if (ret < 0) { + return ret; + } + } + + ret = netdev_dpdk_validate_flow(match); + if (ret < 0) { + return ret; + } + + return netdev_dpdk_add_rte_flow_offload(netdev, match, actions, + actions_len, ufid, info); } + +static int +netdev_dpdk_flow_del(struct netdev *netdev, const ovs_u128 *ufid, + struct dpif_flow_stats *stats OVS_UNUSED) { + + struct rte_flow *rte_flow = ufid_to_rte_flow_find(ufid); + + if (!rte_flow) { + return -1; + } + + return netdev_dpdk_destroy_rte_flow(netdev_dpdk_cast(netdev), + ufid, rte_flow); } + +#define DPDK_FLOW_OFFLOAD_API \ + NULL, /* flow_flush */ \ + NULL, /* flow_dump_create */ \ + NULL, /* flow_dump_destroy */ \ + NULL, /* flow_dump_next */ \ + netdev_dpdk_flow_put, \ + NULL, /* flow_get */ \ + netdev_dpdk_flow_del, \ + NULL /* init_flow_api */ + + #define NETDEV_DPDK_CLASS(NAME, INIT, CONSTRUCT, DESTRUCT, \ SET_CONFIG, SET_TX_MULTIQ, SEND, \ GET_CARRIER, GET_STATS, \ @@ -3783,7 +4344,7 @@ unlock: RXQ_RECV, \ NULL, /* rx_wait */ \ NULL, /* rxq_drain */ \ - NO_OFFLOAD_API \ + DPDK_FLOW_OFFLOAD_API \ } static const struct netdev_class dpdk_class = From patchwork Tue Mar 27 07:54:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shahaf Shuler X-Patchwork-Id: 891415 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=Mellanox.com header.i=@Mellanox.com header.b="yLwtg35L"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 409Ng13YVVz9s1P for ; Tue, 27 Mar 2018 18:58:21 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 7D67C1688; Tue, 27 Mar 2018 07:55:56 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id D9263165E for ; Tue, 27 Mar 2018 07:55:52 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-db5eur01on0088.outbound.protection.outlook.com [104.47.2.88]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id EA82651F for ; Tue, 27 Mar 2018 07:55:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=ZiM2XudLGNqMog3uDwQi8tu/Qqr9STbWBP0r17JTRGM=; b=yLwtg35LKwSc4JOcU18mUVRJ7xGnDgpVMnp9fIPaQSogsWIupIsRtwfgJGYXR9y+5J611RnkGK0ygxaGFE7sPBqXl5yH2M9Nmf/AyLzJoNYss9F9RDaNZxWvHRnDr+tEO5xOsCmtSDClrxVweIfxcibylzsP0XV5pRpgwykmhfg= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=shahafs@mellanox.com; Received: from mellanox.com (141.226.120.58) by AM0PR05MB4418.eurprd05.prod.outlook.com (2603:10a6:208:5a::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.609.10; Tue, 27 Mar 2018 07:55:46 +0000 From: Shahaf Shuler To: fc@napatech.com, ian.stokes@intel.com Date: Tue, 27 Mar 2018 10:54:45 +0300 Message-Id: <46627727bd00966149d16235c6b5ec5a3f99f841.1522136948.git.shahafs@mellanox.com> X-Mailer: git-send-email 2.12.0 In-Reply-To: References: <1517209188-16608-2-git-send-email-yliu@fridaylinux.org> MIME-Version: 1.0 X-Originating-IP: [141.226.120.58] X-ClientProxiedBy: DB6PR1001CA0041.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:4:55::27) To AM0PR05MB4418.eurprd05.prod.outlook.com (2603:10a6:208:5a::15) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 5fd4b388-a123-4814-e9d4-08d593b82659 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(4604075)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:AM0PR05MB4418; X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 3:6rBjDBuDFCRTVrE1P0e3ELGAvjq/Tf5+LPI8gyiNSrQDFE7HXlbe8PeDw4QXGCqS7Z7NKJQRaF7pL1UysDubxfNJLxKo+BO/k0s7CQv8fqdm8g4iS9I+btNl2fMTlPsvislqiun02EAHvtCSIysHr0SXekSq32nc3jVVx+DUm92xnH3M1vW3eCk8Zol2KYjjLFevaiNYWY+Uq3MBIZR3PHyCkeMvzPC8ii6NZ84B8XBYaXTGgskZK3lG702T88FW; 25:ak3F4tg3chBEhskVW7zJVK9hAG6LI9jXmt302YTfmebgz8UFayng5CONcR8rDgiXS3MY7BO1sDneq/H6gU9LlGt4260RTiH4fSHpaXqvM/7eQp8mqdaW/LWQwARHhXxFeGDyWlfMkr5P0iC6QlIIVIAhPmt2se9g0O1T5kKDVLI7naUVWRwFv9hnJ+nUsY6FvcALQhF+gex+SyApFhdTq8iQKsilGMKjWXRdbZnwNNYFHC/i7UaxmYwfWfsdH59IZpzBLAvf3DL12AyOqKDkWJ3W/+LEfKv3vLZjbviecN/hJbAKcQdI74tLekCzDbPsic8B5o4wuVxXmwdsqbDM3Q==; 31:pS7yM7mlWss9PSMWTCG41HkquLX7nDiYHRBLXWSobsgmFlAedSoTPLWliJwJnmGKjKlxNUOuZPxifHXVSZax3kxChFt/otDrqkAKmCJ3Hjs5vmWutc69oOtPKZr+6VWTPeP29GPndLW0SoQcKKE0xZsqMURai6XCqw+9wkFSx8bcmDBspmdnm7X0PrCPZR46geoKaZ+bm0RO4R8JYxCfsGD0eYmWMMtWF3wsP44NZ1s= X-MS-TrafficTypeDiagnostic: AM0PR05MB4418: X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 20:VMJBhIJfVXNfYRYTRD76F+Iaej7/4HGs5fm5UWbnWEieZKjVm/Rk/QU2h0UPMtW+/1NdBck/cnFL++4zwE9o9dnz7whJnqGtB44Vq7yR5q8YNFqP1usiO8k6BIlqseqRlsCSrcbi22HBkdFQZqME6VKRCHnzZiTCeh5KxPF1X2w0O6HgJ1Dsw4yMaX+MadCKQX+Dj4Y06CqlR02TrYHqwRb4NmJFH0p79HzV7tcXU2NaJZIYRgFQcHzj/8M2ZSTrmO7PMbDsQUuGnV4LjK2nlsFtl59XtKpazB2gQYKAmeF6DuRIb1GW1NAuB1C+v1Zkc0efuAIq9jI60NDbahrZKkezgG8Y/13hvO6eiDBHTY2/zWXLEdX9nP1VeMhImYajuFt2lLx6UvPr3K2CglNsBvxW/V6TI8He05XwL/i7AbWtpvrkZGZ3LKXzVlA7btdQd4ZZPOrO7zxjh47J73FUw8zaHGCurSm+VVoshDsL/GE0WjAJHWDSDIIb9xWAWriG; 4:pbVsRVsV3+PBUAkf5dEtHdCkKRyAWhsxWhlQrxfeS3wyGMSqwZgFv+8jlWtfhquXQ3xXcFiQeYmSHvs37oajxIStchJfnUBHZqh/+zOsziF1FLPoGMHclJYlsnYfTlrEZ/MT2PaFgy+Y4Ogi4fAwGUoP2EKDUZ90we8JbA7K2cnRQRi3H7x6uCFdTLa6jrXfzO44r75e9gnvOXEfEFvwvcnoBWNecdKMgBx5S3c2ReSBWsoGQd2VY6xyK1OPTWyLNc66YGsz5ryy4s4z+lhArQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3002001)(3231221)(944501327)(52105095)(6055026)(6041310)(20161123564045)(20161123558120)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM0PR05MB4418; BCL:0; PCL:0; RULEID:; SRVR:AM0PR05MB4418; X-Forefront-PRVS: 0624A2429E X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(366004)(39380400002)(376002)(396003)(199004)(189003)(50226002)(7736002)(68736007)(3846002)(36756003)(6116002)(7696005)(50466002)(51416003)(21086003)(52116002)(386003)(76176011)(118296001)(16586007)(97736004)(8936002)(486005)(956004)(486005)(478600001)(305945005)(39060400002)(8676002)(25786009)(4326008)(48376002)(186003)(86362001)(26005)(316002)(106356001)(69596002)(16526019)(81156014)(55016002)(2906002)(81166006)(66066001)(105586002)(5660300001)(11346002)(2616005)(53936002)(47776003)(476003)(446003); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR05MB4418; H:mellanox.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM0PR05MB4418; 23:VMICMa+iLI+1nwOAgUL1L8EdGbm+Axi1K0kbRThwR?= 6Bgasvc/jUJTy56Gy/x4q5pg+dpVne+gQfHApaT0j5cI3i9dYwj/uWBDvi/LeGyHkaC/s4zR6/JolYYN160mqNl/7fiAS+zpTxmtfUtAeY2NA0v8ttkOjiJW+cSUarkqu8HlUxGCspS5Gd13ncYK7DgF56WgXjT0ojqMd3YL9NWrrdpQTj8nMEw1sj5mi9RxS3fjE4IaLvEdT8IfviFF2mjQem7mJJYhXrfkMrPsIjrFPJJjWWkOKLi8j+Efla4Bx9TnGgtOveP5qUD5HNJW8OGwdd9BCRilYPt6AG7pg9iqh3+xI3eQ3CFTZeTscCC/SBo+IQZRFENTMelPRASFK1a0EaZc1D1kX4rmqvyhSRrvg7eW5dGw2kXFINPMx+/tBmcUhIuO2v47VQ2sqyGl1yDriXzn1dBCQPU19CXgQ2HLdTuzAVw2CFWqLOsMZLm/TiDYDLhGcM6wLGKDkHUz8YYtq5neFSrWk0tX1sXxvHxR0K28XK0+K/JFBXagE6gkAvIe5SbSEt2zndFBZE0Syae7fpa+gHXJZrasAAnqlBepr02quJhlRy0VStVG94JULEm5hidixG0RaV61khJV5Y+qx1SKIRnyW7p1PWD7FQmtnI5yN9bYXFgRhSOCbKj8/0rRd47y6Y4tPc9kYwm56lks8xgvtRmSTAOcfAPU2Za4Hw1Fgn1KKbIqY5qq8IvcA/uPXMmgKVmF20mH9CkiPejeYfNRCsOTkZ5azRM3atBYzG1h3rf+Ufu3pioqlITsBO2cZS3klrro4uhCCyTuqGCtgqOHpeBXq0uloHAKIw5Wr0abLtkyK9sBcmogF6A9z2PtJ1R5Bt994Ec0SXcYzCNHOuRoFuEf/Ml1DZqRb58RHO/kFI7nvU6yJok3r3uJWtICOIz6wTbYtIiGCMzp1MfDaV01GWNGxiGMX3q+bRf+SMhW67ovCDtIkq5e3YcPELMhe4oh+Xpb9pVy/rVVeeQub4FNSShpvBOOBbAhplNx7f3qbajM9J9YwZYs5K4FYRaecKxGUjtyHu2tI8qILU003aXaZZe9ylTvJ6PSJe3ykk49Dy/HdezbVsm90fTnKVX+pg2A3FoBKxnHvw2pKl9RQtqPFwBQBa5YELVyF6nmyMqgXBKYR3VW3oCcwEOjbcNWgqe5EglNcE1/vXSgpTsigy1GAsvg3z54QOi5T+Pbg== X-Microsoft-Antispam-Message-Info: Stz27h1McoQ7z0WVzocC2zWtaTE7dC8b4O4pJCIPDVeIQEHS20B21ujXWAwAgPOKKrGKN7mtc/iWpCqT9b6dmMfDe6rcZeXpg4xyYa34AWJUz+SBbj+ope9G7Ojf3Um5GXfVu/GmFMfJ/yY9yNXRqF10/Y9fK4A8+eUhrdYSb5/jKe4tD7W4OcPTm7N+THlA X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 6:xcjy2z01jk6i0KIOvR4u6YH433aH/iPXzEx3J3jcCjlD/9pAdqVvcFnkmIQ+4/pPdvcVBO/wpjK+jdsq3c6dmWmSduL9BeejmFEYBsm9pqcaLiBAuKlKCFqW1TeoT8C/oes+hNSrXY3363rnOFjUzlm7Cl31DB9bkp5/QfohZ2Ob9VrHeef95ZUEHoqhq6L2KdceUfxmscIRt7IkMC80nbjzsTya27Iaxgo6eHKANAgbrmhTAwzky9EZrx+edNrxpv2E3B3YZs3UPjxPAUPywG28NaxCTtxJ0cCR+X1e3gDbEOEVqAShWePl1whDn680Z4SzSUtzxenU6tuVF2aWI9mf+yR/igTiJoqq0QguhVtx4jQwVcBpNuPCmep6AtxBnBE7H31zdnm2DdtcTw4kP7hXbkg356sri/PD5+Odu9UMdLn1H+10X9obCCLH6befVlhUzktuHy0btU7Umt5Czg==; 5:sUjVRn+xoGlIp1KfU1D81t+vtC5leR3yz/az1nwpscUPkK1UzLRCe7cdiOG8n3X0cmPYEuTM0cH2wNmY/7G/LDw18mr11Oyu0bMPQWfcPA+aaN6e91qvnfLxXyyQ0wV6RY03tEqEOe9TWCf5Nev1aGm6V5sCj0YruUye6yfSXFE=; 24:D60Nuq0ij9WFSZ8RWCVcSz4dJfgbvhGbjxrZcXtHX8xPZ66rahk36VdQ2izRcbqIMRS8F6vIedvssanqnPHR32seaHAsPNnvgr/DCVOCLX0= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 7:scoGCWOIs5qkG02+Djr/VBWxDRgdEWjiN7BjeXKA78gRQYd2FFBxgzHdafr9duXN5Hx2/fpo0VypETra6QzHXYbUBC1IYYuNWCN+hE6ZmLCwT5C+Gv9dhGJCnW8SC0lBsqPibAnVLWdS91HAIdZTfLxvKMm59yvQxLYvPzipdudZcDLhPj5l48hFXis+go4ozqB8K+wYbBg4Q8gMrRf9/98MWqAlu1+tRarS1vuDJms7RSYno/bau6yw8bEQqLzC X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Mar 2018 07:55:46.0422 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5fd4b388-a123-4814-e9d4-08d593b82659 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4418 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: simon.horman@netronome.com, ovs-dev@openvswitch.org Subject: [ovs-dev] [PATCH v8 4/6] netdev-dpdk: add debug for rte flow patterns X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Yuanhan Liu For debug purpose. Co-authored-by: Finn Christensen Signed-off-by: Yuanhan Liu Signed-off-by: Finn Christensen Signed-off-by: Shahaf Shuler --- lib/netdev-dpdk.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index df4d480..9785b1e 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -3797,6 +3797,182 @@ struct flow_actions { }; static void +dump_flow_pattern(struct rte_flow_item *item) +{ + if (item->type == RTE_FLOW_ITEM_TYPE_ETH) { + const struct rte_flow_item_eth *eth_spec = item->spec; + const struct rte_flow_item_eth *eth_mask = item->mask; + + VLOG_DBG("rte flow eth pattern:\n"); + if (eth_spec) { + VLOG_DBG(" Spec: src="ETH_ADDR_FMT", dst="ETH_ADDR_FMT", " + "type=0x%04" PRIx16"\n", + eth_spec->src.addr_bytes[0], eth_spec->src.addr_bytes[1], + eth_spec->src.addr_bytes[2], eth_spec->src.addr_bytes[3], + eth_spec->src.addr_bytes[4], eth_spec->src.addr_bytes[5], + eth_spec->dst.addr_bytes[0], eth_spec->dst.addr_bytes[1], + eth_spec->dst.addr_bytes[2], eth_spec->dst.addr_bytes[3], + eth_spec->dst.addr_bytes[4], eth_spec->dst.addr_bytes[5], + ntohs(eth_spec->type)); + } else { + VLOG_DBG(" Spec = null\n"); + } + if (eth_mask) { + VLOG_DBG(" Mask: src="ETH_ADDR_FMT", dst="ETH_ADDR_FMT", " + "type=0x%04"PRIx16"\n", + eth_mask->src.addr_bytes[0], eth_mask->src.addr_bytes[1], + eth_mask->src.addr_bytes[2], eth_mask->src.addr_bytes[3], + eth_mask->src.addr_bytes[4], eth_mask->src.addr_bytes[5], + eth_mask->dst.addr_bytes[0], eth_mask->dst.addr_bytes[1], + eth_mask->dst.addr_bytes[2], eth_mask->dst.addr_bytes[3], + eth_mask->dst.addr_bytes[4], eth_mask->dst.addr_bytes[5], + eth_mask->type); + } else { + VLOG_DBG(" Mask = null\n"); + } + } + + if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) { + const struct rte_flow_item_vlan *vlan_spec = item->spec; + const struct rte_flow_item_vlan *vlan_mask = item->mask; + + VLOG_DBG("rte flow vlan pattern:\n"); + if (vlan_spec) { + VLOG_DBG(" Spec: tpid=0x%"PRIx16", tci=0x%"PRIx16"\n", + ntohs(vlan_spec->tpid), ntohs(vlan_spec->tci)); + } else { + VLOG_DBG(" Spec = null\n"); + } + + if (vlan_mask) { + VLOG_DBG(" Mask: tpid=0x%"PRIx16", tci=0x%"PRIx16"\n", + vlan_mask->tpid, vlan_mask->tci); + } else { + VLOG_DBG(" Mask = null\n"); + } + } + + if (item->type == RTE_FLOW_ITEM_TYPE_IPV4) { + const struct rte_flow_item_ipv4 *ipv4_spec = item->spec; + const struct rte_flow_item_ipv4 *ipv4_mask = item->mask; + + VLOG_DBG("rte flow ipv4 pattern:\n"); + if (ipv4_spec) { + VLOG_DBG(" Spec: tos=0x%"PRIx8", ttl=%"PRIx8", proto=0x%"PRIx8 + ", src="IP_FMT", dst="IP_FMT"\n", + ipv4_spec->hdr.type_of_service, + ipv4_spec->hdr.time_to_live, + ipv4_spec->hdr.next_proto_id, + IP_ARGS(ipv4_spec->hdr.src_addr), + IP_ARGS(ipv4_spec->hdr.dst_addr)); + } else { + VLOG_DBG(" Spec = null\n"); + } + if (ipv4_mask) { + VLOG_DBG(" Mask: tos=0x%"PRIx8", ttl=%"PRIx8", proto=0x%"PRIx8 + ", src="IP_FMT", dst="IP_FMT"\n", + ipv4_mask->hdr.type_of_service, + ipv4_mask->hdr.time_to_live, + ipv4_mask->hdr.next_proto_id, + IP_ARGS(ipv4_mask->hdr.src_addr), + IP_ARGS(ipv4_mask->hdr.dst_addr)); + } else { + VLOG_DBG(" Mask = null\n"); + } + } + + if (item->type == RTE_FLOW_ITEM_TYPE_UDP) { + const struct rte_flow_item_udp *udp_spec = item->spec; + const struct rte_flow_item_udp *udp_mask = item->mask; + + VLOG_DBG("rte flow udp pattern:\n"); + if (udp_spec) { + VLOG_DBG(" Spec: src_port=%"PRIu16", dst_port=%"PRIu16"\n", + ntohs(udp_spec->hdr.src_port), + ntohs(udp_spec->hdr.dst_port)); + } else { + VLOG_DBG(" Spec = null\n"); + } + if (udp_mask) { + VLOG_DBG(" Mask: src_port=0x%"PRIx16", dst_port=0x%"PRIx16"\n", + udp_mask->hdr.src_port, + udp_mask->hdr.dst_port); + } else { + VLOG_DBG(" Mask = null\n"); + } + } + + if (item->type == RTE_FLOW_ITEM_TYPE_SCTP) { + const struct rte_flow_item_sctp *sctp_spec = item->spec; + const struct rte_flow_item_sctp *sctp_mask = item->mask; + + VLOG_DBG("rte flow sctp pattern:\n"); + if (sctp_spec) { + VLOG_DBG(" Spec: src_port=%"PRIu16", dst_port=%"PRIu16"\n", + ntohs(sctp_spec->hdr.src_port), + ntohs(sctp_spec->hdr.dst_port)); + } else { + VLOG_DBG(" Spec = null\n"); + } + if (sctp_mask) { + VLOG_DBG(" Mask: src_port=0x%"PRIx16", dst_port=0x%"PRIx16"\n", + sctp_mask->hdr.src_port, + sctp_mask->hdr.dst_port); + } else { + VLOG_DBG(" Mask = null\n"); + } + } + + if (item->type == RTE_FLOW_ITEM_TYPE_ICMP) { + const struct rte_flow_item_icmp *icmp_spec = item->spec; + const struct rte_flow_item_icmp *icmp_mask = item->mask; + + VLOG_DBG("rte flow icmp pattern:\n"); + if (icmp_spec) { + VLOG_DBG(" Spec: icmp_type=%"PRIu8", icmp_code=%"PRIu8"\n", + ntohs(icmp_spec->hdr.icmp_type), + ntohs(icmp_spec->hdr.icmp_code)); + } else { + VLOG_DBG(" Spec = null\n"); + } + if (icmp_mask) { + VLOG_DBG(" Mask: icmp_type=0x%"PRIx8", icmp_code=0x%"PRIx8"\n", + icmp_spec->hdr.icmp_type, + icmp_spec->hdr.icmp_code); + } else { + VLOG_DBG(" Mask = null\n"); + } + } + + if (item->type == RTE_FLOW_ITEM_TYPE_TCP) { + const struct rte_flow_item_tcp *tcp_spec = item->spec; + const struct rte_flow_item_tcp *tcp_mask = item->mask; + + VLOG_DBG("rte flow tcp pattern:\n"); + if (tcp_spec) { + VLOG_DBG(" Spec: src_port=%"PRIu16", dst_port=%"PRIu16 + ", data_off=0x%"PRIx8", tcp_flags=0x%"PRIx8"\n", + ntohs(tcp_spec->hdr.src_port), + ntohs(tcp_spec->hdr.dst_port), + tcp_spec->hdr.data_off, + tcp_spec->hdr.tcp_flags); + } else { + VLOG_DBG(" Spec = null\n"); + } + if (tcp_mask) { + VLOG_DBG(" Mask: src_port=%"PRIx16", dst_port=%"PRIx16 + ", data_off=0x%"PRIx8", tcp_flags=0x%"PRIx8"\n", + tcp_mask->hdr.src_port, + tcp_mask->hdr.dst_port, + tcp_mask->hdr.data_off, + tcp_mask->hdr.tcp_flags); + } else { + VLOG_DBG(" Mask = null\n"); + } + } +} + +static void add_flow_pattern(struct flow_patterns *patterns, enum rte_flow_item_type type, const void *spec, const void *mask) { int cnt = patterns->cnt; @@ -3814,6 +3990,7 @@ add_flow_pattern(struct flow_patterns *patterns, enum rte_flow_item_type type, patterns->items[cnt].spec = spec; patterns->items[cnt].mask = mask; patterns->items[cnt].last = NULL; + dump_flow_pattern(&patterns->items[cnt]); patterns->cnt++; } From patchwork Tue Mar 27 07:54:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shahaf Shuler X-Patchwork-Id: 891416 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=Mellanox.com header.i=@Mellanox.com header.b="EfzpjOn4"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 409NgW02G8z9ry1 for ; Tue, 27 Mar 2018 18:58:46 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 6C98B168D; Tue, 27 Mar 2018 07:55:57 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 407DA1675 for ; Tue, 27 Mar 2018 07:55:54 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-db5eur01on0088.outbound.protection.outlook.com [104.47.2.88]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 0C33651F for ; Tue, 27 Mar 2018 07:55:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=3Lc5gb4fggQHBCjiMT8pxC6uxBDyuNwOUztFsjguRrA=; b=EfzpjOn4abO+01llO+Tgf+iV/E1PzqaaAUWH0100q4aAjskFK7AoilQgYp7aVjQdtcmYT7gWLPUEDIVVfKyx696tObnz/Logh+K8PB88PZ01nD6YQl34G3DJpksUTqZTKllsIInAAvTjg0vA9Ckl0HsCENahzFu5U3EwouLZ7vg= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=shahafs@mellanox.com; Received: from mellanox.com (141.226.120.58) by AM0PR05MB4418.eurprd05.prod.outlook.com (2603:10a6:208:5a::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.609.10; Tue, 27 Mar 2018 07:55:47 +0000 From: Shahaf Shuler To: fc@napatech.com, ian.stokes@intel.com Date: Tue, 27 Mar 2018 10:54:46 +0300 Message-Id: <8ab46eb0b4bf178fccc7dae008c10beb290d291e.1522136948.git.shahafs@mellanox.com> X-Mailer: git-send-email 2.12.0 In-Reply-To: References: <1517209188-16608-2-git-send-email-yliu@fridaylinux.org> MIME-Version: 1.0 X-Originating-IP: [141.226.120.58] X-ClientProxiedBy: DB6PR1001CA0041.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:4:55::27) To AM0PR05MB4418.eurprd05.prod.outlook.com (2603:10a6:208:5a::15) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: c51d54b7-cca2-4b58-a652-08d593b82718 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(4604075)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:AM0PR05MB4418; X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 3:AqlX/h8OKeVYcu0jC/IDlUbTDQQymxLd5oOVmtmGan53GH+nNik82KVGxKD2PYW7+YHF6h+HFQOrofazvfL/XVjdE8wMcpFgGsbJy7rLA6NX8pJ7UoHP55jP7EmwhpqbcpSFuLNOEEk37fSFY+WPQNRSy1HWK4dgibeCr1mQ3+p9oNunJ7pgSkbnBNQifH27m0NXLbDdTNeLX/srPICOq6T+MaC5VB1q9KDCK0VQZBiZoU0lc0XmiTzVZXEEDyRN; 25:DZrelL7c0iQin83xkCYCnYww/HdJyYizf6g34Cob6eRoxYUA1eh0sX9sHoXZ42LAwQ7G76j/UDSxXGFGvzo1UVfq7Lhb0LpZITNjfpguIwGXNdtFfMS6B36wZnDi7uZuSOJ69Zd3RtqB6TOY5J2BJK/jvG9bq4TRysZKjNmYmZLBna62ZodU9nUdaXKHr0u6tIb5SoAPeIfLfKru8ksJ6LOvuViDvvBq/qD2O4WXj5u8N0+OqXn5GMc6PxCZjayPiQj9WWYRlknF12ApUyntOezj59q8wibF35Di1hKdmIX7M93v3tZxD2Nm9HGyQyK97Yf9VQANwLzgu2bi0y5MNw==; 31:ox9ssyTbWiP7DUZ4THmyShw6Pi6SQgaly3GxysOx4B/UWtMuYfokLlZ6ub7QmEzuHzHiaQ3KiBlLL1WUD4p3lnqbeasMrQyiisfXD83MlgDN4vILRisQ/nqpiwCX8KS8hSqZSoGrLOsac8aV/ePm5ajZQb2P3jirZ/n/BnxaMOb5kVp5LNwf2B226dM2Xadh6UjHP93VElLF6trQ2OJDeBACaunuDIGhYA4dn3pSUhQ= X-MS-TrafficTypeDiagnostic: AM0PR05MB4418: X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 20:cVNKMxPctRNA+JpZvf0VtdxjV970AvWaMW1wLNd6vJhE1GVsjDeFHvyiB0MHOBC8SXhlU/Haj26Hgo1vEqka0CAMVS4Tjf5DR/1r+Sm4Tgn+KoAcaWPTasOE6QfCF+Vh3umK3yhN2wQM4YQzie8EsWIIHIX2wubdDYVSsOdIUhCuF184/YvTxBMRo06obBM3NaOZF2CmaM9Dr57PbYGI8sj0/Uocnlzo6mbNwUxFLF25zG2p0iXYvnT73zMMoGL7rTn3VbgSZqI47+k1eV1lznrrIAJ9W+WralMOA6IqNPqpal2+KH1BHEpS86B2O3+r/VvuSo3h9BO0msDDs+992y7tPmKFyL4lqdehBqblI7SotBiMBhPbEcWpEyD0Tx4XeptJ6Wn0AwPtbKYmSi3vvUXGooPtmzlBctNkvmzJi6aiVsXH7lVYkwm6Z7V8Mbh++2yq2AaCQNbpwFL5qGRiuD1py/CuHQwJSuIzmQlR0m6eNHqM/YC1CT+TJzpynwIf; 4:mJoJ4kZ6TG0nsTCXiJqsyomthn903O8EsdNfQbEGJJ6H8xGJ1Q+H1vVItOfJF5pHZKqwuVgdmA37LLaJd+Jfx6sRuCLLiUagc+Yy+BzEzwQ+RFNVFw4NyJEgybbrn2Hr+lGVekvpp4RGBRIGrrjXvj6N2eV3iQNYYPYDlv9xU1DmLWLBNQACtv7BAx6796Jp9ikx1TxaCCZ+1MOEH+dBHfzUC3dcc+Y3N4MpUIGjYYb+pvXn4k28dp/YVmk2+0whgLsj+gzs1CTmOdAyqzEV9g== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3002001)(3231221)(944501327)(52105095)(6055026)(6041310)(20161123564045)(20161123558120)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM0PR05MB4418; BCL:0; PCL:0; RULEID:; SRVR:AM0PR05MB4418; X-Forefront-PRVS: 0624A2429E X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(366004)(39380400002)(376002)(396003)(199004)(189003)(50226002)(7736002)(68736007)(3846002)(36756003)(6116002)(7696005)(50466002)(51416003)(21086003)(52116002)(59450400001)(386003)(76176011)(118296001)(16586007)(97736004)(8936002)(486005)(956004)(486005)(478600001)(305945005)(39060400002)(8676002)(25786009)(4326008)(48376002)(186003)(86362001)(26005)(316002)(106356001)(69596002)(16526019)(81156014)(55016002)(2906002)(81166006)(66066001)(105586002)(5660300001)(11346002)(2616005)(53936002)(47776003)(476003)(446003); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR05MB4418; H:mellanox.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM0PR05MB4418; 23:ytzUB0DKMXI2eGPdyMA9JGR7Es29Jl70Y9sGpVOhu?= RxLJOP3nT9Us0uGAYzjv05lHVQVy5QbUn5eItjUZYEPediaOgDDIY/WAyM6G9XZ1W1VzXH96IYVCpMAvEYENnYtr1ud+o/XZPekaabDE4xwKg9tJ8bIdQmtNOkuc9wvFffVlmvCscPBjsEOx+AubUUO/W5R8WXfjaosVOIw0bl73KubD461QWuyWnZ3M8meKr5VC/U013EZV1gIPRQ0urhpPWb0QFsf9D4E7Y+y8Jof24Vr8EmQE83+OOWvYetFlIo/PBjQzzrUckpDDk6n1rSgKEBkkMf3gUk1nxPUEtIjdvXGH0V/oLbHnnr/ipCuAZUXOvsf/m1LIbb5XHVbi5BbZqOzzGFGMlgSeG38AOuEav5Go2ThPza+1NRbVZ8LHd3EqCsSv3aFfrzZUMSWVC+q3SHYyzxxfjPZBZpQcuNNjbLGSIFoIDbcR+aIm52gpi3OYx89/XtTyqD45PQBCHiIgxjKV7YrYxNEqxCPOD0gpiFeRYD6kV6MWy7f2ReK19Z2eTrskrXPM9gu2sN/119k9jc0ygvSWSN6gGs1yadi1VuKwhvEn2ClkCnK/vYSg2U8kDdHjrjd4xikEIjssUolu2tBOm8hGTEmf1hOO9c+Wbp2idvidCB54HXCN5lVk4dUduYExW++yPf72rQA1F7UVw2h/cLi5KluIOvMsI+fD4O+21GL1wDt7tUHVCUJRLiacVVUIPYi4SmFUnw9ebTPo/sOGsGWyz9N34Ye30d2ei+ucFSPKHZBGS+js7vXjBe5kSaXefZn1KSO8o5KpFEQJPsGGjBCJOWNGwL0+6sdFkzh5ifD+cKTW2/GvAARNy7iMjOTyukhEsgSLi1P3gQ4LCPzSXUmMrc8NAYkAA/fK9a0vV4blDfSztDDN5p9b8JcPlW3e3kiU1Gm8P6RpaASCRQPuFUoUvH89Uu2ZNgL/y0lwqw7EqFMk06q8AqbjwWQnCIg+kw4Bl/FD1bo7AskFFjU4zPSxzsMWpwOjQTdjDCqy/4grp5L9xfPhWhu4HPUCPbZcGNRYmhI++AfLZqd1bqa85Su/YgdAlzev5+xMQOX2JQfuZNulwir7wNcVa0Ln7recR+7x7gLg3V8UpzPpbioFgA4umz4Q5A06W8/jPR6YX4DbKm+8qXesLzDB7Y+AuqQc2h+DlTIcAaU473WBNIFZ3dOYUWMmVTyDKtSaGZLrrWsEphGrWYD2SRtRBE= X-Microsoft-Antispam-Message-Info: irmezEfpsfPYcofdS3436pBUwdxHStupUoYJoxvvpaeSNYVLDnBZMt/DscvLTGcwR4Z35kAmKRzWyW1gxN7p7W8w3KYqJT5gjJzCh3byUJNDZBJT6IpXoSzjXVEHNLS5YDAR4jktQT/PDxo+Cd4oK7gIQYE0rNka0WCwlAVZVeeuMl8vJ6QtbLJXKOunm7xH X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 6:tmOkXZzkGKQX2DkmoSvvBKW2pgEFIKPuTDghhp/OpI5X52eeeUx36PaxxjmbmwrIip/SrzWMixnfdejHJeRn2pv2RcswBR+z5hK9spNTHKCWIAZpMGa2ZHg5N4+pNOoWSkNOsqz/X4QikwVT9peUK96xOMT/iCN+r8b0uqaRwgUq9f14Ny5yidzahwo4gI/cvcRoGEt3/wBK8j+sYBgOVA7HxWuDPrYXFj2J31JDPI9NBvw+n1HQDtVhO0cX2lFHRnncXBknimmukW/M9eyzuJjdxkV2S/2YCjqkXdTWEbqyxNtXx+lZxQUA8FM3np8HiJi0HfeL9z5LmmBVFpmCIcrgAjY77rZAuDBPmLzZ6IyKjCaTB5U8DKMHRL9xwLy6tHuJPqyTBVxu2xoh+sLvUQGaJOKW0OYKDgPKC3G9trX+doDV5k6iPGZcTA/3ArRHDsg9/ni+DcLGRmOFaarXyQ==; 5:fE6EJARQMx32fKykn983Eg/2ICGQ+qdnMPqZcBIOAF9KNCyAIHvM87pIgZIqOlYzOPNnM4Fi+vtRzj37HgSFQyb7XOgE/dtU5buAY7rGap0uhbkz7i/TbsKxVMaNJ05AD7JgyWm+8P/2jRhO7Cfy5DYnSo8WA8RdqajltUyW/44=; 24:jq0xtn1KSVenr24+fU7amyyNWooFJNaVxTGt+9ZjAggvq0+2CJm2l8/Mc/nC4wkjN5iS4hoIMH96EgeqBKN0w9BViV5XyORrFT/Bx+1wCB8= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 7:Jrxv2TMXQzDl1vpaY9tt8FxjNjyePRf4LXJPFCpi8vnWSjba/T/oii5LAlFxchIdJ8G1adET1tJfx9qG+/K4coMHhjdws4gYKhA6gihd3B++VnblYUO3PPqnoBMkz+Xr3PbYzhFajB+4iwdP1E+TbRx/doJjyEFEE8F0IhSmZR1DNxahXiTJOIzjgG8GfOn4TLPdGy1F3b0zeefPILOfX5nkfYfygYhz5B4cvMfUQov6UePQT4D5JRD7gwxo3WR9 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Mar 2018 07:55:47.2923 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c51d54b7-cca2-4b58-a652-08d593b82718 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4418 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: simon.horman@netronome.com, ovs-dev@openvswitch.org Subject: [ovs-dev] [PATCH v8 5/6] dpif-netdev: do hw flow offload in a thread X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Yuanhan Liu Currently, the major trigger for hw flow offload is at upcall handling, which is actually in the datapath. Moreover, the hw offload installation and modification is not that lightweight. Meaning, if there are so many flows being added or modified frequently, it could stall the datapath, which could result to packet loss. To diminish that, all those flow operations will be recorded and appended to a list. A thread is then introduced to process this list (to do the real flow offloading put/del operations). This could leave the datapath as lightweight as possible. Signed-off-by: Yuanhan Liu Signed-off-by: Shahaf Shuler --- lib/dpif-netdev.c | 348 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 258 insertions(+), 90 deletions(-) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 7489a2f..8300286 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -345,6 +345,12 @@ enum rxq_cycles_counter_type { RXQ_N_CYCLES }; +enum { + DP_NETDEV_FLOW_OFFLOAD_OP_ADD, + DP_NETDEV_FLOW_OFFLOAD_OP_MOD, + DP_NETDEV_FLOW_OFFLOAD_OP_DEL, +}; + #define XPS_TIMEOUT 500000LL /* In microseconds. */ /* Contained by struct dp_netdev_port's 'rxqs' member. */ @@ -721,6 +727,8 @@ static inline bool emc_entry_alive(struct emc_entry *ce); static void emc_clear_entry(struct emc_entry *ce); static void dp_netdev_request_reconfigure(struct dp_netdev *dp); +static void queue_netdev_flow_del(struct dp_netdev_pmd_thread *pmd, + struct dp_netdev_flow *flow); static void emc_cache_init(struct emc_cache *flow_cache) @@ -1854,13 +1862,11 @@ struct flow_mark { struct cmap megaflow_to_mark; struct cmap mark_to_flow; struct id_pool *pool; - struct ovs_mutex mutex; }; static struct flow_mark flow_mark = { .megaflow_to_mark = CMAP_INITIALIZER, .mark_to_flow = CMAP_INITIALIZER, - .mutex = OVS_MUTEX_INITIALIZER, }; static uint32_t @@ -2010,7 +2016,7 @@ flow_mark_flush(struct dp_netdev_pmd_thread *pmd) CMAP_FOR_EACH (flow, mark_node, &flow_mark.mark_to_flow) { if (flow->pmd_id == pmd->core_id) { - mark_to_flow_disassociate(pmd, flow); + queue_netdev_flow_del(pmd, flow); } } } @@ -2032,6 +2038,251 @@ mark_to_flow_find(const struct dp_netdev_pmd_thread *pmd, return NULL; } +struct dp_flow_offload_item { + struct dp_netdev_pmd_thread *pmd; + struct dp_netdev_flow *flow; + int op; + struct match match; + struct nlattr *actions; + size_t actions_len; + + struct ovs_list node; +}; + +struct dp_flow_offload { + struct ovs_mutex mutex; + struct ovs_list list; + pthread_cond_t cond; +}; + +static struct dp_flow_offload dp_flow_offload = { + .mutex = OVS_MUTEX_INITIALIZER, + .list = OVS_LIST_INITIALIZER(&dp_flow_offload.list), +}; + +static struct ovsthread_once offload_thread_once + = OVSTHREAD_ONCE_INITIALIZER; + +static struct dp_flow_offload_item * +dp_netdev_alloc_flow_offload(struct dp_netdev_pmd_thread *pmd, + struct dp_netdev_flow *flow, + int op) +{ + struct dp_flow_offload_item *offload; + + offload = xzalloc(sizeof(*offload)); + offload->pmd = pmd; + offload->flow = flow; + offload->op = op; + + dp_netdev_flow_ref(flow); + dp_netdev_pmd_try_ref(pmd); + + return offload; +} + +static void +dp_netdev_free_flow_offload(struct dp_flow_offload_item *offload) +{ + dp_netdev_pmd_unref(offload->pmd); + dp_netdev_flow_unref(offload->flow); + + free(offload->actions); + free(offload); +} + +static void +dp_netdev_append_flow_offload(struct dp_flow_offload_item *offload) +{ + ovs_mutex_lock(&dp_flow_offload.mutex); + ovs_list_push_back(&dp_flow_offload.list, &offload->node); + xpthread_cond_signal(&dp_flow_offload.cond); + ovs_mutex_unlock(&dp_flow_offload.mutex); +} + +static int +dp_netdev_flow_offload_del(struct dp_flow_offload_item *offload) +{ + return mark_to_flow_disassociate(offload->pmd, offload->flow); +} + +/* + * There are two flow offload operations here: addition and modification. + * + * For flow addition, this function does: + * - allocate a new flow mark id + * - perform hardware flow offload + * - associate the flow mark with flow and mega flow + * + * For flow modification, both flow mark and the associations are still + * valid, thus only item 2 needed. + */ +static int +dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload) +{ + struct dp_netdev_port *port; + struct dp_netdev_pmd_thread *pmd = offload->pmd; + struct dp_netdev_flow *flow = offload->flow; + odp_port_t in_port = flow->flow.in_port.odp_port; + bool modification = offload->op == DP_NETDEV_FLOW_OFFLOAD_OP_MOD; + struct offload_info info; + uint32_t mark; + int ret; + + if (flow->dead) { + return -1; + } + + if (modification) { + mark = flow->mark; + ovs_assert(mark != INVALID_FLOW_MARK); + } else { + /* + * If a mega flow has already been offloaded (from other PMD + * instances), do not offload it again. + */ + mark = megaflow_to_mark_find(&flow->mega_ufid); + if (mark != INVALID_FLOW_MARK) { + VLOG_DBG("Flow has already been offloaded with mark %u\n", mark); + if (flow->mark != INVALID_FLOW_MARK) { + ovs_assert(flow->mark == mark); + } else { + mark_to_flow_associate(mark, flow); + } + return 0; + } + + mark = flow_mark_alloc(); + if (mark == INVALID_FLOW_MARK) { + VLOG_ERR("Failed to allocate flow mark!\n"); + } + } + info.flow_mark = mark; + + ovs_mutex_lock(&pmd->dp->port_mutex); + port = dp_netdev_lookup_port(pmd->dp, in_port); + if (!port) { + ovs_mutex_unlock(&pmd->dp->port_mutex); + return -1; + } + ret = netdev_flow_put(port->netdev, &offload->match, + CONST_CAST(struct nlattr *, offload->actions), + offload->actions_len, &flow->mega_ufid, &info, + NULL); + ovs_mutex_unlock(&pmd->dp->port_mutex); + + if (ret) { + if (!modification) { + flow_mark_free(mark); + } else { + mark_to_flow_disassociate(pmd, flow); + } + return -1; + } + + if (!modification) { + megaflow_to_mark_associate(&flow->mega_ufid, mark); + mark_to_flow_associate(mark, flow); + } + + return 0; +} + +static void * +dp_netdev_flow_offload_main(void *data OVS_UNUSED) +{ + struct dp_flow_offload_item *offload; + struct ovs_list *list; + const char *op; + int ret; + + for (;;) { + ovs_mutex_lock(&dp_flow_offload.mutex); + if (ovs_list_is_empty(&dp_flow_offload.list)) { + ovsrcu_quiesce_start(); + ovs_mutex_cond_wait(&dp_flow_offload.cond, + &dp_flow_offload.mutex); + } + list = ovs_list_pop_front(&dp_flow_offload.list); + offload = CONTAINER_OF(list, struct dp_flow_offload_item, node); + ovs_mutex_unlock(&dp_flow_offload.mutex); + + switch (offload->op) { + case DP_NETDEV_FLOW_OFFLOAD_OP_ADD: + op = "add"; + ret = dp_netdev_flow_offload_put(offload); + break; + case DP_NETDEV_FLOW_OFFLOAD_OP_MOD: + op = "modify"; + ret = dp_netdev_flow_offload_put(offload); + break; + case DP_NETDEV_FLOW_OFFLOAD_OP_DEL: + op = "delete"; + ret = dp_netdev_flow_offload_del(offload); + break; + default: + OVS_NOT_REACHED(); + } + + VLOG_DBG("%s to %s netdev flow\n", + ret == 0 ? "succeed" : "failed", op); + dp_netdev_free_flow_offload(offload); + } + + return NULL; +} + +static void +queue_netdev_flow_del(struct dp_netdev_pmd_thread *pmd, + struct dp_netdev_flow *flow) +{ + struct dp_flow_offload_item *offload; + + if (ovsthread_once_start(&offload_thread_once)) { + xpthread_cond_init(&dp_flow_offload.cond, NULL); + ovs_thread_create("dp_netdev_flow_offload", + dp_netdev_flow_offload_main, NULL); + ovsthread_once_done(&offload_thread_once); + } + + offload = dp_netdev_alloc_flow_offload(pmd, flow, + DP_NETDEV_FLOW_OFFLOAD_OP_DEL); + dp_netdev_append_flow_offload(offload); +} + +static void +queue_netdev_flow_put(struct dp_netdev_pmd_thread *pmd, + struct dp_netdev_flow *flow, struct match *match, + const struct nlattr *actions, size_t actions_len) +{ + struct dp_flow_offload_item *offload; + int op; + + if (!netdev_is_flow_api_enabled()) { + return; + } + + if (ovsthread_once_start(&offload_thread_once)) { + xpthread_cond_init(&dp_flow_offload.cond, NULL); + ovs_thread_create("dp_netdev_flow_offload", + dp_netdev_flow_offload_main, NULL); + ovsthread_once_done(&offload_thread_once); + } + + if (flow->mark != INVALID_FLOW_MARK) { + op = DP_NETDEV_FLOW_OFFLOAD_OP_MOD; + } else { + op = DP_NETDEV_FLOW_OFFLOAD_OP_ADD; + } + offload = dp_netdev_alloc_flow_offload(pmd, flow, op); + offload->match = *match; + offload->actions = xmalloc(actions_len); + memcpy(offload->actions, actions, actions_len); + offload->actions_len = actions_len; + + dp_netdev_append_flow_offload(offload); +} + static void dp_netdev_pmd_remove_flow(struct dp_netdev_pmd_thread *pmd, struct dp_netdev_flow *flow) @@ -2046,7 +2297,7 @@ dp_netdev_pmd_remove_flow(struct dp_netdev_pmd_thread *pmd, dpcls_remove(cls, &flow->cr); cmap_remove(&pmd->flow_table, node, dp_netdev_flow_hash(&flow->ufid)); if (flow->mark != INVALID_FLOW_MARK) { - mark_to_flow_disassociate(pmd, flow); + queue_netdev_flow_del(pmd, flow); } flow->dead = true; @@ -2627,88 +2878,6 @@ out: return error; } -/* - * There are two flow offload operations here: addition and modification. - * - * For flow addition, this function does: - * - allocate a new flow mark id - * - perform hardware flow offload - * - associate the flow mark with flow and mega flow - * - * For flow modification, both flow mark and the associations are still - * valid, thus only item 2 needed. - */ -static void -try_netdev_flow_put(struct dp_netdev_pmd_thread *pmd, odp_port_t in_port, - struct dp_netdev_flow *flow, struct match *match, - const struct nlattr *actions, size_t actions_len) -{ - struct offload_info info; - struct dp_netdev_port *port; - bool modification = flow->mark != INVALID_FLOW_MARK; - const char *op = modification ? "modify" : "add"; - uint32_t mark; - int ret; - - ovs_mutex_lock(&flow_mark.mutex); - - if (modification) { - mark = flow->mark; - } else { - if (!netdev_is_flow_api_enabled()) { - goto out; - } - - /* - * If a mega flow has already been offloaded (from other PMD - * instances), do not offload it again. - */ - mark = megaflow_to_mark_find(&flow->mega_ufid); - if (mark != INVALID_FLOW_MARK) { - VLOG_DBG("Flow has already been offloaded with mark %u\n", mark); - mark_to_flow_associate(mark, flow); - goto out; - } - - mark = flow_mark_alloc(); - if (mark == INVALID_FLOW_MARK) { - VLOG_ERR("Failed to allocate flow mark!\n"); - goto out; - } - } - info.flow_mark = mark; - - ovs_mutex_lock(&pmd->dp->port_mutex); - port = dp_netdev_lookup_port(pmd->dp, in_port); - if (!port) { - ovs_mutex_unlock(&pmd->dp->port_mutex); - goto out; - } - ret = netdev_flow_put(port->netdev, match, - CONST_CAST(struct nlattr *, actions), - actions_len, &flow->mega_ufid, &info, NULL); - ovs_mutex_unlock(&pmd->dp->port_mutex); - - if (ret) { - VLOG_ERR("Failed to %s netdev flow with mark %u\n", op, mark); - if (!modification) { - flow_mark_free(mark); - } else { - mark_to_flow_disassociate(pmd, flow); - } - goto out; - } - - if (!modification) { - megaflow_to_mark_associate(&flow->mega_ufid, mark); - mark_to_flow_associate(mark, flow); - } - VLOG_DBG("Succeed to %s netdev flow with mark %u\n", op, mark); - -out: - ovs_mutex_unlock(&flow_mark.mutex); -} - static void dp_netdev_get_mega_ufid(const struct match *match, ovs_u128 *mega_ufid) { @@ -2774,7 +2943,7 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd, cmap_insert(&pmd->flow_table, CONST_CAST(struct cmap_node *, &flow->node), dp_netdev_flow_hash(&flow->ufid)); - try_netdev_flow_put(pmd, in_port, flow, match, actions, actions_len); + queue_netdev_flow_put(pmd, flow, match, actions, actions_len); if (OVS_UNLIKELY(!VLOG_DROP_DBG((&upcall_rl)))) { struct ds ds = DS_EMPTY_INITIALIZER; @@ -2856,7 +3025,6 @@ flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd, if (put->flags & DPIF_FP_MODIFY) { struct dp_netdev_actions *new_actions; struct dp_netdev_actions *old_actions; - odp_port_t in_port = netdev_flow->flow.in_port.odp_port; new_actions = dp_netdev_actions_create(put->actions, put->actions_len); @@ -2864,8 +3032,8 @@ flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd, old_actions = dp_netdev_flow_get_actions(netdev_flow); ovsrcu_set(&netdev_flow->actions, new_actions); - try_netdev_flow_put(pmd, in_port, netdev_flow, match, - put->actions, put->actions_len); + queue_netdev_flow_put(pmd, netdev_flow, match, + put->actions, put->actions_len); if (stats) { get_dpif_flow_stats(netdev_flow, stats); From patchwork Tue Mar 27 07:54:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shahaf Shuler X-Patchwork-Id: 891417 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=mellanox.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=Mellanox.com header.i=@Mellanox.com header.b="fSiOBkFQ"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 409Nh13fH5z9ry1 for ; Tue, 27 Mar 2018 18:59:13 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 813621684; Tue, 27 Mar 2018 07:55:58 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 1ECA7167F for ; Tue, 27 Mar 2018 07:55:55 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-db5eur01on0088.outbound.protection.outlook.com [104.47.2.88]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 6949D51F for ; Tue, 27 Mar 2018 07:55:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=oGzCDgaMjHoQvgrgfN1Oervj4ACWi4OJiMD9lmE+G0g=; b=fSiOBkFQXCq56u166+CzsXmJ0YBQ/LZX24g8dL36xsSoGURAxErcUqRxP9FuM+bPiR9DnIs06GPm22hrMAxSA/QiaxZ3VXYIfWDRXXgs/X0QkVf1gaUJYbQdxITywd/iSvgsTkcGhjVkl+0eiSZ8czdgWNNvRNxbg32WvMX+ppk= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=shahafs@mellanox.com; Received: from mellanox.com (141.226.120.58) by AM0PR05MB4418.eurprd05.prod.outlook.com (2603:10a6:208:5a::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.609.10; Tue, 27 Mar 2018 07:55:48 +0000 From: Shahaf Shuler To: fc@napatech.com, ian.stokes@intel.com Date: Tue, 27 Mar 2018 10:54:47 +0300 Message-Id: X-Mailer: git-send-email 2.12.0 In-Reply-To: References: <1517209188-16608-2-git-send-email-yliu@fridaylinux.org> MIME-Version: 1.0 X-Originating-IP: [141.226.120.58] X-ClientProxiedBy: DB6PR1001CA0041.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:4:55::27) To AM0PR05MB4418.eurprd05.prod.outlook.com (2603:10a6:208:5a::15) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: be3a0c96-2cea-4956-89e3-08d593b827de X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(4604075)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:AM0PR05MB4418; X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 3:HU6QtTudNLEo+bY/tBO7etlhvtaezFoKAs22a2cM2Yl5D058XAEJAocl6mU/PrwnFXJ+t+ulPPJDbgx0f1wvAJPQe0xpR0FeNXO6JxmG/OPPcWltypTXaDrQXVsuHrkQ3x23I05MqSmPRyiX76RIMXPTU8PeKj5O5291un2Tv0UbsFk+2dd0AF9Bq0IZPZt7xbMaBS6kAOfyE7hT3v5knRxaFOCnDm8k6lYT/7hfFY97q4VHVVdJY0gPou+Mge9Q; 25:vKxYYBGfuueTrCh5daeltbd4V4jPx/Sd2C5qYK5bkJp+bQC4E3hzNwAkSVpzQWiyDGhfE/LCOWn1OQxCv6npksNX8+XCRp+V8jyjxpCyHwNj4IMU38kmqFO8FjUYid5GQdJzoMLTgXub4KM1GcMtKJB2gV6ZXcsChCxOIUYiuZYEaj1JjEKwOHRkURY67zgz9W/mh9FlLVhK/3yYDVL77lCyedNiNy55jC9cuSYZ9tIAqgTjhWNi7kplUmI9Q9yNcSMfPampb6PWX0gUkcqPoT+jwl6CunEnjYKoGUm1Q9g68MgDZhNd2oaoSwPltd5UFH8qsfWw/TktJLC5VgTkIQ==; 31:8aMahfWeFamKriAQrHafZ3bhSvwTZ26in263NwAoNpCl8GrxZdjGuPrzpBz8GnBMTa+KvWpaxEzStA2PzLac+TRTHDok39R0UvqoPyYnanOfYT6fbRy2nYZzO1LwAD6Y48wZfIZpHcrACHDKv+KrQbCU13YqizxuAwieZscIyZYBeXDAUyO0GSfTen+PkS3zqw30oBK4PvjnOumWW+m9ngyCgZl0duyDt764awZRLsA= X-MS-TrafficTypeDiagnostic: AM0PR05MB4418: X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 20:ZS/K/AZ7nfbzD5r9HE55psKyLmFRtca6ghG0cVsVF8s1dJIi2Tn5Ctd1B3ByrzVH8PeH+FOMc8PlSbgODqAd4iu1nV+aRZ4uqc9+6I4MzKZzmmH/G4DnfZKXbYnThzVNTyRL2cf//U84WI5KDidEjNrrGKUTB7XkEluUCaR3WrVigpSXY9nfDRmkk8OFBuA24rqoFRWEoqBtSC+20+dNjLJCx7hdKxO8ZUYRCy8O8VK9pJUnz4BZzB6kc2gXQPq5LdHgTRn8gmRYi4DvGaCJHSj3sSaxNTKAli/M8BObw6I5JqgVtjb66EEkqRXRdMzD6VSRUy0C74EtoMdq1Zyai6JPr28QPqPXgj4oAD+EznOGKa9TQE5O/JYYUDWkfmqPQ40f1ztK/dFm0cG+dWa8Yg31ydLlLiWbM7N4+1f+CQXrpPnR4h52Mygyu4RyROHRzfPkMjhjJ1043Qua6KIvx3rZAjW7bFfbQaRx2RDblFgvXsUzEy9dM7YVUtHaC3KY; 4:LukO9D1LW1NF6p4wJG70EgjBI1h6fYYEpfXkEtITBPBTirIq0vvxtw45snmltUq5NGRAPKCcxh8KeOziHgGvrEYkQ/IgrW66NRreVCSQioAirvd/hXo+sDxS+kj4OOQqqZn3Kq1X9HxJNFFkrU4rdOjRUGvafz7ZxdqFKcdsA0/+IrLs1oAUCiBDO3Xm/oqUZjcwR+MVzKSer/yy2Rz8oVfbzK0x8tBvOcHFO37n223/b4056gD3bia48ACvsS06hktr00Iw+eqaMP5ckMHENg== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3002001)(3231221)(944501327)(52105095)(6055026)(6041310)(20161123564045)(20161123558120)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:AM0PR05MB4418; BCL:0; PCL:0; RULEID:; SRVR:AM0PR05MB4418; X-Forefront-PRVS: 0624A2429E X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(346002)(39860400002)(366004)(39380400002)(376002)(396003)(199004)(189003)(50226002)(7736002)(68736007)(3846002)(36756003)(6116002)(7696005)(50466002)(51416003)(21086003)(52116002)(59450400001)(386003)(76176011)(118296001)(16586007)(97736004)(8936002)(486005)(956004)(486005)(478600001)(305945005)(39060400002)(8676002)(25786009)(4326008)(48376002)(186003)(86362001)(575784001)(26005)(316002)(106356001)(69596002)(16526019)(81156014)(55016002)(2906002)(81166006)(66066001)(105586002)(5660300001)(11346002)(2616005)(53936002)(47776003)(476003)(446003); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR05MB4418; H:mellanox.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM0PR05MB4418; 23:vXr4qBanfD7bCpDjBd5hMfS13ZPrBXm9XIBx+KvJi?= NdpKv5nJPq+AcPo57jsH2UrsOVQwryga1nvgS7n7rsMVwMyU59YonFRXYThiCNJf0FhvTac+3DetzXU7xxp06tiJJciyDVwM/MxWuF4aZCF7hDg5dCEH6Cg39cHE3blpcGT9zayJwdM9AkkFJwLIEtCpqKivZgt1TBPbWXuzjYQj55/1TZXlW1BUBpKk6dOPv5OYDR1LoOzr/qXeMcFg+VdwZPO7pIwRBnwr439WP3wEAiM34ljQogU8sf2cV/WBRFP4+sA0PWUUtyFT3PnlFItIv8unn8yozDzoldeT7mCRdmxwe7SbZQ2ZW6794yQJfBgMvad3oXzGpkCFAvTa99Ro9unYdC4Td3cNbdniZTUQq5Ue6PouBT+dl6jY8lHH+RR3TUeAz8LtdNKX+kKxMaBcxJVOlnCc9IbXsLnjKUwGpAIvkv/OqZ6Ii0ukGZFWkllBA8H3OWfCZEyY5KjDHaPBpRxTy4cjGYfPt6H5o6aD3geuRyRozrV1QIsslP3s8MpMwti61euLTBp8KeI5GLfsT3iMV7gjq9a+qUF+DaeOG+Qm0qQrnluD2FJzklI/oj0AVcep/V5q1MH6/r6B55tNTa1gwax5ltE+7Eu54qzoKujfIostWP/nr1I4fKPsYG7CunaGvLrjHg1WHJp1/6vAMHihuxLIBVs2wzQsA9YXanAJUPv77G7f1+0wydZHnwBK1G9s5e/e76BcnJq15FrRw6tdsLEzZKpKNTlGGNI2oxQSdWiM5BwHyQmQEKJkcBbzpagqUEkUhHx48gR3k5b6/TZbeWFRsI+wp3Uo6aowvCKj7ZdBeerfYSWo9i8EPnP7/OCbvqQMaMSToLNHB6P5KPXxTOGMzXxaxUETXYY77PR6grGM/5CLKjmSdxZsRVoMX1uh8wAn1MNnrRDStlK2s/Xq5kIz19faEAqRkMaBaGdg5w1xMyaDdx9wFB3aisoX6GQDHDWrhMNabtGWFdjMy5y4lW2+iwbam+tS7GcwDI1GM2poTsu9v8p1cMRunMU2/+jDZgHOKgrednLLpCV5Jn5c7QcffCVrWPJ1Vm1PzWMR6jUmU168vYNTJKyndzaN77YTLCJd5buZmhPQOAzrwh8BEDwqv4sZNr8T6p8D7owYgWNbtmA/wl8jXPhNqo9f9mxuPkjN5Ya8aqS/AG3TSOG0JMeF3vQaWKZKltlW37qIwTJsb2KE8c6rVITSMOT9EPBmvHYB3GinGTa9V7q7hFJWOvh1egS32tnVO3sQA== X-Microsoft-Antispam-Message-Info: QKdFRaHP1g/fqWh7aBglgW5NKN0V+L9eDfs7l7ttPeqM2n/qxFJ+W297aWz4ZaIuMIGRWpStx5fBSh7XuqVbkU3nqrmUd46xeDKn0IFm9b283qlyKSo6QOkSdGGVGXrR+mf4GfcEf0sn23pbBYmUaPqCz9r8/gLIly8T+wXlzeaVbICrGxkejHqspzlR3p0n X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 6:KKKo8vgwrus6Vw5aXuAZvdv+yrIEQPN16bG+AVCZUiszz5XPa4HAzYmuLfCKz5miCZfsKYTFjqX4iElOQirxrLIa3SRn1QoLIN9R2WLBAWu06XEH4BHdMTt5cEKeChksHyWCyg3du6Q1Bj/4ZAaXnBy0AyIxChN6D3oYDy5YlBgSt3YvrNqDgTkCQNnpAcYDTQYYa+GEqugwod+w9F+zY4D/fD00LYgr8sfPfPYlZl09/GuADCWbfH+Hy1duzWuusPPHGUTBvL+Lu2R5KDBx1bAzBNDKaENEhTB+GeVD3KM+//stAqLyK5Mq0UmJRgRi5pOdAybDOBY3xy1T1igLLy7h+EEkS0gmf1LbiMUhvHmBMs3D2sbeD8IkT8gCsRmKmx75w2ZPLaLJsWQe4U12acHf2kt7LvBPMYQeY7jGDSCePqmwzzaC+RjRDf54HrqAgbkkGgL6wN0XnY9VxRG/dA==; 5:bNK8gkeCDkRzMYSPoW+/dMeXsgpfrXLa50ZmH5HhJrJWA+aqoD0MSsWf9C8O1pRVMJa6SK/iyumddlfk0fmj5gMqlTBMg9ZY/AofsVfB75nt/YukwHsx0xAYQm7sgQEeaG2iztfHrG3idwxBOdUqgD7/SnObf2Pa/DQ7m3RyRmI=; 24:5WtcO2Y/FelsQDiApqB5Tawlanj5v50yNZkXxAEgeKLj3i5HiieoMX3FzB9AUQgsGhMcDUvi4N+UYVSPq2UMxSDniGczlq+PNYg4ahauj7Y= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM0PR05MB4418; 7:0Ifoq9qP+/+eVswHQWmS1IfsDFvipbYCupDJ1SAtqHswANRJD5Iya+c/ewO4XeTMKDvesrlWHh5dPobdSXagfY3vQ1wPdp8uakxczq2Q/ZoAMA5YUjo0gSnFgFsslRBJE1eBxJfGegNFt+BEG23s874X2ReGezTM/nNACzpE6kDIzf5oozKgefGXXHwFnQEVcNGimrRsvrf5U+NFvtgxuqR3JdBuEN+L1qX2fL87P0OFf1A1k/2uCBXUVYnL8a+o X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Mar 2018 07:55:48.5891 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: be3a0c96-2cea-4956-89e3-08d593b827de X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR05MB4418 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: simon.horman@netronome.com, ovs-dev@openvswitch.org Subject: [ovs-dev] [PATCH v8 6/6] Documentation: document ovs-dpdk flow offload X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Yuanhan Liu Add details in the DPDK howto guide on the way to enable the offload along with the supported NICs and flow types. The flow offload is marked as experimental. Signed-off-by: Yuanhan Liu Signed-off-by: Shahaf Shuler --- Documentation/howto/dpdk.rst | 22 ++++++++++++++++++++++ NEWS | 3 ++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Documentation/howto/dpdk.rst b/Documentation/howto/dpdk.rst index 79b626c..c5794bc 100644 --- a/Documentation/howto/dpdk.rst +++ b/Documentation/howto/dpdk.rst @@ -739,3 +739,25 @@ devices to bridge ``br0``. Once complete, follow the below steps: Check traffic on multiple queues:: $ cat /proc/interrupts | grep virtio + +.. _dpdk-flow-hardware-offload: + +Flow Hardware Offload (Experimental) +------------------------------------ + +The flow hardware offload is disabled by default and can be enabled by:: + + $ ovs-vsctl set Open_vSwitch . other_config:hw-offload=true + +So far only partial flow offload is implemented. Moreover, it only works +with PMD drivers have the rte_flow action "MARK + RSS" support. + +The validated NICs are: + +- Mellanox (ConnectX-4, ConnectX-4 Lx, ConnectX-5) +- Napatech (NT200B01) + +Supported protocols for hardware offload are: +- L2: Ethernet, VLAN +- L3: IPv4, IPv6 +- L4: TCP, UDP, SCTP, ICMP diff --git a/NEWS b/NEWS index 8d0b502..f682b25 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,8 @@ Post-v2.9.0 * OFPT_ROLE_STATUS is now available in OpenFlow 1.3. - Linux kernel 4.14 * Add support for compiling OVS with the latest Linux 4.14 kernel + - DPDK: + * Add experimental flow hardware offload support v2.9.0 - 19 Feb 2018 -------------------- @@ -70,7 +72,6 @@ v2.9.0 - 19 Feb 2018 * New appctl command 'dpif-netdev/pmd-rxq-rebalance' to rebalance rxq to pmd assignments. * Add rxq utilization of pmd to appctl 'dpif-netdev/pmd-rxq-show'. - * Add support for vHost dequeue zero copy (experimental) - Userspace datapath: * Output packet batching support. - vswitchd: