Show a patch.

GET /api/patches/73560/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 73560,
    "url": "https://patches.dpdk.org/api/patches/73560/?format=api",
    "web_url": "https://patches.dpdk.org/patch/73560/",
    "project": {
        "id": 1,
        "url": "https://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"
    },
    "msgid": "<20200708213946.30108-7-andreyv@mellanox.com>",
    "date": "2020-07-08T21:39:45",
    "name": "[v2,6/6] examples/flow_filtering: utilize shared RSS action",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "a8bc9267c80fa2c1ef658142830e71650f202817",
    "submitter": {
        "id": 1809,
        "url": "https://patches.dpdk.org/api/people/1809/?format=api",
        "name": "Andrey Vesnovaty",
        "email": "andreyv@mellanox.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@intel.com"
    },
    "mbox": "https://patches.dpdk.org/patch/73560/mbox/",
    "series": [
        {
            "id": 10899,
            "url": "https://patches.dpdk.org/api/series/10899/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=10899",
            "date": "2020-07-08T21:39:39",
            "name": "add flow shared action API + PMD",
            "version": 2,
            "mbox": "https://patches.dpdk.org/series/10899/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/73560/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/73560/checks/",
    "tags": {},
    "headers": {
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "List-Post": "<mailto:dev@dpdk.org>",
        "MIME-Version": "1.0",
        "References": "<20200702120511.16315-1-andreyv@mellanox.com>\n <20200708213946.30108-1-andreyv@mellanox.com>",
        "X-BeenThere": "dev@dpdk.org",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "Subject": "[dpdk-dev] [PATCH v2 6/6] examples/flow_filtering: utilize shared\n\tRSS action",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>",
        "From": "Andrey Vesnovaty <andreyv@mellanox.com>",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id BAFFBA0526;\n\tWed,  8 Jul 2020 23:40:49 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 5113B1E552;\n\tWed,  8 Jul 2020 23:40:08 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id E71A91E49A\n for <dev@dpdk.org>; Wed,  8 Jul 2020 23:39:57 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n andreyv@mellanox.com) with SMTP; 9 Jul 2020 00:39:55 +0300",
            "from r-arch-host11.mtr.labs.mlnx. (r-arch-host11.mtr.labs.mlnx\n [10.213.43.60])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 068LdrB7032740;\n Thu, 9 Jul 2020 00:39:54 +0300"
        ],
        "To": "dev@dpdk.org",
        "X-Mailer": "git-send-email 2.26.2",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "Date": "Thu,  9 Jul 2020 00:39:45 +0300",
        "Content-Transfer-Encoding": "8bit",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "In-Reply-To": "<20200708213946.30108-1-andreyv@mellanox.com>",
        "Cc": "jer@marvell.com, jerinjacobk@gmail.com, thomas@monjalon.net,\n ferruh.yigit@intel.com, stephen@networkplumber.org,\n bruce.richardson@intel.com, orika@mellanox.com,\n viacheslavo@mellanox.com, andrey.vesnovaty@gmail.com,\n Marko Kovacevic <marko.kovacevic@intel.com>,\n Radu Nicolau <radu.nicolau@intel.com>, 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>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Message-Id": "<20200708213946.30108-7-andreyv@mellanox.com>",
        "Return-Path": "<dev-bounces@dpdk.org>"
    },
    "content": "This commit gives very first shared RSS action usage example and\ndemonstrates shared action capability for in-place update.\n\nFirst application creates shared action during initialization phase.\nLater on the flow object created by application uses previously created\nshared RSS action with 1 queue configured instead of queue action in\noriginal application.\n\nOn each RX queue burst shared RSS action reconfigured via\nrte_flow_shared_action_update() API to switch queue 0 to 1 & 1 to 0.\nUser supposed to observe consistent queue switches on each packet burst.\n\nSigned-off-by: Andrey Vesnovaty <andreyv@mellanox.com>\n---\n doc/guides/sample_app_ug/flow_filtering.rst | 62 +++++++++++++++++----\n examples/flow_filtering/flow_blocks.c       | 30 +++++-----\n examples/flow_filtering/main.c              | 41 +++++++++++++-\n 3 files changed, 105 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..99bfed3172 100644\n--- a/examples/flow_filtering/flow_blocks.c\n+++ b/examples/flow_filtering/flow_blocks.c\n@@ -6,11 +6,11 @@\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-\n+generate_ipv4_flow(uint16_t port_id,\n+\t\t   struct rte_flow_shared_action *shared_action,\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 /**\n  * create a flow rule that sends packets with matching src and dest ip\n@@ -18,8 +18,8 @@ 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 shared_action\n+ *   The shared RSS action with single queue\n  * @param src_ip\n  *   The src ip value to match the input packet.\n  * @param src_mask\n@@ -35,16 +35,16 @@ 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   struct rte_flow_shared_action *shared_action,\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 +61,10 @@ 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+\taction[0].type = RTE_FLOW_ACTION_TYPE_SHARED;\n+\taction[0].conf = shared_action;\n \taction[1].type = RTE_FLOW_ACTION_TYPE_END;\n \n \t/*\ndiff --git a/examples/flow_filtering/main.c b/examples/flow_filtering/main.c\nindex cc9e7e7808..d6b18d95fc 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@@ -42,6 +41,24 @@ struct rte_flow *flow;\n #define FULL_MASK 0xffffffff /* full mask */\n #define EMPTY_MASK 0x0 /* empty mask */\n \n+struct rte_flow_shared_action *shared_action;\n+uint16_t rss_queue[1] = {0};\n+\n+struct rte_flow_action_rss action_rss = {\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 action = {\n+\t.type = RTE_FLOW_ACTION_TYPE_RSS,\n+\t.conf = &action_rss,\n+};\n+\n #include \"flow_blocks.c\"\n \n static inline void\n@@ -61,6 +78,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 +100,21 @@ main_loop(void)\n \n \t\t\t\t\trte_pktmbuf_free(m);\n \t\t\t\t}\n+\t\t\t\tif (rss_queue[0] == 0) {\n+\t\t\t\t\tprintf(\">>> switching queue 0 -> 1\\n\");\n+\t\t\t\t\trss_queue[0] = 1;\n+\t\t\t\t} else {\n+\t\t\t\t\tprintf(\">>> switching queue 1 -> 0\\n\");\n+\t\t\t\t\trss_queue[0] = 0;\n+\t\t\t\t}\n+\t\t\t\tret = rte_flow_shared_action_update\n+\t\t\t\t\t(port_id, shared_action, &action,\n+\t\t\t\t\t &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 +276,10 @@ main(int argc, char **argv)\n \n \tinit_port();\n \n+\tshared_action = rte_flow_shared_action_create(port_id, &action, &error);\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, shared_action,\n \t\t\t\tSRC_IP, EMPTY_MASK,\n \t\t\t\tDEST_IP, FULL_MASK, &error);\n \tif (!flow) {\n",
    "prefixes": [
        "v2",
        "6/6"
    ]
}