get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 107294,
    "url": "http://patches.dpdk.org/api/patches/107294/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20220210162926.20436-10-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": "<20220210162926.20436-10-suanmingm@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220210162926.20436-10-suanmingm@nvidia.com",
    "date": "2022-02-10T16:29:22",
    "name": "[09/13] net/mlx5: add flow jump action",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "394d77c1bcbbd43c6067ea777fde022e1dc8255d",
    "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/20220210162926.20436-10-suanmingm@nvidia.com/mbox/",
    "series": [
        {
            "id": 21609,
            "url": "http://patches.dpdk.org/api/series/21609/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=21609",
            "date": "2022-02-10T16:29:13",
            "name": "net/mlx5: add hardware steering",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/21609/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/107294/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/107294/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 89496A00BE;\n\tThu, 10 Feb 2022 17:31:05 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 3D33A411B6;\n\tThu, 10 Feb 2022 17:30:09 +0100 (CET)",
            "from NAM11-CO1-obe.outbound.protection.outlook.com\n (mail-co1nam11on2075.outbound.protection.outlook.com [40.107.220.75])\n by mails.dpdk.org (Postfix) with ESMTP id BFA4E42739\n for <dev@dpdk.org>; Thu, 10 Feb 2022 17:30:06 +0100 (CET)",
            "from DM5PR19CA0052.namprd19.prod.outlook.com (2603:10b6:3:116::14)\n by MN0PR12MB5785.namprd12.prod.outlook.com (2603:10b6:208:374::17) with\n Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4975.11; Thu, 10 Feb\n 2022 16:30:04 +0000",
            "from DM6NAM11FT013.eop-nam11.prod.protection.outlook.com\n (2603:10b6:3:116:cafe::fd) by DM5PR19CA0052.outlook.office365.com\n (2603:10b6:3:116::14) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4975.11 via Frontend\n Transport; Thu, 10 Feb 2022 16:30:04 +0000",
            "from mail.nvidia.com (12.22.5.238) by\n DM6NAM11FT013.mail.protection.outlook.com (10.13.173.142) with Microsoft SMTP\n Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id\n 15.20.4975.11 via Frontend Transport; Thu, 10 Feb 2022 16:30:04 +0000",
            "from rnnvmail201.nvidia.com (10.129.68.8) by DRHQMAIL105.nvidia.com\n (10.27.9.14) with Microsoft SMTP Server (TLS) id 15.0.1497.18;\n Thu, 10 Feb 2022 16:30:03 +0000",
            "from nvidia.com (10.126.230.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; Thu, 10 Feb 2022\n 08:30:01 -0800"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=CP7pmYEKcOto+/+AApfPSsI/vSAjMkDySZDVoAWZxoY4+n62eHfyrUNR64bRf4mlxl5letnJMimiVXjqPkkNoKYapxF/o7JUZ527sYJeMCbhgRy5AfHltzE02ij8kyD4OTWmLqqV3ucfjaXGmnzB/Aa1f9vMMu49jZU0kGzfOLNrfoI64j2dWXP94neInN1cE2iov/h66RbRfvUhkfQ6aGFAgKvyTYJYQsPx/sz0ZIk7u04XO3fIiBFQkmtmh1wp3HEZim7qgd5BREdZxmV98F2TaN2zA+sziOxLa0mM/7tsAJtvI44pqt5QD/autUhv5/+Bgs6So9i1Ea5vdGLJHw==",
        "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=P5OferphP0ivB6EOkUmU0W8+N5qG+TL0DYIGFouI+mI=;\n b=ht5nLY9vxZlzDkgBHMTDHTvdC76MWYx0zU0r19mzAncV2LEEv4vZn/wqT53qSSlT6YPxyC97QhVwMsBcTSjIMux+KnPBj8vh7tKoo5GszeSA1egzThY5D1JHXgRYSpRZpnzBIAdXj2rzlARNHWyGPw9NS8/tRAPPkcYYoW3WaRbuzpEJgQjKRmVhzcwO3kkwynbrkv9sR+iqgqqV/iLTRrvq9dFR3WIS2kdXZ3U7m09JLYnHMzjKW4JyTJXILRJlR8pwpYKOiLnuys+D+/ujy9lwcA+rIIC2DuJD75Dcaa/A6PFMEdVNKIrNw5c2kSxv85I4wIR6TM+XXmJeX+rTyQ==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass (sender ip is\n 12.22.5.238) 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=P5OferphP0ivB6EOkUmU0W8+N5qG+TL0DYIGFouI+mI=;\n b=XE3Rz03rqVLhSktguMkIGEJ7LAEyNToDEJ5mRF9vyzWnwyn1HENXdotglE3umQSKzXz2M9fUiNpxZANqlx69Lf9eaYBNi7CroBLcAjmQOz3QzNdmjYCIcds7wuyPxw0FrZXBtmMyEZKNq0L9nTfiskMIQIK6rKSe5cvno3wqMJaU3OQTxP7Hyct77TOCAXGcP+ldU2RLgxMi56T6QLECIPiKsV8eY9HJ8ELjzJe8Pwd9K9DHnubCBKHRHy3SNz/6V4IYeqNt7qEQQKOvtIR848AbxM7Ybdjd3doFqQc7+W+MKOJzyNevm6F1c+f9DYpHS7DrV1R9tOZrq009imLTzw==",
        "X-MS-Exchange-Authentication-Results": "spf=pass (sender IP is 12.22.5.238)\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.238 as permitted sender) receiver=protection.outlook.com;\n client-ip=12.22.5.238; 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 09/13] net/mlx5: add flow jump action",
        "Date": "Thu, 10 Feb 2022 18:29:22 +0200",
        "Message-ID": "<20220210162926.20436-10-suanmingm@nvidia.com>",
        "X-Mailer": "git-send-email 2.18.1",
        "In-Reply-To": "<20220210162926.20436-1-suanmingm@nvidia.com>",
        "References": "<20220210162926.20436-1-suanmingm@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-Originating-IP": "[10.126.230.35]",
        "X-ClientProxiedBy": "rnnvmail203.nvidia.com (10.129.68.9) To\n rnnvmail201.nvidia.com (10.129.68.8)",
        "X-EOPAttributedMessage": "0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-Office365-Filtering-Correlation-Id": "82bebdd0-a2e1-47c3-b696-08d9ecb297b2",
        "X-MS-TrafficTypeDiagnostic": "MN0PR12MB5785:EE_",
        "X-Microsoft-Antispam-PRVS": "\n <MN0PR12MB578569FC2020B0244F441E86C12F9@MN0PR12MB5785.namprd12.prod.outlook.com>",
        "X-MS-Oob-TLC-OOBClassifiers": "OLM:514;",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;",
        "X-Microsoft-Antispam-Message-Info": "\n 302G9w6LUGb1AqhItfp+xq5HkRI0sL5/x7SKyw+lLbFwWj6ABBMOru7EMkIzrrg8E4GxrAeBFOIb2KgpaBPaK3EUWwxWqlpnwx4NJljOnhHRpRM+SCR23feRlILgcPunuxFQX3iBe0scz75aXqQ4sEMz6Q7k05bUxo4iH25etEtGfl6tvsCJdmB4m8pGIfPfxnoKb/uQ/vqAEmBjziR8kAFtttEgYHWtq+y2oJem9jTSlhoLIzo7ErUJcMW1VsPa3Wfj2N6rgAv4303N1fp5k/FuSRbc2K4A2awU66llHGGFwDE8X3SrjSTFD3r/NVW+dwcUnYm5PFM9rn7PS3jjDvWtEBM5Owf47TdyJOYJE8GcQXV3W+Zalpbn1WBpYVulIDc+DT+0a9i+9VgnwP0tfQCwqj9B4P4fRaC4ZCwnUwVTVLQRIqcmajQlOrNIJv7IbofMKLmDNglVF/jFkUeNNKvhZS1jKRJtGzmYZ7sVtMjTvg4ypfedIA6x/PFMfEpDiibN1IssAosz0sgmp35LbvWt46Zaq3kZJalDL+stN8AtE4WwNy/yOpgOIQS+JLAkInyBVleV8RKJlpiwbAElLqpaWJkOh+242OCDK2JEvjI5l8nUr2PXCQeqd/0YKn+IedtZzB0bZRzHzFcU//jxhaSh/HuPy1TUsJX+ZPO2Cv3WI4Z1RHgZ/aXc6S/tAA5RB23Lz4wKfaHKaR9PERLwi4N/gvhuec5LpdBSsqXLQ4uazTTboC+Zzh+LODvpFktl",
        "X-Forefront-Antispam-Report": "CIP:12.22.5.238; CTRY:US; LANG:en; SCL:1; SRV:;\n IPV:CAL; SFV:NSPM; H:mail.nvidia.com; PTR:InfoNoRecords; CAT:NONE;\n SFS:(13230001)(4636009)(40470700004)(36840700001)(46966006)(4326008)(508600001)(426003)(54906003)(26005)(8676002)(336012)(70586007)(2616005)(8936002)(5660300002)(16526019)(6636002)(316002)(6286002)(70206006)(110136005)(86362001)(186003)(82310400004)(81166007)(40460700003)(2906002)(6666004)(55016003)(36860700001)(36756003)(47076005)(356005)(83380400001)(7696005)(1076003)(30864003)(36900700001)(309714004);\n DIR:OUT; SFP:1101;",
        "X-OriginatorOrg": "Nvidia.com",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "10 Feb 2022 16:30:04.1947 (UTC)",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n 82bebdd0-a2e1-47c3-b696-08d9ecb297b2",
        "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.238];\n Helo=[mail.nvidia.com]",
        "X-MS-Exchange-CrossTenant-AuthSource": "\n DM6NAM11FT013.eop-nam11.prod.protection.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Anonymous",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "MN0PR12MB5785",
        "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 as a complete data\nflow.\nA new action construct data struct is also added in this commit to help\nhandle the dynamic actions.\n\nSigned-off-by: Suanming Mou <suanmingm@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 ec4eb7ee94..0bc9897101 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -1525,6 +1525,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 };\n \n #define PORT_ID(priv) ((priv)->dev_data->port_id)\ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex 40eb8d79aa..a1ab9173d9 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -1018,10 +1018,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@@ -1054,9 +1069,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 dcf72ab89f..a825766245 100644\n--- a/drivers/net/mlx5/mlx5_flow_hw.c\n+++ b/drivers/net/mlx5/mlx5_flow_hw.c\n@@ -30,18 +30,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@@ -74,14 +214,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@@ -89,14 +231,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@@ -105,7 +267,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@@ -114,6 +283,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@@ -127,31 +300,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@@ -230,7 +435,8 @@ flow_hw_q_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@@ -344,8 +550,11 @@ flow_hw_q_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@@ -616,6 +825,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@@ -631,7 +841,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@@ -687,7 +897,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@@ -1106,6 +1316,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->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@@ -1124,6 +1343,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@@ -1193,6 +1415,10 @@ flow_hw_configure(struct rte_eth_dev *dev,\n \t\tmlx5_free(priv->hw_q);\n \t\tpriv->hw_q = NULL;\n \t}\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@@ -1234,6 +1460,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": [
        "09/13"
    ]
}