get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 108209,
    "url": "http://patches.dpdk.org/api/patches/108209/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20220224031029.14049-11-suanmingm@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": "<20220224031029.14049-11-suanmingm@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220224031029.14049-11-suanmingm@nvidia.com",
    "date": "2022-02-24T03:10:25",
    "name": "[v3,10/14] net/mlx5: add flow jump action",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "4e136b3639b011bad86b0669e2e724dfa5a7fe62",
    "submitter": {
        "id": 1887,
        "url": "http://patches.dpdk.org/api/people/1887/?format=api",
        "name": "Suanming Mou",
        "email": "suanmingm@nvidia.com"
    },
    "delegate": {
        "id": 3268,
        "url": "http://patches.dpdk.org/api/users/3268/?format=api",
        "username": "rasland",
        "first_name": "Raslan",
        "last_name": "Darawsheh",
        "email": "rasland@nvidia.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20220224031029.14049-11-suanmingm@nvidia.com/mbox/",
    "series": [
        {
            "id": 21839,
            "url": "http://patches.dpdk.org/api/series/21839/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=21839",
            "date": "2022-02-24T03:10:16",
            "name": "net/mlx5: add hardware steering",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/21839/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/108209/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/108209/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 mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id D9756A0353;\n\tThu, 24 Feb 2022 04:11:37 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id CF34941199;\n\tThu, 24 Feb 2022 04:11:11 +0100 (CET)",
            "from NAM11-BN8-obe.outbound.protection.outlook.com\n (mail-bn8nam11on2069.outbound.protection.outlook.com [40.107.236.69])\n by mails.dpdk.org (Postfix) with ESMTP id 258FE4118A\n for <dev@dpdk.org>; Thu, 24 Feb 2022 04:11:08 +0100 (CET)",
            "from MW4PR03CA0326.namprd03.prod.outlook.com (2603:10b6:303:dd::31)\n by MN2PR12MB3951.namprd12.prod.outlook.com (2603:10b6:208:16b::24)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5017.21; Thu, 24 Feb\n 2022 03:11:06 +0000",
            "from CO1NAM11FT036.eop-nam11.prod.protection.outlook.com\n (2603:10b6:303:dd:cafe::65) by MW4PR03CA0326.outlook.office365.com\n (2603:10b6:303:dd::31) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5017.23 via Frontend\n Transport; Thu, 24 Feb 2022 03:11:06 +0000",
            "from mail.nvidia.com (12.22.5.234) by\n CO1NAM11FT036.mail.protection.outlook.com (10.13.174.124) with Microsoft SMTP\n Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id\n 15.20.5017.22 via Frontend Transport; Thu, 24 Feb 2022 03:11:05 +0000",
            "from rnnvmail201.nvidia.com (10.129.68.8) by DRHQMAIL101.nvidia.com\n (10.27.9.10) with Microsoft SMTP Server (TLS) id 15.0.1497.18;\n Thu, 24 Feb 2022 03:11:04 +0000",
            "from nvidia.com (10.126.231.35) by rnnvmail201.nvidia.com\n (10.129.68.8) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.9; Wed, 23 Feb 2022\n 19:11:02 -0800"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=Z6wJ1/8tUKShtjxFw9H9CYoCqE5+HMMwn2ccNfn4kdy5E6prUy1abl3QyOBHfwWAF9J+OVo64g9wN5QV8ySGXm82OLqcPDvjFS9LkGL7BNPohmjXHd6pD9t00Q7marfG/3McUjy2/RSPF0ULjiv2b7sC1kOtNbjY9mJcv69iU9ExTid/wB3yljbchzmXG/FNUEs21Tn2wLIYq3aGAesQuIOHiXrpnBONgiLxFd7WIgj4CroWaXRu8jcg1ZX0HJZsGWgZ4Lh1iUuRIIIA49KUNfSWXuvw5pJ7zJ+gBdsCM18YgbuQ+JWkmp6VXM8j63sSY8077HtmfkftNNEUjnhMug==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector9901;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n bh=Sn7DqmwSxM9M4dXxd+vpjrbqAlcRITSMO+Z9I2Z3+vg=;\n b=LDsJEWrpD5tYJm7jW9PYHxLh03jBlbmpQ1td68cxrC91dRlFG+4aNTV3B3l01iWJaPGh+WDWNWMOmYgGKP4Tb/PN+XZV37JcY7G4RSHXRp+XVtVZjwhDvod3CpovN1V4y00sOQ1vvnu2is/9d9s7vC4LSlddAd7qhIQ2mFrz9sZzhi91P2/FMjNmMpk7dBka5OLycUAz1jCGJUmg6IY0T71GSsCfR8huDldkXPU/blDvHwpVYqsxx8VX3idssuHdJQjgpM8tUo0jRtvmkQWp0Cu4nW9CQSXNzfHTRYljXjFjBG0hUH4ogq2Tq8k7d3ONM6Je9/y005Y4cwaCb82VCw==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 12.22.5.234) smtp.rcpttodomain=dpdk.org smtp.mailfrom=nvidia.com; dmarc=pass\n (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none\n (message not signed); arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com;\n s=selector2;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=Sn7DqmwSxM9M4dXxd+vpjrbqAlcRITSMO+Z9I2Z3+vg=;\n b=H92nOb8lnm9bJ0H1ErWEFztsX6qhncrLC9ckPFxHR5pVdnZajvQS1crYHj8NOstH6MbARXUHInATjKjtO31EIK8pAA3709qYEt2VMPnSUQuMAtK0Mq94fOveIxW/lSThJmCypjkKHijnKpfLs8doVkl0rt6kXHfOxDxEQOviy1dXNJ6G4jZhNuNYyl/Fp2oa2X/pdawhabWaLTpXFlRKU/p1PVmonplwxHJLlv20itN4uBsw3GauFPI1YMGaRzxZ+pAoVzRrXXrNg5n2Ia43y4Lz6H5CgQXxRYvO6A/jLqwtrP9QXtzweq114bfTPrFWCLIIbffCF+dQWjqcBSt5nw==",
        "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 12.22.5.234)\n smtp.mailfrom=nvidia.com; dkim=none (message not signed)\n header.d=none;dmarc=pass action=none header.from=nvidia.com;",
        "Received-SPF": "Pass (protection.outlook.com: domain of nvidia.com designates\n 12.22.5.234 as permitted sender) receiver=protection.outlook.com;\n client-ip=12.22.5.234; helo=mail.nvidia.com;",
        "From": "Suanming Mou <suanmingm@nvidia.com>",
        "To": "<viacheslavo@nvidia.com>, <matan@nvidia.com>",
        "CC": "<rasland@nvidia.com>, <orika@nvidia.com>, <dev@dpdk.org>",
        "Subject": "[PATCH v3 10/14] net/mlx5: add flow jump action",
        "Date": "Thu, 24 Feb 2022 05:10:25 +0200",
        "Message-ID": "<20220224031029.14049-11-suanmingm@nvidia.com>",
        "X-Mailer": "git-send-email 2.18.1",
        "In-Reply-To": "<20220224031029.14049-1-suanmingm@nvidia.com>",
        "References": "<20220210162926.20436-1-suanmingm@nvidia.com>\n <20220224031029.14049-1-suanmingm@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.126.231.35]",
        "X-ClientProxiedBy": "rnnvmail201.nvidia.com (10.129.68.8) To\n rnnvmail201.nvidia.com (10.129.68.8)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "2233a846-6df1-497f-6fab-08d9f7434bf1",
        "X-MS-TrafficTypeDiagnostic": "MN2PR12MB3951:EE_",
        "X-Microsoft-Antispam-PRVS": "\n <MN2PR12MB3951BFBDDAA4D5699CB6A170C13D9@MN2PR12MB3951.namprd12.prod.outlook.com>",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n zvoKtfWz0ISNcKOo1WYjnASRO14VgQDU0pKzSboR/11/6Zczx1LF+HsZqNXt8pYrhoH6PzJxy9O67Crb2bMrKub3ZnrTEHvi0k5nDGvBUDD6bi9likrly7ejUZ42aqjHMUQU3X6bm+uc/4rQi59WJIYmfQa0vTDkesFIjVu+5G+m9Ofaem9j7hXE6FUYBOGMkxqgMuJFnw9KeJKxsW5butmWQF7FPYIO9HRykpndy5yvtdeMJEofmuEZV42hLWmmcDADbWf5ibZNx/ptF8Ric6MR/IivVexqZLISGFoRLSBjwcpWp3oIXf3E8Qnhdy+8UbT5XjvjOCNOhFR1tAosl+D9K8sfuQWfX5JSLFth4wdEd3eVHHlj4Ud5CHd8noVFUH5I8E6xVPDuT/WR8OYICQCcGk1svyvyW04a3MoIqzBdLhHkNGuyVDcDmPsVQXbMRF9M9ZRxbnH0CvBuQkP2XB1Oo+IJronMDGd98/eluTe41A7cw6Vi3HYz0GYonQH3Ts3YdhGC9FQur956zv8FxMwyZqcv+Nn29naHEkFDJL9NaVKyVnkAkS7Glrtv4SKJCBjQAYIui0fs/N5WCov0Xia3+6segDzIS1vFGXtfYf+yTd67e0IDWISWL73oYI9rx+dLIRkQRMMJ+DriT6mO3v2RNeLdwP1VRIW6j/vUphq605e/2WqxEf8HoQ+WUkgqMppIXcED3PkT0gX1NiND1DZNurTvZPHpfhQS9nqbtsd6Y+zg2GFhfDKYriD8aaUr",
        "X-Forefront-Antispam-Report": "CIP:12.22.5.234; CTRY:US; LANG:en; SCL:1; SRV:;\n IPV:CAL; SFV:NSPM; H:mail.nvidia.com; PTR:InfoNoRecords; CAT:NONE;\n SFS:(13230001)(4636009)(46966006)(36840700001)(40470700004)(5660300002)(40460700003)(30864003)(110136005)(2906002)(36756003)(508600001)(356005)(54906003)(6636002)(81166007)(8936002)(316002)(6666004)(6286002)(4326008)(1076003)(26005)(186003)(83380400001)(426003)(336012)(7696005)(16526019)(86362001)(82310400004)(70206006)(70586007)(8676002)(47076005)(55016003)(2616005)(36860700001)(36900700001)(309714004);\n DIR:OUT; SFP:1101;",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "24 Feb 2022 03:11:05.7525 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 2233a846-6df1-497f-6fab-08d9f7434bf1",
        "X-MS-Exchange-CrossTenant-Id": "43083d15-7273-40c1-b7db-39efd9ccc17a",
        "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "\n TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[12.22.5.234];\n Helo=[mail.nvidia.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n CO1NAM11FT036.eop-nam11.prod.protection.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "MN2PR12MB3951",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "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"
    },
    "content": "Jump action connects different level of flow tables and allows packet\nhandling in the chain of flows.\n\nA new action construct data struct is also added in this commit to help\nto handle not only the dynamic jump action but also for the other generic\ndynamic actions. The actions with empty mask configuration means dynamic\naction, and the dedicated action will be created with the flow action\nconfiguration during flow creation. In that dynamic action case, the action\nwill be appended to the table template's action list during table creation.\nWhen creating the flows, traverse the action list and pick the dynamic\naction configuration details from flow actions as the action construct data\nstruct describes, then create the dedicated dynamic actions.\n\nThis commit adds the jump action and the generic dynamic action construct\nmechanism.\n\nSigned-off-by: Suanming Mou <suanmingm@nvidia.com>\nAcked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>\n---\n drivers/net/mlx5/mlx5.h         |   1 +\n drivers/net/mlx5/mlx5_flow.h    |  25 ++-\n drivers/net/mlx5/mlx5_flow_hw.c | 270 +++++++++++++++++++++++++++++---\n 3 files changed, 275 insertions(+), 21 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex d94e98db77..f3732958a2 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -1527,6 +1527,7 @@ struct mlx5_priv {\n \t/* HW steering global drop action. */\n \tstruct mlx5dr_action *hw_drop[MLX5_HW_ACTION_FLAG_MAX]\n \t\t\t\t     [MLX5DR_TABLE_TYPE_MAX];\n+\tstruct mlx5_indexed_pool *acts_ipool; /* Action data indexed pool. */\n #endif\n };\n \ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex 3add4c4a81..963dbd7806 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -1020,10 +1020,25 @@ struct rte_flow {\n /* HWS flow struct. */\n struct rte_flow_hw {\n \tuint32_t idx; /* Flow index from indexed pool. */\n+\tuint32_t fate_type; /* Fate action type. */\n+\tunion {\n+\t\t/* Jump action. */\n+\t\tstruct mlx5_hw_jump_action *jump;\n+\t};\n \tstruct rte_flow_template_table *table; /* The table flow allcated from. */\n \tstruct mlx5dr_rule rule; /* HWS layer data struct. */\n } __rte_packed;\n \n+/* rte flow action translate to DR action struct. */\n+struct mlx5_action_construct_data {\n+\tLIST_ENTRY(mlx5_action_construct_data) next;\n+\t/* Ensure the action types are matched. */\n+\tint type;\n+\tuint32_t idx;  /* Data index. */\n+\tuint16_t action_src; /* rte_flow_action src offset. */\n+\tuint16_t action_dst; /* mlx5dr_rule_action dst offset. */\n+};\n+\n /* Flow item template struct. */\n struct rte_flow_pattern_template {\n \tLIST_ENTRY(rte_flow_pattern_template) next;\n@@ -1051,9 +1066,17 @@ struct mlx5_hw_jump_action {\n \tstruct mlx5dr_action *hws_action;\n };\n \n+/* The maximum actions support in the flow. */\n+#define MLX5_HW_MAX_ACTS 16\n+\n /* DR action set struct. */\n struct mlx5_hw_actions {\n-\tstruct mlx5dr_action *drop; /* Drop action. */\n+\t/* Dynamic action list. */\n+\tLIST_HEAD(act_list, mlx5_action_construct_data) act_list;\n+\tstruct mlx5_hw_jump_action *jump; /* Jump action. */\n+\tuint32_t acts_num:4; /* Total action number. */\n+\t/* Translated DR action array from action template. */\n+\tstruct mlx5dr_rule_action rule_acts[MLX5_HW_MAX_ACTS];\n };\n \n /* mlx5 action template struct. */\ndiff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c\nindex ed14eacce2..f320d0db8c 100644\n--- a/drivers/net/mlx5/mlx5_flow_hw.c\n+++ b/drivers/net/mlx5/mlx5_flow_hw.c\n@@ -36,18 +36,158 @@ static uint32_t mlx5_hw_act_flag[MLX5_HW_ACTION_FLAG_MAX]\n \t},\n };\n \n+/**\n+ * Register destination table DR jump action.\n+ *\n+ * @param[in] dev\n+ *   Pointer to the rte_eth_dev structure.\n+ * @param[in] table_attr\n+ *   Pointer to the flow attributes.\n+ * @param[in] dest_group\n+ *   The destination group ID.\n+ * @param[out] error\n+ *   Pointer to error structure.\n+ *\n+ * @return\n+ *    Table on success, NULL otherwise and rte_errno is set.\n+ */\n+static struct mlx5_hw_jump_action *\n+flow_hw_jump_action_register(struct rte_eth_dev *dev,\n+\t\t\t     const struct rte_flow_attr *attr,\n+\t\t\t     uint32_t dest_group,\n+\t\t\t     struct rte_flow_error *error)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct rte_flow_attr jattr = *attr;\n+\tstruct mlx5_flow_group *grp;\n+\tstruct mlx5_flow_cb_ctx ctx = {\n+\t\t.dev = dev,\n+\t\t.error = error,\n+\t\t.data = &jattr,\n+\t};\n+\tstruct mlx5_list_entry *ge;\n+\n+\tjattr.group = dest_group;\n+\tge = mlx5_hlist_register(priv->sh->flow_tbls, dest_group, &ctx);\n+\tif (!ge)\n+\t\treturn NULL;\n+\tgrp = container_of(ge, struct mlx5_flow_group, entry);\n+\treturn &grp->jump;\n+}\n+\n+/**\n+ * Release jump action.\n+ *\n+ * @param[in] dev\n+ *   Pointer to the rte_eth_dev structure.\n+ * @param[in] jump\n+ *   Pointer to the jump action.\n+ */\n+\n+static void\n+flow_hw_jump_release(struct rte_eth_dev *dev, struct mlx5_hw_jump_action *jump)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_flow_group *grp;\n+\n+\tgrp = container_of\n+\t\t(jump, struct mlx5_flow_group, jump);\n+\tmlx5_hlist_unregister(priv->sh->flow_tbls, &grp->entry);\n+}\n+\n /**\n  * Destroy DR actions created by action template.\n  *\n  * For DR actions created during table creation's action translate.\n  * Need to destroy the DR action when destroying the table.\n  *\n+ * @param[in] dev\n+ *   Pointer to the rte_eth_dev structure.\n  * @param[in] acts\n  *   Pointer to the template HW steering DR actions.\n  */\n static void\n-__flow_hw_action_template_destroy(struct mlx5_hw_actions *acts __rte_unused)\n+__flow_hw_action_template_destroy(struct rte_eth_dev *dev,\n+\t\t\t\t struct mlx5_hw_actions *acts)\n {\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\n+\tif (acts->jump) {\n+\t\tstruct mlx5_flow_group *grp;\n+\n+\t\tgrp = container_of\n+\t\t\t(acts->jump, struct mlx5_flow_group, jump);\n+\t\tmlx5_hlist_unregister(priv->sh->flow_tbls, &grp->entry);\n+\t\tacts->jump = NULL;\n+\t}\n+}\n+\n+/**\n+ * Append dynamic action to the dynamic action list.\n+ *\n+ * @param[in] priv\n+ *   Pointer to the port private data structure.\n+ * @param[in] acts\n+ *   Pointer to the template HW steering DR actions.\n+ * @param[in] type\n+ *   Action type.\n+ * @param[in] action_src\n+ *   Offset of source rte flow action.\n+ * @param[in] action_dst\n+ *   Offset of destination DR action.\n+ *\n+ * @return\n+ *    0 on success, negative value otherwise and rte_errno is set.\n+ */\n+static __rte_always_inline struct mlx5_action_construct_data *\n+__flow_hw_act_data_alloc(struct mlx5_priv *priv,\n+\t\t\t enum rte_flow_action_type type,\n+\t\t\t uint16_t action_src,\n+\t\t\t uint16_t action_dst)\n+{\n+\tstruct mlx5_action_construct_data *act_data;\n+\tuint32_t idx = 0;\n+\n+\tact_data = mlx5_ipool_zmalloc(priv->acts_ipool, &idx);\n+\tif (!act_data)\n+\t\treturn NULL;\n+\tact_data->idx = idx;\n+\tact_data->type = type;\n+\tact_data->action_src = action_src;\n+\tact_data->action_dst = action_dst;\n+\treturn act_data;\n+}\n+\n+/**\n+ * Append dynamic action to the dynamic action list.\n+ *\n+ * @param[in] priv\n+ *   Pointer to the port private data structure.\n+ * @param[in] acts\n+ *   Pointer to the template HW steering DR actions.\n+ * @param[in] type\n+ *   Action type.\n+ * @param[in] action_src\n+ *   Offset of source rte flow action.\n+ * @param[in] action_dst\n+ *   Offset of destination DR action.\n+ *\n+ * @return\n+ *    0 on success, negative value otherwise and rte_errno is set.\n+ */\n+static __rte_always_inline int\n+__flow_hw_act_data_general_append(struct mlx5_priv *priv,\n+\t\t\t\t  struct mlx5_hw_actions *acts,\n+\t\t\t\t  enum rte_flow_action_type type,\n+\t\t\t\t  uint16_t action_src,\n+\t\t\t\t  uint16_t action_dst)\n+{\tstruct mlx5_action_construct_data *act_data;\n+\n+\tact_data = __flow_hw_act_data_alloc(priv, type, action_src, action_dst);\n+\tif (!act_data)\n+\t\treturn -1;\n+\tLIST_INSERT_HEAD(&acts->act_list, act_data, next);\n+\treturn 0;\n }\n \n /**\n@@ -80,14 +220,16 @@ flow_hw_actions_translate(struct rte_eth_dev *dev,\n \t\t\t  const struct rte_flow_template_table_attr *table_attr,\n \t\t\t  struct mlx5_hw_actions *acts,\n \t\t\t  struct rte_flow_actions_template *at,\n-\t\t\t  struct rte_flow_error *error __rte_unused)\n+\t\t\t  struct rte_flow_error *error)\n {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n \tconst struct rte_flow_attr *attr = &table_attr->flow_attr;\n \tstruct rte_flow_action *actions = at->actions;\n+\tstruct rte_flow_action *action_start = actions;\n \tstruct rte_flow_action *masks = at->masks;\n \tbool actions_end = false;\n-\tuint32_t type;\n+\tuint32_t type, i;\n+\tint err;\n \n \tif (attr->transfer)\n \t\ttype = MLX5DR_TABLE_TYPE_FDB;\n@@ -95,14 +237,34 @@ flow_hw_actions_translate(struct rte_eth_dev *dev,\n \t\ttype = MLX5DR_TABLE_TYPE_NIC_TX;\n \telse\n \t\ttype = MLX5DR_TABLE_TYPE_NIC_RX;\n-\tfor (; !actions_end; actions++, masks++) {\n+\tfor (i = 0; !actions_end; actions++, masks++) {\n \t\tswitch (actions->type) {\n \t\tcase RTE_FLOW_ACTION_TYPE_INDIRECT:\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_VOID:\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_DROP:\n-\t\t\tacts->drop = priv->hw_drop[!!attr->group][type];\n+\t\t\tacts->rule_acts[i++].action =\n+\t\t\t\tpriv->hw_drop[!!attr->group][type];\n+\t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_JUMP:\n+\t\t\tif (masks->conf) {\n+\t\t\t\tuint32_t jump_group =\n+\t\t\t\t\t((const struct rte_flow_action_jump *)\n+\t\t\t\t\tactions->conf)->group;\n+\t\t\t\tacts->jump = flow_hw_jump_action_register\n+\t\t\t\t\t\t(dev, attr, jump_group, error);\n+\t\t\t\tif (!acts->jump)\n+\t\t\t\t\tgoto err;\n+\t\t\t\tacts->rule_acts[i].action = (!!attr->group) ?\n+\t\t\t\t\t\tacts->jump->hws_action :\n+\t\t\t\t\t\tacts->jump->root_action;\n+\t\t\t} else if (__flow_hw_act_data_general_append\n+\t\t\t\t\t(priv, acts, actions->type,\n+\t\t\t\t\t actions - action_start, i)){\n+\t\t\t\tgoto err;\n+\t\t\t}\n+\t\t\ti++;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_END:\n \t\t\tactions_end = true;\n@@ -111,7 +273,14 @@ flow_hw_actions_translate(struct rte_eth_dev *dev,\n \t\t\tbreak;\n \t\t}\n \t}\n+\tacts->acts_num = i;\n \treturn 0;\n+err:\n+\terr = rte_errno;\n+\t__flow_hw_action_template_destroy(dev, acts);\n+\treturn rte_flow_error_set(error, err,\n+\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t  \"fail to create rte table\");\n }\n \n /**\n@@ -120,6 +289,10 @@ flow_hw_actions_translate(struct rte_eth_dev *dev,\n  * For action template contains dynamic actions, these actions need to\n  * be updated according to the rte_flow action during flow creation.\n  *\n+ * @param[in] dev\n+ *   Pointer to the rte_eth_dev structure.\n+ * @param[in] job\n+ *   Pointer to job descriptor.\n  * @param[in] hw_acts\n  *   Pointer to translated actions from template.\n  * @param[in] actions\n@@ -133,31 +306,63 @@ flow_hw_actions_translate(struct rte_eth_dev *dev,\n  *    0 on success, negative value otherwise and rte_errno is set.\n  */\n static __rte_always_inline int\n-flow_hw_actions_construct(struct mlx5_hw_actions *hw_acts,\n+flow_hw_actions_construct(struct rte_eth_dev *dev,\n+\t\t\t  struct mlx5_hw_q_job *job,\n+\t\t\t  struct mlx5_hw_actions *hw_acts,\n \t\t\t  const struct rte_flow_action actions[],\n \t\t\t  struct mlx5dr_rule_action *rule_acts,\n \t\t\t  uint32_t *acts_num)\n {\n-\tbool actions_end = false;\n-\tuint32_t i;\n+\tstruct rte_flow_template_table *table = job->flow->table;\n+\tstruct mlx5_action_construct_data *act_data;\n+\tconst struct rte_flow_action *action;\n+\tstruct rte_flow_attr attr = {\n+\t\t\t.ingress = 1,\n+\t};\n \n-\tfor (i = 0; !actions_end || (i >= MLX5_HW_MAX_ACTS); actions++) {\n-\t\tswitch (actions->type) {\n+\tmemcpy(rule_acts, hw_acts->rule_acts,\n+\t       sizeof(*rule_acts) * hw_acts->acts_num);\n+\t*acts_num = hw_acts->acts_num;\n+\tif (LIST_EMPTY(&hw_acts->act_list))\n+\t\treturn 0;\n+\tattr.group = table->grp->group_id;\n+\tif (table->type == MLX5DR_TABLE_TYPE_FDB) {\n+\t\tattr.transfer = 1;\n+\t\tattr.ingress = 1;\n+\t} else if (table->type == MLX5DR_TABLE_TYPE_NIC_TX) {\n+\t\tattr.egress = 1;\n+\t\tattr.ingress = 0;\n+\t} else {\n+\t\tattr.ingress = 1;\n+\t}\n+\tLIST_FOREACH(act_data, &hw_acts->act_list, next) {\n+\t\tuint32_t jump_group;\n+\t\tstruct mlx5_hw_jump_action *jump;\n+\n+\t\taction = &actions[act_data->action_src];\n+\t\tMLX5_ASSERT(action->type == RTE_FLOW_ACTION_TYPE_INDIRECT ||\n+\t\t\t    (int)action->type == act_data->type);\n+\t\tswitch (action->type) {\n \t\tcase RTE_FLOW_ACTION_TYPE_INDIRECT:\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_VOID:\n \t\t\tbreak;\n-\t\tcase RTE_FLOW_ACTION_TYPE_DROP:\n-\t\t\trule_acts[i++].action = hw_acts->drop;\n-\t\t\tbreak;\n-\t\tcase RTE_FLOW_ACTION_TYPE_END:\n-\t\t\tactions_end = true;\n+\t\tcase RTE_FLOW_ACTION_TYPE_JUMP:\n+\t\t\tjump_group = ((const struct rte_flow_action_jump *)\n+\t\t\t\t\t\taction->conf)->group;\n+\t\t\tjump = flow_hw_jump_action_register\n+\t\t\t\t(dev, &attr, jump_group, NULL);\n+\t\t\tif (!jump)\n+\t\t\t\treturn -1;\n+\t\t\trule_acts[act_data->action_dst].action =\n+\t\t\t(!!attr.group) ? jump->hws_action : jump->root_action;\n+\t\t\tjob->flow->jump = jump;\n+\t\t\tjob->flow->fate_type = MLX5_FLOW_FATE_JUMP;\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tbreak;\n \t\t}\n \t}\n-\t*acts_num = i;\n \treturn 0;\n }\n \n@@ -239,7 +444,8 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,\n \trule_attr.user_data = job;\n \thw_acts = &table->ats[action_template_index].acts;\n \t/* Construct the flow action array based on the input actions.*/\n-\tflow_hw_actions_construct(hw_acts, actions, rule_acts, &acts_num);\n+\tflow_hw_actions_construct(dev, job, hw_acts, actions,\n+\t\t\t\t  rule_acts, &acts_num);\n \tret = mlx5dr_rule_create(table->matcher,\n \t\t\t\t pattern_template_index, items,\n \t\t\t\t rule_acts, acts_num,\n@@ -356,8 +562,11 @@ flow_hw_pull(struct rte_eth_dev *dev,\n \t\tjob = (struct mlx5_hw_q_job *)res[i].user_data;\n \t\t/* Restore user data. */\n \t\tres[i].user_data = job->user_data;\n-\t\tif (job->type == MLX5_HW_Q_JOB_TYPE_DESTROY)\n+\t\tif (job->type == MLX5_HW_Q_JOB_TYPE_DESTROY) {\n+\t\t\tif (job->flow->fate_type == MLX5_FLOW_FATE_JUMP)\n+\t\t\t\tflow_hw_jump_release(dev, job->flow->jump);\n \t\t\tmlx5_ipool_free(job->flow->table->flow, job->flow->idx);\n+\t\t}\n \t\tpriv->hw_q[queue].job[priv->hw_q[queue].job_idx++] = job;\n \t}\n \treturn ret;\n@@ -642,6 +851,7 @@ flow_hw_table_create(struct rte_eth_dev *dev,\n \t\t\trte_errno = EINVAL;\n \t\t\tgoto at_error;\n \t\t}\n+\t\tLIST_INIT(&tbl->ats[i].acts.act_list);\n \t\terr = flow_hw_actions_translate(dev, attr,\n \t\t\t\t\t\t&tbl->ats[i].acts,\n \t\t\t\t\t\taction_templates[i], error);\n@@ -657,7 +867,7 @@ flow_hw_table_create(struct rte_eth_dev *dev,\n \treturn tbl;\n at_error:\n \twhile (i--) {\n-\t\t__flow_hw_action_template_destroy(&tbl->ats[i].acts);\n+\t\t__flow_hw_action_template_destroy(dev, &tbl->ats[i].acts);\n \t\t__atomic_sub_fetch(&action_templates[i]->refcnt,\n \t\t\t\t   1, __ATOMIC_RELAXED);\n \t}\n@@ -716,7 +926,7 @@ flow_hw_table_destroy(struct rte_eth_dev *dev,\n \t\t__atomic_sub_fetch(&table->its[i]->refcnt,\n \t\t\t\t   1, __ATOMIC_RELAXED);\n \tfor (i = 0; i < table->nb_action_templates; i++) {\n-\t\t__flow_hw_action_template_destroy(&table->ats[i].acts);\n+\t\t__flow_hw_action_template_destroy(dev, &table->ats[i].acts);\n \t\t__atomic_sub_fetch(&table->ats[i].action_template->refcnt,\n \t\t\t\t   1, __ATOMIC_RELAXED);\n \t}\n@@ -1167,6 +1377,15 @@ flow_hw_configure(struct rte_eth_dev *dev,\n \tstruct mlx5_hw_q *hw_q;\n \tstruct mlx5_hw_q_job *job = NULL;\n \tuint32_t mem_size, i, j;\n+\tstruct mlx5_indexed_pool_config cfg = {\n+\t\t.size = sizeof(struct rte_flow_hw),\n+\t\t.trunk_size = 4096,\n+\t\t.need_lock = 1,\n+\t\t.release_mem_en = !!priv->sh->config.reclaim_mode,\n+\t\t.malloc = mlx5_malloc,\n+\t\t.free = mlx5_free,\n+\t\t.type = \"mlx5_hw_action_construct_data\",\n+\t};\n \n \tif (!port_attr || !nb_queue || !queue_attr) {\n \t\trte_errno = EINVAL;\n@@ -1185,6 +1404,9 @@ flow_hw_configure(struct rte_eth_dev *dev,\n \t\t}\n \t\tflow_hw_resource_release(dev);\n \t}\n+\tpriv->acts_ipool = mlx5_ipool_create(&cfg);\n+\tif (!priv->acts_ipool)\n+\t\tgoto err;\n \t/* Allocate the queue job descriptor LIFO. */\n \tmem_size = sizeof(priv->hw_q[0]) * nb_queue;\n \tfor (i = 0; i < nb_queue; i++) {\n@@ -1252,6 +1474,10 @@ flow_hw_configure(struct rte_eth_dev *dev,\n \t\tclaim_zero(mlx5dr_context_close(dr_ctx));\n \tmlx5_free(priv->hw_q);\n \tpriv->hw_q = NULL;\n+\tif (priv->acts_ipool) {\n+\t\tmlx5_ipool_destroy(priv->acts_ipool);\n+\t\tpriv->acts_ipool = NULL;\n+\t}\n \treturn rte_flow_error_set(error, rte_errno,\n \t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n \t\t\t\t  \"fail to configure port\");\n@@ -1293,6 +1519,10 @@ flow_hw_resource_release(struct rte_eth_dev *dev)\n \t\t\tmlx5dr_action_destroy(priv->hw_drop[i][j]);\n \t\t}\n \t}\n+\tif (priv->acts_ipool) {\n+\t\tmlx5_ipool_destroy(priv->acts_ipool);\n+\t\tpriv->acts_ipool = NULL;\n+\t}\n \tmlx5_free(priv->hw_q);\n \tpriv->hw_q = NULL;\n \tclaim_zero(mlx5dr_context_close(priv->dr_ctx));\n",
    "prefixes": [
        "v3",
        "10/14"
    ]
}