get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 52271,
    "url": "http://patches.dpdk.org/api/patches/52271/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1554371628-170844-4-git-send-email-orika@mellanox.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": "<1554371628-170844-4-git-send-email-orika@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1554371628-170844-4-git-send-email-orika@mellanox.com",
    "date": "2019-04-04T09:54:08",
    "name": "[v4,3/3] net/mlx5: add jump action support for NIC",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "93760fc5b28bf866a52158914f214dd78802bc75",
    "submitter": {
        "id": 795,
        "url": "http://patches.dpdk.org/api/people/795/?format=api",
        "name": "Ori Kam",
        "email": "orika@mellanox.com"
    },
    "delegate": {
        "id": 6624,
        "url": "http://patches.dpdk.org/api/users/6624/?format=api",
        "username": "shahafs",
        "first_name": "Shahaf",
        "last_name": "Shuler",
        "email": "shahafs@mellanox.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1554371628-170844-4-git-send-email-orika@mellanox.com/mbox/",
    "series": [
        {
            "id": 4110,
            "url": "http://patches.dpdk.org/api/series/4110/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=4110",
            "date": "2019-04-04T09:54:05",
            "name": "net/mlx5: Add Direct Rule support",
            "version": 4,
            "mbox": "http://patches.dpdk.org/series/4110/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/52271/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/52271/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id A87971B136;\n\tThu,  4 Apr 2019 11:54:15 +0200 (CEST)",
            "from EUR04-HE1-obe.outbound.protection.outlook.com\n\t(mail-eopbgr70049.outbound.protection.outlook.com [40.107.7.49])\n\tby dpdk.org (Postfix) with ESMTP id A48CF1B114\n\tfor <dev@dpdk.org>; Thu,  4 Apr 2019 11:54:10 +0200 (CEST)",
            "from AM4PR05MB3425.eurprd05.prod.outlook.com (10.171.190.15) by\n\tAM4PR05MB3282.eurprd05.prod.outlook.com (10.171.187.159) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n\t15.20.1750.19; Thu, 4 Apr 2019 09:54:08 +0000",
            "from AM4PR05MB3425.eurprd05.prod.outlook.com\n\t([fe80::5df0:22de:97f0:3827]) by\n\tAM4PR05MB3425.eurprd05.prod.outlook.com\n\t([fe80::5df0:22de:97f0:3827%4]) with mapi id 15.20.1771.014;\n\tThu, 4 Apr 2019 09:54:08 +0000"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com;\n\ts=selector1;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n\tbh=ZIXeWTG8IWs0ds+dFr5gPGbukNMmbv6QK0eLk3C7v+Y=;\n\tb=rXTVI1y65cMPngxKixB9OB4jAc4gqZyGLRfm0p+buPrVguRytpp8gD3ecKWCiPLrD+NbzmVDRvjNgU461wAOUuXjTw8mfMOraMseVROA3R66R94F7JVT6Q0edjtclOh6k/YAzM8db4tQ2YkFCb+iJ0yi7QKY3ZmHtlsTiCId5TQ=",
        "From": "Ori Kam <orika@mellanox.com>",
        "To": "Matan Azrad <matan@mellanox.com>, Yongseok Koh <yskoh@mellanox.com>,\n\tShahaf Shuler <shahafs@mellanox.com>",
        "CC": "\"dev@dpdk.org\" <dev@dpdk.org>, Ori Kam <orika@mellanox.com>, Slava\n\tOvsiienko <viacheslavo@mellanox.com>",
        "Thread-Topic": "[PATCH v4 3/3] net/mlx5: add jump action support for NIC",
        "Thread-Index": "AQHU6sxYVemT+nideEqytG2zNK8Spg==",
        "Date": "Thu, 4 Apr 2019 09:54:08 +0000",
        "Message-ID": "<1554371628-170844-4-git-send-email-orika@mellanox.com>",
        "References": "<1553790741-69362-1-git-send-email-orika@mellanox.com>\n\t<1554371628-170844-1-git-send-email-orika@mellanox.com>",
        "In-Reply-To": "<1554371628-170844-1-git-send-email-orika@mellanox.com>",
        "Accept-Language": "en-US",
        "Content-Language": "en-US",
        "X-MS-Has-Attach": "",
        "X-MS-TNEF-Correlator": "",
        "x-clientproxiedby": "LO2P265CA0363.GBRP265.PROD.OUTLOOK.COM\n\t(2603:10a6:600:a3::15) To AM4PR05MB3425.eurprd05.prod.outlook.com\n\t(2603:10a6:205:b::15)",
        "authentication-results": "spf=none (sender IP is )\n\tsmtp.mailfrom=orika@mellanox.com; ",
        "x-ms-exchange-messagesentrepresentingtype": "1",
        "x-mailer": "git-send-email 1.8.3.1",
        "x-originating-ip": "[37.142.13.130]",
        "x-ms-publictraffictype": "Email",
        "x-ms-office365-filtering-correlation-id": "82662b30-3303-435a-8f1c-08d6b8e37b46",
        "x-ms-office365-filtering-ht": "Tenant",
        "x-microsoft-antispam": "BCL:0; PCL:0;\n\tRULEID:(2390118)(7020095)(4652040)(8989299)(5600139)(711020)(4605104)(4618075)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7193020);\n\tSRVR:AM4PR05MB3282; ",
        "x-ms-traffictypediagnostic": "AM4PR05MB3282:",
        "x-microsoft-antispam-prvs": "<AM4PR05MB3282F020991B12E8ADB9E3F7DB500@AM4PR05MB3282.eurprd05.prod.outlook.com>",
        "x-forefront-prvs": "0997523C40",
        "x-forefront-antispam-report": "SFV:NSPM;\n\tSFS:(10009020)(376002)(366004)(39860400002)(136003)(346002)(396003)(199004)(189003)(256004)(446003)(386003)(97736004)(102836004)(6506007)(6116002)(6436002)(8676002)(316002)(11346002)(53936002)(2906002)(81156014)(107886003)(478600001)(5660300002)(54906003)(81166006)(2616005)(53946003)(476003)(110136005)(6486002)(8936002)(6512007)(50226002)(76176011)(52116002)(14454004)(86362001)(36756003)(26005)(14444005)(486006)(71200400001)(4326008)(4720700003)(3846002)(186003)(66066001)(68736007)(25786009)(305945005)(106356001)(99286004)(6636002)(30864003)(105586002)(7736002)(71190400001);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR05MB3282;\n\tH:AM4PR05MB3425.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en;\n\tPTR:InfoNoRecords; A:1; MX:1; ",
        "received-spf": "None (protection.outlook.com: mellanox.com does not designate\n\tpermitted sender hosts)",
        "x-ms-exchange-senderadcheck": "1",
        "x-microsoft-antispam-message-info": "xHqE2gRZ43H/zo4dgsZ+72AyNWZtLrX6o5H6Ibim6nfqqoOjBcblfELWWNpnRapeiwsa+j3TrdvzGy9rs/QmdPSssYcP0WbANqhDpRPmZtXNrZm2ahiCe2PIP2PmBY9WU/jMabelfGcZ+qtlZL1cXFc1uPoYQ/SPikYvn036fJCTmAwJFlIk2HB9/ZHZtx5S1r190DJMo1nTHW7VmvP+k3zKBrVaDuv6JL5NPOeo1no36ImGdHguoW0GQYj8UMdDNvX7cTMFgGfJ8q5G+apKl2AiG1h+j+9FnBY9ButPkVONUbHSkSTzpnqyl/U6zuRX8a5DpMR0JTQYW9H/n9r7Hq5DHp9o0cwzgo95pO0JuX1clKxXyE5ebA2FE8UlAoBJ1Av9dRM+VxCxN2B02Pt6hNY4bQtRs6BATuvArdqLLHM=",
        "Content-Type": "text/plain; charset=\"iso-8859-1\"",
        "Content-Transfer-Encoding": "quoted-printable",
        "MIME-Version": "1.0",
        "X-OriginatorOrg": "Mellanox.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "82662b30-3303-435a-8f1c-08d6b8e37b46",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "04 Apr 2019 09:54:08.7884\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-fromentityheader": "Hosted",
        "X-MS-Exchange-CrossTenant-id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-CrossTenant-mailboxtype": "HOSTED",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM4PR05MB3282",
        "Subject": "[dpdk-dev] [PATCH v4 3/3] net/mlx5: add jump action support for NIC",
        "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\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "When using Direct Rules we can add actions to jump between tables.\nThis is extra useful since rule insertion rate is much higher on other\ntables compared to table zero.\n\nif no group is selected the rule is added to group 0.\n\nSigned-off-by: Ori Kam <orika@mellanox.com>\nAcked-by: Shahaf Shuler <shahafs@mellanox.com>\n---\nv4:\n* Fix compilation issue.\n---\n drivers/net/mlx5/mlx5.h         |   6 +\n drivers/net/mlx5/mlx5_flow.h    |  15 ++-\n drivers/net/mlx5/mlx5_flow_dv.c | 280 +++++++++++++++++++++++++++++++++++-----\n drivers/net/mlx5/mlx5_glue.c    |  13 ++\n drivers/net/mlx5/mlx5_glue.h    |   1 +\n 5 files changed, 284 insertions(+), 31 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex d4963cb..5a7597e 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -319,6 +319,12 @@ struct mlx5_priv {\n \tLIST_HEAD(encap_decap, mlx5_flow_dv_encap_decap_resource) encaps_decaps;\n \tLIST_HEAD(modify_cmd, mlx5_flow_dv_modify_hdr_resource) modify_cmds;\n \tLIST_HEAD(tag, mlx5_flow_dv_tag_resource) tags;\n+\tLIST_HEAD(jump, mlx5_flow_dv_jump_tbl_resource) jump_tbl;\n+\t/* Pointer to next element. */\n+\trte_atomic32_t refcnt; /**< Reference counter. */\n+\tstruct ibv_flow_action *verbs_action;\n+\t/**< Verbs modify header action object. */\n+\tuint8_t ft_type; /**< Flow table type, Rx or Tx. */\n \t/* Tags resources cache. */\n \tuint32_t link_speed_capa; /* Link speed capabilities. */\n \tstruct mlx5_xstats_ctrl xstats_ctrl; /* Extended stats control. */\ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex 8ba37a0..622e305 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -115,7 +115,8 @@\n #define MLX5_FLOW_ACTION_RAW_DECAP (1u << 27)\n \n #define MLX5_FLOW_FATE_ACTIONS \\\n-\t(MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | MLX5_FLOW_ACTION_RSS)\n+\t(MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \\\n+\t MLX5_FLOW_ACTION_RSS | MLX5_FLOW_ACTION_JUMP)\n \n #define MLX5_FLOW_ENCAP_ACTIONS\t(MLX5_FLOW_ACTION_VXLAN_ENCAP | \\\n \t\t\t\t MLX5_FLOW_ACTION_NVGRE_ENCAP | \\\n@@ -250,6 +251,16 @@ struct mlx5_flow_dv_modify_hdr_resource {\n \t/**< Modification actions. */\n };\n \n+/* Jump action resource structure. */\n+struct mlx5_flow_dv_jump_tbl_resource {\n+\tLIST_ENTRY(mlx5_flow_dv_jump_tbl_resource) next;\n+\t/* Pointer to next element. */\n+\trte_atomic32_t refcnt; /**< Reference counter. */\n+\tvoid *action; /**< Pointer to the rdma core action. */\n+\tuint8_t ft_type; /**< Flow table type, Rx or Tx. */\n+\tstruct mlx5_flow_tbl_resource *tbl; /**< The target table. */\n+};\n+\n /*\n  * Max number of actions per DV flow.\n  * See CREATE_FLOW_MAX_FLOW_ACTIONS_SUPPORTED\n@@ -270,6 +281,8 @@ struct mlx5_flow_dv {\n \tstruct mlx5_flow_dv_modify_hdr_resource *modify_hdr;\n \t/**< Pointer to modify header resource in cache. */\n \tstruct ibv_flow *flow; /**< Installed flow. */\n+\tstruct mlx5_flow_dv_jump_tbl_resource *jump;\n+\t/**< Pointer to the jump action resource. */\n #ifdef HAVE_IBV_FLOW_DV_SUPPORT\n \tvoid *actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS];\n \t/**< Action list. */\ndiff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c\nindex dd5b541..10c6eee 100644\n--- a/drivers/net/mlx5/mlx5_flow_dv.c\n+++ b/drivers/net/mlx5/mlx5_flow_dv.c\n@@ -865,6 +865,68 @@ struct field_modify_info modify_tcp[] = {\n }\n \n /**\n+ * Find existing table jump resource or create and register a new one.\n+ *\n+ * @param dev[in, out]\n+ *   Pointer to rte_eth_dev structure.\n+ * @param[in, out] resource\n+ *   Pointer to jump table resource.\n+ * @parm[in, out] dev_flow\n+ *   Pointer to the dev_flow.\n+ * @param[out] error\n+ *   pointer to error structure.\n+ *\n+ * @return\n+ *   0 on success otherwise -errno and errno is set.\n+ */\n+static int\n+flow_dv_jump_tbl_resource_register\n+\t\t\t(struct rte_eth_dev *dev,\n+\t\t\t struct mlx5_flow_dv_jump_tbl_resource *resource,\n+\t\t\t struct mlx5_flow *dev_flow,\n+\t\t\t struct rte_flow_error *error)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_flow_dv_jump_tbl_resource *cache_resource;\n+\n+\t/* Lookup a matching resource from cache. */\n+\tLIST_FOREACH(cache_resource, &priv->jump_tbl, next) {\n+\t\tif (resource->tbl == cache_resource->tbl) {\n+\t\t\tDRV_LOG(DEBUG, \"jump table resource resource %p: refcnt %d++\",\n+\t\t\t\t(void *)cache_resource,\n+\t\t\t\trte_atomic32_read(&cache_resource->refcnt));\n+\t\t\trte_atomic32_inc(&cache_resource->refcnt);\n+\t\t\tdev_flow->dv.jump = cache_resource;\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\t/* Register new jump table resource. */\n+\tcache_resource = rte_calloc(__func__, 1, sizeof(*cache_resource), 0);\n+\tif (!cache_resource)\n+\t\treturn rte_flow_error_set(error, ENOMEM,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t  \"cannot allocate resource memory\");\n+\t*cache_resource = *resource;\n+\tcache_resource->action =\n+\t\tmlx5_glue->dr_create_flow_action_dest_flow_tbl\n+\t\t(resource->tbl->obj);\n+\tif (!cache_resource->action) {\n+\t\trte_free(cache_resource);\n+\t\treturn rte_flow_error_set(error, ENOMEM,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL, \"cannot create action\");\n+\t}\n+\trte_atomic32_init(&cache_resource->refcnt);\n+\trte_atomic32_inc(&cache_resource->refcnt);\n+\tLIST_INSERT_HEAD(&priv->jump_tbl, cache_resource, next);\n+\tdev_flow->dv.jump = cache_resource;\n+\tDRV_LOG(DEBUG, \"new jump table  resource %p: refcnt %d++\",\n+\t\t(void *)cache_resource,\n+\t\trte_atomic32_read(&cache_resource->refcnt));\n+\treturn 0;\n+}\n+\n+/**\n  * Get the size of specific rte_flow_item_type\n  *\n  * @param[in] item_type\n@@ -1427,6 +1489,37 @@ struct field_modify_info modify_tcp[] = {\n }\n \n /**\n+ * Validate jump action.\n+ *\n+ * @param[in] action\n+ *   Pointer to the modify action.\n+ * @param[in] group\n+ *   The group of the current flow.\n+ * @param[out] error\n+ *   Pointer to error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+flow_dv_validate_action_jump(const struct rte_flow_action *action,\n+\t\t\t     uint32_t group,\n+\t\t\t     struct rte_flow_error *error)\n+{\n+\tif (action->type != RTE_FLOW_ACTION_TYPE_JUMP && !action->conf)\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION_CONF,\n+\t\t\t\t\t  NULL, \"action configuration not set\");\n+\tif (group >= ((const struct rte_flow_action_jump *)action->conf)->group)\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION, NULL,\n+\t\t\t\t\t  \"target group must be higher then\"\n+\t\t\t\t\t  \" the current flow group\");\n+\treturn 0;\n+}\n+\n+\n+/**\n  * Find existing modify-header resource or create and register a new one.\n  *\n  * @param dev[in, out]\n@@ -1609,7 +1702,7 @@ struct field_modify_info modify_tcp[] = {\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n \tuint32_t priority_max = priv->config.flow_prio - 1;\n \n-#ifdef HAVE_MLX5DV_DR\n+#ifndef HAVE_MLX5DV_DR\n \tif (attributes->group)\n \t\treturn rte_flow_error_set(error, ENOTSUP,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ATTR_GROUP,\n@@ -1981,6 +2074,14 @@ struct field_modify_info modify_tcp[] = {\n \t\t\t\t\t\tMLX5_FLOW_ACTION_SET_TTL :\n \t\t\t\t\t\tMLX5_FLOW_ACTION_DEC_TTL;\n \t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_JUMP:\n+\t\t\tret = flow_dv_validate_action_jump(actions,\n+\t\t\t\t\t\t\t   attr->group, error);\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n+\t\t\t++actions_n;\n+\t\t\taction_flags |= MLX5_FLOW_ACTION_JUMP;\n+\t\t\tbreak;\n \t\tdefault:\n \t\t\treturn rte_flow_error_set(error, ENOTSUP,\n \t\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_ACTION,\n@@ -2760,6 +2861,82 @@ struct field_modify_info modify_tcp[] = {\n \treturn match_criteria_enable;\n }\n \n+\n+/**\n+ * Get a flow table.\n+ *\n+ * @param dev[in, out]\n+ *   Pointer to rte_eth_dev structure.\n+ * @param[in] table_id\n+ *   Table id to use.\n+ * @param[in] egress\n+ *   Direction of the table.\n+ * @param[out] error\n+ *   pointer to error structure.\n+ *\n+ * @return\n+ *   Returns tables resource based on the index, NULL in case of failed.\n+ */\n+static struct mlx5_flow_tbl_resource *\n+flow_dv_tbl_resource_get(struct rte_eth_dev *dev,\n+\t\t\t uint32_t table_id, uint8_t egress,\n+\t\t\t struct rte_flow_error *error)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_flow_tbl_resource *tbl;\n+\n+#ifdef HAVE_MLX5DV_DR\n+\tif (egress) {\n+\t\ttbl = &priv->tx_tbl[table_id];\n+\t\tif (!tbl->obj)\n+\t\t\ttbl->obj = mlx5_glue->dr_create_flow_tbl\n+\t\t\t\t(priv->tx_ns, table_id);\n+\t} else {\n+\t\ttbl = &priv->rx_tbl[table_id];\n+\t\tif (!tbl->obj)\n+\t\t\ttbl->obj = mlx5_glue->dr_create_flow_tbl\n+\t\t\t\t(priv->rx_ns, table_id);\n+\t}\n+\tif (!tbl->obj) {\n+\t\trte_flow_error_set(error, ENOMEM,\n+\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t   NULL, \"cannot create table\");\n+\t\treturn NULL;\n+\t}\n+\trte_atomic32_inc(&tbl->refcnt);\n+\treturn tbl;\n+#else\n+\t(void)error;\n+\t(void)tbl;\n+\tif (egress)\n+\t\treturn &priv->tx_tbl[table_id];\n+\telse\n+\t\treturn &priv->rx_tbl[table_id];\n+#endif\n+}\n+\n+/**\n+ * Release a flow table.\n+ *\n+ * @param[in] tbl\n+ *   Table resource to be released.\n+ *\n+ * @return\n+ *   Returns 0 if table was released, else return 1;\n+ */\n+static int\n+flow_dv_tbl_resource_release(struct mlx5_flow_tbl_resource *tbl)\n+{\n+\tif (!tbl)\n+\t\treturn 0;\n+\tif (rte_atomic32_dec_and_test(&tbl->refcnt)) {\n+\t\tmlx5_glue->dr_destroy_flow_tbl(tbl->obj);\n+\t\ttbl->obj = NULL;\n+\t\treturn 0;\n+\t}\n+\treturn 1;\n+}\n+\n /**\n  * Register the flow matcher.\n  *\n@@ -2809,33 +2986,20 @@ struct field_modify_info modify_tcp[] = {\n \t\t\treturn 0;\n \t\t}\n \t}\n-#ifdef HAVE_MLX5DV_DR\n-\tif (matcher->egress) {\n-\t\ttbl = &priv->tx_tbl[matcher->group];\n-\t\tif (!tbl->obj)\n-\t\t\ttbl->obj = mlx5_glue->dr_create_flow_tbl\n-\t\t\t\t(priv->tx_ns,\n-\t\t\t\t matcher->group * MLX5_GROUP_FACTOR);\n-\t} else {\n-\t\ttbl = &priv->rx_tbl[matcher->group];\n-\t\tif (!tbl->obj)\n-\t\t\ttbl->obj = mlx5_glue->dr_create_flow_tbl\n-\t\t\t\t(priv->rx_ns,\n-\t\t\t\t matcher->group * MLX5_GROUP_FACTOR);\n-\t}\n-\tif (!tbl->obj)\n-\t\treturn rte_flow_error_set(error, ENOMEM,\n-\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n-\t\t\t\t\t  NULL, \"cannot create table\");\n-\n-\trte_atomic32_inc(&tbl->refcnt);\n-#endif\n \t/* Register new matcher. */\n \tcache_matcher = rte_calloc(__func__, 1, sizeof(*cache_matcher), 0);\n \tif (!cache_matcher)\n \t\treturn rte_flow_error_set(error, ENOMEM,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n \t\t\t\t\t  \"cannot allocate matcher memory\");\n+\ttbl = flow_dv_tbl_resource_get(dev, matcher->group * MLX5_GROUP_FACTOR,\n+\t\t\t\t       matcher->egress, error);\n+\tif (!tbl) {\n+\t\trte_free(cache_matcher);\n+\t\treturn rte_flow_error_set(error, ENOMEM,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL, \"cannot create table\");\n+\t}\n \t*cache_matcher = *matcher;\n \tdv_attr.match_criteria_enable =\n \t\tflow_dv_matcher_enable(cache_matcher->mask.buf);\n@@ -2848,10 +3012,7 @@ struct field_modify_info modify_tcp[] = {\n \tif (!cache_matcher->matcher_object) {\n \t\trte_free(cache_matcher);\n #ifdef HAVE_MLX5DV_DR\n-\t\tif (rte_atomic32_dec_and_test(&tbl->refcnt)) {\n-\t\t\tmlx5_glue->dr_destroy_flow_tbl(tbl->obj);\n-\t\t\ttbl->obj = NULL;\n-\t\t}\n+\t\tflow_dv_tbl_resource_release(tbl);\n #endif\n \t\treturn rte_flow_error_set(error, ENOMEM,\n \t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n@@ -3037,6 +3198,9 @@ struct field_modify_info modify_tcp[] = {\n \t\tconst struct rte_flow_action *action = actions;\n \t\tconst struct rte_flow_action_count *count = action->conf;\n \t\tconst uint8_t *rss_key;\n+\t\tconst struct rte_flow_action_jump *jump_data;\n+\t\tstruct mlx5_flow_dv_jump_tbl_resource jump_tbl_resource;\n+\t\tstruct mlx5_flow_tbl_resource *tbl;\n \n \t\tswitch (actions->type) {\n \t\tcase RTE_FLOW_ACTION_TYPE_VOID:\n@@ -3175,6 +3339,31 @@ struct field_modify_info modify_tcp[] = {\n \t\t\t/* If decap is followed by encap, handle it at encap. */\n \t\t\taction_flags |= MLX5_FLOW_ACTION_RAW_DECAP;\n \t\t\tbreak;\n+\t\tcase RTE_FLOW_ACTION_TYPE_JUMP:\n+\t\t\tjump_data = action->conf;\n+\t\t\ttbl = flow_dv_tbl_resource_get(dev, jump_data->group *\n+\t\t\t\t\t\t       MLX5_GROUP_FACTOR,\n+\t\t\t\t\t\t       attr->egress, error);\n+\t\t\tif (!tbl)\n+\t\t\t\treturn rte_flow_error_set\n+\t\t\t\t\t\t(error, errno,\n+\t\t\t\t\t\t RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t\t\t NULL,\n+\t\t\t\t\t\t \"cannot create jump action.\");\n+\t\t\tjump_tbl_resource.tbl = tbl;\n+\t\t\tif (flow_dv_jump_tbl_resource_register\n+\t\t\t    (dev, &jump_tbl_resource, dev_flow, error)) {\n+\t\t\t\tflow_dv_tbl_resource_release(tbl);\n+\t\t\t\treturn rte_flow_error_set\n+\t\t\t\t\t\t(error, errno,\n+\t\t\t\t\t\t RTE_FLOW_ERROR_TYPE_ACTION,\n+\t\t\t\t\t\t NULL,\n+\t\t\t\t\t\t \"cannot create jump action.\");\n+\t\t\t}\n+\t\t\tdev_flow->dv.actions[actions_n++] =\n+\t\t\t\tdev_flow->dv.jump->action;\n+\t\t\taction_flags |= MLX5_FLOW_ACTION_JUMP;\n+\t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_SET_MAC_SRC:\n \t\tcase RTE_FLOW_ACTION_TYPE_SET_MAC_DST:\n \t\t\tif (flow_dv_convert_action_modify_mac(&res, actions,\n@@ -3507,10 +3696,7 @@ struct field_modify_info modify_tcp[] = {\n \t\t\ttbl = &priv->tx_tbl[matcher->group];\n \t\telse\n \t\t\ttbl = &priv->rx_tbl[matcher->group];\n-\t\tif (rte_atomic32_dec_and_test(&tbl->refcnt)) {\n-\t\t\tmlx5_glue->dr_destroy_flow_tbl(tbl->obj);\n-\t\t\ttbl->obj = NULL;\n-\t\t}\n+\t\tflow_dv_tbl_resource_release(tbl);\n \t\trte_free(matcher);\n \t\tDRV_LOG(DEBUG, \"port %u matcher %p: removed\",\n \t\t\tdev->data->port_id, (void *)matcher);\n@@ -3551,6 +3737,38 @@ struct field_modify_info modify_tcp[] = {\n }\n \n /**\n+ * Release an jump to table action resource.\n+ *\n+ * @param flow\n+ *   Pointer to mlx5_flow.\n+ *\n+ * @return\n+ *   1 while a reference on it exists, 0 when freed.\n+ */\n+static int\n+flow_dv_jump_tbl_resource_release(struct mlx5_flow *flow)\n+{\n+\tstruct mlx5_flow_dv_jump_tbl_resource *cache_resource =\n+\t\t\t\t\t\tflow->dv.jump;\n+\n+\tassert(cache_resource->action);\n+\tDRV_LOG(DEBUG, \"jump table resource %p: refcnt %d--\",\n+\t\t(void *)cache_resource,\n+\t\trte_atomic32_read(&cache_resource->refcnt));\n+\tif (rte_atomic32_dec_and_test(&cache_resource->refcnt)) {\n+\t\tclaim_zero(mlx5_glue->destroy_flow_action\n+\t\t\t\t(cache_resource->action));\n+\t\tLIST_REMOVE(cache_resource, next);\n+\t\tflow_dv_tbl_resource_release(cache_resource->tbl);\n+\t\trte_free(cache_resource);\n+\t\tDRV_LOG(DEBUG, \"jump table resource %p: removed\",\n+\t\t\t(void *)cache_resource);\n+\t\treturn 0;\n+\t}\n+\treturn 1;\n+}\n+\n+/**\n  * Release a modify-header resource.\n  *\n  * @param flow\n@@ -3646,6 +3864,8 @@ struct field_modify_info modify_tcp[] = {\n \t\t\tflow_dv_encap_decap_resource_release(dev_flow);\n \t\tif (dev_flow->dv.modify_hdr)\n \t\t\tflow_dv_modify_hdr_resource_release(dev_flow);\n+\t\tif (dev_flow->dv.jump)\n+\t\t\tflow_dv_jump_tbl_resource_release(dev_flow);\n \t\trte_free(dev_flow);\n \t}\n }\ndiff --git a/drivers/net/mlx5/mlx5_glue.c b/drivers/net/mlx5/mlx5_glue.c\nindex b0b144c..f5a6c2e 100644\n--- a/drivers/net/mlx5/mlx5_glue.c\n+++ b/drivers/net/mlx5/mlx5_glue.c\n@@ -370,6 +370,17 @@\n }\n \n static void *\n+mlx5_glue_dr_create_flow_action_dest_flow_tbl(void *tbl)\n+{\n+#ifdef HAVE_MLX5DV_DR\n+\treturn mlx5dv_dr_create_action_dest_flow_table(tbl);\n+#else\n+\t(void)tbl;\n+\treturn NULL;\n+#endif\n+}\n+\n+static void *\n mlx5_glue_dr_create_flow_tbl(void *ns, uint32_t level)\n {\n #ifdef HAVE_MLX5DV_DR\n@@ -833,6 +844,8 @@\n \t.get_async_event = mlx5_glue_get_async_event,\n \t.port_state_str = mlx5_glue_port_state_str,\n \t.cq_ex_to_cq = mlx5_glue_cq_ex_to_cq,\n+\t.dr_create_flow_action_dest_flow_tbl =\n+\t\tmlx5_glue_dr_create_flow_action_dest_flow_tbl,\n \t.dr_create_flow_tbl = mlx5_glue_dr_create_flow_tbl,\n \t.dr_destroy_flow_tbl = mlx5_glue_dr_destroy_flow_tbl,\n \t.dr_create_ns = mlx5_glue_dr_create_ns,\ndiff --git a/drivers/net/mlx5/mlx5_glue.h b/drivers/net/mlx5/mlx5_glue.h\nindex eb29ffa..058e9b1 100644\n--- a/drivers/net/mlx5/mlx5_glue.h\n+++ b/drivers/net/mlx5/mlx5_glue.h\n@@ -145,6 +145,7 @@ struct mlx5_glue {\n \t\t\t       struct ibv_async_event *event);\n \tconst char *(*port_state_str)(enum ibv_port_state port_state);\n \tstruct ibv_cq *(*cq_ex_to_cq)(struct ibv_cq_ex *cq);\n+\tvoid *(*dr_create_flow_action_dest_flow_tbl)(void *tbl);\n \tvoid *(*dr_create_flow_tbl)(void *ns, uint32_t level);\n \tint (*dr_destroy_flow_tbl)(void *tbl);\n \tvoid *(*dr_create_ns)(struct ibv_context *ctx,\n",
    "prefixes": [
        "v4",
        "3/3"
    ]
}