Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/79577/?format=api
http://patches.dpdk.org/api/patches/79577/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/patch/20201003220619.19231-10-andreyv@nvidia.com/", "project": { "id": 1, "url": "http://patches.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<20201003220619.19231-10-andreyv@nvidia.com>", "list_archive_url": "https://inbox.dpdk.org/dev/20201003220619.19231-10-andreyv@nvidia.com", "date": "2020-10-03T22:06:18", "name": "[v3,09/10] examples/flow_filtering: utilize shared RSS action", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "165fc916c4eafa908349302d31760aba9524f3dc", "submitter": { "id": 1969, "url": "http://patches.dpdk.org/api/people/1969/?format=api", "name": "Andrey Vesnovaty", "email": "andreyv@nvidia.com" }, "delegate": { "id": 319, "url": "http://patches.dpdk.org/api/users/319/?format=api", "username": "fyigit", "first_name": "Ferruh", "last_name": "Yigit", "email": "ferruh.yigit@amd.com" }, "mbox": "http://patches.dpdk.org/project/dpdk/patch/20201003220619.19231-10-andreyv@nvidia.com/mbox/", "series": [ { "id": 12678, "url": "http://patches.dpdk.org/api/series/12678/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=12678", "date": "2020-10-03T22:06:09", "name": "RTE flow shared action", "version": 3, "mbox": "http://patches.dpdk.org/series/12678/mbox/" } ], "comments": "http://patches.dpdk.org/api/patches/79577/comments/", "check": "warning", "checks": "http://patches.dpdk.org/api/patches/79577/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@inbox.dpdk.org", "Delivered-To": "patchwork@inbox.dpdk.org", "Received": [ "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 1DCB1A04B5;\n\tSun, 4 Oct 2020 00:09:53 +0200 (CEST)", "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 231301C128;\n\tSun, 4 Oct 2020 00:07:55 +0200 (CEST)", "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id 609A51BF38\n for <dev@dpdk.org>; Sun, 4 Oct 2020 00:07:53 +0200 (CEST)", "from Internal Mail-Server by MTLPINE1 (envelope-from\n andreyv@nvidia.com) with SMTP; 4 Oct 2020 01:07:47 +0300", "from nvidia.com (r-arch-host11.mtr.labs.mlnx [10.213.43.60])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 093M6YLm018436;\n Sun, 4 Oct 2020 01:07:47 +0300" ], "From": "Andrey Vesnovaty <andreyv@nvidia.com>", "To": "dev@dpdk.org", "Cc": "jer@marvell.com, jerinjacobk@gmail.com, thomas@monjalon.net,\n ferruh.yigit@intel.com, stephen@networkplumber.org,\n bruce.richardson@intel.com, orika@nvidia.com, viacheslavo@nvidia.com,\n andrey.vesnovaty@gmail.com, mdr@ashroe.eu, nhorman@tuxdriver.com,\n ajit.khaparde@broadcom.com, samik.gupta@broadcom.com,\n Andrey Vesnovaty <andreyv@mellanox.com>,\n Marko Kovacevic <marko.kovacevic@intel.com>,\n Ori Kam <orika@mellanox.com>, Radu Nicolau <radu.nicolau@intel.com>,\n Akhil Goyal <akhil.goyal@nxp.com>,\n Tomasz Kantecki <tomasz.kantecki@intel.com>,\n Sunil Kumar Kori <skori@marvell.com>,\n Pavan Nikhilesh <pbhagavatula@marvell.com>,\n John McNamara <john.mcnamara@intel.com>", "Date": "Sun, 4 Oct 2020 01:06:18 +0300", "Message-Id": "<20201003220619.19231-10-andreyv@nvidia.com>", "X-Mailer": "git-send-email 2.26.2", "In-Reply-To": "<20201003220619.19231-1-andreyv@nvidia.com>", "References": "\n <MWHPR1201MB252566195BE51EA0B0C768C8DB370@MWHPR1201MB2525.namprd12.prod.outlook.com>\n <20201003220619.19231-1-andreyv@nvidia.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[dpdk-dev] [PATCH v3 09/10] examples/flow_filtering: utilize shared\n\tRSS action", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://mails.dpdk.org/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "content": "From: Andrey Vesnovaty <andreyv@mellanox.com>\n\nThis commit give very first shared RSS action usage example.\nQueue action used by the flow replaced by shared RSS action\nhaving single queue. On each RX burst queue switched 0 <-> 1\nutilizing rte_flow_shared_action_update() API. User supposed\nto observe consistent queue switches on each packet burst.\n\nSigned-off-by: Andrey Vesnovaty <andreyv@mellanox.com>\nSigned-off-by: Andrey Vesnovaty <andreyv@nvidia.com>\n---\n doc/guides/sample_app_ug/flow_filtering.rst | 62 +++++++++++++---\n examples/flow_filtering/flow_blocks.c | 81 +++++++++++++++++----\n examples/flow_filtering/main.c | 13 +++-\n 3 files changed, 128 insertions(+), 28 deletions(-)", "diff": "diff --git a/doc/guides/sample_app_ug/flow_filtering.rst b/doc/guides/sample_app_ug/flow_filtering.rst\nindex 5e5a6cd8a0..cfe9334717 100644\n--- a/doc/guides/sample_app_ug/flow_filtering.rst\n+++ b/doc/guides/sample_app_ug/flow_filtering.rst\n@@ -106,7 +106,7 @@ following code:\n .. code-block:: c\n \n /* create flow for send packet with */\n- flow = generate_ipv4_flow(port_id, selected_queue,\n+ flow = generate_ipv4_flow(port_id, shared_action,\n SRC_IP, EMPTY_MASK,\n DEST_IP, FULL_MASK, &error);\n if (!flow) {\n@@ -242,7 +242,7 @@ The Ethernet port is configured with default settings using the\n rxq_conf = dev_info.default_rxconf;\n rxq_conf.offloads = port_conf.rxmode.offloads;\n \n-For this example we are configuring number of rx and tx queues that are connected\n+For this example we are configuring 2 rx and 2 tx queues that are connected\n to a single port.\n \n .. code-block:: c\n@@ -270,13 +270,22 @@ to a single port.\n }\n }\n \n+Before we create the flow we create shared action in order to send it as\n+actions argument when creating a flow. The action is single queue RSS action\n+similar to action queue with the only difference that shared RSS action\n+provides update capability after action creation.\n+\n+.. code-block:: c\n+\n+ shared_action = rte_flow_shared_action_create(port_id, &action, &error);\n+\n In the next step we create and apply the flow rule. which is to send packets\n with destination ip equals to 192.168.1.1 to queue number 1. The detail\n explanation of the ``generate_ipv4_flow()`` appears later in this document:\n \n .. code-block:: c\n \n- flow = generate_ipv4_flow(port_id, selected_queue,\n+ flow = generate_ipv4_flow(port_id, shared_action,\n SRC_IP, EMPTY_MASK,\n DEST_IP, FULL_MASK, &error);\n \n@@ -339,6 +348,21 @@ looks like the following:\n printf(\"\\n\");\n rte_pktmbuf_free(m);\n }\n+ if (rss_queue[0] == 0) {\n+ printf(\">>> switching queue 0 -> 1\\n\");\n+ rss_queue[0] = 1;\n+ } else {\n+ printf(\">>> switching queue 1 -> 0\\n\");\n+ rss_queue[0] = 0;\n+ }\n+ ret = rte_flow_shared_action_update\n+ (port_id, shared_action, &action,\n+ &error);\n+ if (ret)\n+ rte_exit(EXIT_FAILURE,\n+ \":: error: RSS action update \"\n+ \"failed: %s\\n\",\n+ rte_strerror(-ret));\n }\n }\n }\n@@ -348,6 +372,8 @@ looks like the following:\n rte_eth_dev_close(port_id);\n }\n \n+On each loop eteration Rx queue switched using\n+``rte_flow_shared_action_update()`` API.\n The main work of the application is reading the packets from all\n queues and printing for each packet the destination queue:\n \n@@ -365,6 +391,21 @@ queues and printing for each packet the destination queue:\n printf(\" - queue=0x%x\", (unsigned int)i);\n printf(\"\\n\");\n rte_pktmbuf_free(m);\n+ if (rss_queue[0] == 0) {\n+ printf(\">>> switching queue 0 -> 1\\n\");\n+ rss_queue[0] = 1;\n+ } else {\n+ printf(\">>> switching queue 1 -> 0\\n\");\n+ rss_queue[0] = 0;\n+ }\n+ ret = rte_flow_shared_action_update\n+ (port_id, shared_action, &action,\n+ &error);\n+ if (ret)\n+ rte_exit(EXIT_FAILURE,\n+ \":: error: RSS action update \"\n+ \"failed: %s\\n\",\n+ rte_strerror(-ret));\n }\n }\n }\n@@ -378,13 +419,15 @@ The forwarding loop can be interrupted and the application closed using\n The generate_ipv4_flow function\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n \n+\n The generate_ipv4_flow function is responsible for creating the flow rule.\n This function is located in the ``flow_blocks.c`` file.\n \n .. code-block:: c\n \n static struct rte_flow *\n- generate_ipv4_flow(uint8_t port_id, uint16_t rx_q,\n+ generate_ipv4_flow(uint8_t port_id,\n+ cstructrte_flow_shared_action *shared_action,\n uint32_t src_ip, uint32_t src_mask,\n uint32_t dest_ip, uint32_t dest_mask,\n struct rte_flow_error *error)\n@@ -393,7 +436,6 @@ This function is located in the ``flow_blocks.c`` file.\n struct rte_flow_item pattern[MAX_PATTERN_NUM];\n struct rte_flow_action action[MAX_ACTION_NUM];\n struct rte_flow *flow = NULL;\n- struct rte_flow_action_queue queue = { .index = rx_q };\n struct rte_flow_item_ipv4 ip_spec;\n struct rte_flow_item_ipv4 ip_mask;\n \n@@ -411,8 +453,8 @@ This function is located in the ``flow_blocks.c`` file.\n * create the action sequence.\n * one action only, move packet to queue\n */\n- action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;\n- action[0].conf = &queue;\n+ action[0].type = RTE_FLOW_ACTION_TYPE_SHARED;\n+ action[0].conf = shared_action;\n action[1].type = RTE_FLOW_ACTION_TYPE_END;\n \n /*\n@@ -468,12 +510,12 @@ The following part create the flow attributes, in our case ingress.\n attr.ingress = 1;\n \n The third part defines the action to be taken when a packet matches\n-the rule. In this case send the packet to queue.\n+the rule. In this case send the packet to single RSS queue.\n \n .. code-block:: c\n \n- action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;\n- action[0].conf = &queue;\n+ action[0].type = RTE_FLOW_ACTION_TYPE_SHARED;\n+ action[0].conf = shared_action;\n action[1].type = RTE_FLOW_ACTION_TYPE_END;\n \n The fourth part is responsible for creating the pattern and is built from\ndiff --git a/examples/flow_filtering/flow_blocks.c b/examples/flow_filtering/flow_blocks.c\nindex 575d792810..ed17ae073e 100644\n--- a/examples/flow_filtering/flow_blocks.c\n+++ b/examples/flow_filtering/flow_blocks.c\n@@ -5,12 +5,30 @@\n #define MAX_PATTERN_NUM\t\t3\n #define MAX_ACTION_NUM\t\t2\n \n-struct rte_flow *\n-generate_ipv4_flow(uint16_t port_id, uint16_t rx_q,\n-\t\tuint32_t src_ip, uint32_t src_mask,\n-\t\tuint32_t dest_ip, uint32_t dest_mask,\n-\t\tstruct rte_flow_error *error);\n+struct rte_flow_shared_action *shared_action;\n+uint16_t rss_queue[1] = {0};\n+\n+struct rte_flow_action_rss rss_action = {\n+\t\t.func = RTE_ETH_HASH_FUNCTION_DEFAULT,\n+\t\t.level = 0,\n+\t\t.types = 0,\n+\t\t.key_len = 0,\n+\t\t.key = NULL,\n+\t\t.queue = rss_queue,\n+\t\t.queue_num = 1,\n+};\n \n+struct rte_flow_action flow_action = {\n+\t.type = RTE_FLOW_ACTION_TYPE_RSS,\n+\t.conf = &rss_action,\n+};\n+\n+struct rte_flow *\n+generate_ipv4_flow(uint16_t port_id,\n+\t\t uint32_t src_ip, uint32_t src_mask,\n+\t\t uint32_t dest_ip, uint32_t dest_mask,\n+\t\t struct rte_flow_error *error);\n+int update_rss_action(uint16_t port_id, struct rte_flow_error *error);\n \n /**\n * create a flow rule that sends packets with matching src and dest ip\n@@ -18,8 +36,6 @@ generate_ipv4_flow(uint16_t port_id, uint16_t rx_q,\n *\n * @param port_id\n * The selected port.\n- * @param rx_q\n- * The selected target queue.\n * @param src_ip\n * The src ip value to match the input packet.\n * @param src_mask\n@@ -35,16 +51,15 @@ generate_ipv4_flow(uint16_t port_id, uint16_t rx_q,\n * A flow if the rule could be created else return NULL.\n */\n struct rte_flow *\n-generate_ipv4_flow(uint16_t port_id, uint16_t rx_q,\n-\t\tuint32_t src_ip, uint32_t src_mask,\n-\t\tuint32_t dest_ip, uint32_t dest_mask,\n-\t\tstruct rte_flow_error *error)\n+generate_ipv4_flow(uint16_t port_id,\n+\t\t uint32_t src_ip, uint32_t src_mask,\n+\t\t uint32_t dest_ip, uint32_t dest_mask,\n+\t\t struct rte_flow_error *error)\n {\n \tstruct rte_flow_attr attr;\n \tstruct rte_flow_item pattern[MAX_PATTERN_NUM];\n \tstruct rte_flow_action action[MAX_ACTION_NUM];\n \tstruct rte_flow *flow = NULL;\n-\tstruct rte_flow_action_queue queue = { .index = rx_q };\n \tstruct rte_flow_item_ipv4 ip_spec;\n \tstruct rte_flow_item_ipv4 ip_mask;\n \tint res;\n@@ -61,10 +76,19 @@ generate_ipv4_flow(uint16_t port_id, uint16_t rx_q,\n \n \t/*\n \t * create the action sequence.\n-\t * one action only, move packet to queue\n+\t * one action only, move packet to shared RSS queue\n \t */\n-\taction[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;\n-\taction[0].conf = &queue;\n+\tshared_action = rte_flow_shared_action_create(port_id, NULL,\n+\t\t\t\t\t\t &flow_action, error);\n+\tif (shared_action) {\n+\t\taction[0].conf = shared_action;\n+\t\taction[0].type = RTE_FLOW_ACTION_TYPE_SHARED;\n+\t} else {\n+\t\tif (rte_errno != ENOSYS)\n+\t\t\trte_exit(EXIT_FAILURE, \":: action creation failure\\n\");\n+\t\tprintf(\"PMD doesn't support shared actions.\\n\");\n+\t\taction[0] = flow_action;\n+\t}\n \taction[1].type = RTE_FLOW_ACTION_TYPE_END;\n \n \t/*\n@@ -98,3 +122,30 @@ generate_ipv4_flow(uint16_t port_id, uint16_t rx_q,\n \n \treturn flow;\n }\n+\n+/**\n+ * updates shared RSS action if flow created with shared action\n+ *\n+ * @param port_id\n+ * The selected port.\n+ * @param[out] error\n+ * Perform verbose error reporting if not NULL.\n+ *\n+ * @return\n+ * 0 on sccess\n+ */\n+int\n+update_rss_action(uint16_t port_id, struct rte_flow_error *error)\n+{\n+\tif (!shared_action)\n+\t\treturn 0;\n+\tif (rss_queue[0] == 0) {\n+\t\tprintf(\">>> switching queue 0 -> 1\\n\");\n+\t\trss_queue[0] = 1;\n+\t} else {\n+\t\tprintf(\">>> switching queue 1 -> 0\\n\");\n+\t\trss_queue[0] = 0;\n+\t}\n+\treturn rte_flow_shared_action_update(port_id, shared_action,\n+\t\t\t\t\t &flow_action, error);\n+}\ndiff --git a/examples/flow_filtering/main.c b/examples/flow_filtering/main.c\nindex cc9e7e7808..9ef7f099d9 100644\n--- a/examples/flow_filtering/main.c\n+++ b/examples/flow_filtering/main.c\n@@ -32,8 +32,7 @@\n static volatile bool force_quit;\n \n static uint16_t port_id;\n-static uint16_t nr_queues = 5;\n-static uint8_t selected_queue = 1;\n+static uint16_t nr_queues = 2;\n struct rte_mempool *mbuf_pool;\n struct rte_flow *flow;\n \n@@ -61,6 +60,7 @@ main_loop(void)\n \tuint16_t nb_rx;\n \tuint16_t i;\n \tuint16_t j;\n+\tint ret;\n \n \twhile (!force_quit) {\n \t\tfor (i = 0; i < nr_queues; i++) {\n@@ -82,6 +82,12 @@ main_loop(void)\n \n \t\t\t\t\trte_pktmbuf_free(m);\n \t\t\t\t}\n+\t\t\t\tret = update_rss_action(port_id, &error);\n+\t\t\t\tif (ret)\n+\t\t\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\t\t \":: error: RSS action update \"\n+\t\t\t\t\t\t \"failed: %s\\n\",\n+\t\t\t\t\t\t rte_strerror(-ret));\n \t\t\t}\n \t\t}\n \t}\n@@ -243,8 +249,9 @@ main(int argc, char **argv)\n \n \tinit_port();\n \n+\n \t/* create flow for send packet with */\n-\tflow = generate_ipv4_flow(port_id, selected_queue,\n+\tflow = generate_ipv4_flow(port_id,\n \t\t\t\tSRC_IP, EMPTY_MASK,\n \t\t\t\tDEST_IP, FULL_MASK, &error);\n \tif (!flow) {\n", "prefixes": [ "v3", "09/10" ] }{ "id": 79577, "url": "