get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 79577,
    "url": "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"
    ]
}