get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 52269,
    "url": "http://patches.dpdk.org/api/patches/52269/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1554371628-170844-2-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-2-git-send-email-orika@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1554371628-170844-2-git-send-email-orika@mellanox.com",
    "date": "2019-04-04T09:54:06",
    "name": "[v4,1/3] net/mlx5: prepare Direct Verbs for Direct Rule",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "c2dd9c03ddc52f4633db153715b473d2960c2bdb",
    "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-2-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/52269/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/52269/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 8F91B1B112;\n\tThu,  4 Apr 2019 11:54:10 +0200 (CEST)",
            "from EUR04-HE1-obe.outbound.protection.outlook.com\n\t(mail-eopbgr70085.outbound.protection.outlook.com [40.107.7.85])\n\tby dpdk.org (Postfix) with ESMTP id 194941B0F7\n\tfor <dev@dpdk.org>; Thu,  4 Apr 2019 11:54:08 +0200 (CEST)",
            "from AM4PR05MB3425.eurprd05.prod.outlook.com (10.171.190.15) by\n\tAM4PR05MB3139.eurprd05.prod.outlook.com (10.171.186.16) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n\t15.20.1750.22; Thu, 4 Apr 2019 09:54:06 +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:06 +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=MQekMAaAiykr28ELAo4jU3LKAA31kx5Z1UaDfObl/nY=;\n\tb=qMr47z289qwE0fo8OJGQ4xtNBjjKw9/R798Pr4e/4yHtKm2ok9qOLPguJi8ggxPXtUxCAWzbf8xOyc8Ylc0acuCnWHq4NtuTTQzZ9JqX6ROAMYqC5vSRGMp93Wx/szZLTLXd7ACYPVQsC1lE/jWtjkSPBQrly7LqkAlByfrGBhc=",
        "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 1/3] net/mlx5: prepare Direct Verbs for Direct Rule",
        "Thread-Index": "AQHU6sxXvdqR4PNy4EGhKBhNp77JIQ==",
        "Date": "Thu, 4 Apr 2019 09:54:06 +0000",
        "Message-ID": "<1554371628-170844-2-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": "03055bca-19d1-4de1-1379-08d6b8e379e5",
        "x-ms-office365-filtering-ht": "Tenant",
        "x-microsoft-antispam": "BCL:0; PCL:0;\n\tRULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600139)(711020)(4605104)(4618075)(2017052603328)(7193020);\n\tSRVR:AM4PR05MB3139; ",
        "x-ms-traffictypediagnostic": "AM4PR05MB3139:",
        "x-microsoft-antispam-prvs": "<AM4PR05MB3139A3DDD2D671988616D068DB500@AM4PR05MB3139.eurprd05.prod.outlook.com>",
        "x-forefront-prvs": "0997523C40",
        "x-forefront-antispam-report": "SFV:NSPM;\n\tSFS:(10009020)(136003)(376002)(39860400002)(396003)(366004)(346002)(51234002)(199004)(189003)(76176011)(53936002)(186003)(6636002)(2616005)(446003)(25786009)(26005)(52116002)(36756003)(6486002)(6512007)(476003)(5660300002)(256004)(107886003)(2906002)(3846002)(53946003)(6116002)(97736004)(68736007)(486006)(4326008)(478600001)(6436002)(110136005)(105586002)(99286004)(86362001)(305945005)(66066001)(11346002)(30864003)(316002)(102836004)(8676002)(81166006)(8936002)(14454004)(106356001)(6506007)(81156014)(71200400001)(386003)(7736002)(50226002)(71190400001)(54906003)(4720700003)(579004);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR05MB3139;\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": "6BSEStSF1cRBhGLVnIpa9S+tsCn+PcOb7V97Ne63n7rv64Pgo4SFq5+ofMfaGgKd6hbAMsnFPYy7Lv5pE6jLkNW3hOdnen5qfalMNbocrSFMC5GSL9apBF+o1voVPv8BMPJKJ+DqZWzHVWNM0miViHzUXLvxBv6bgS+Xagl4+dciyxAhY/Vp+9RRhLh/qnoSvYOs8aetQL4Eim6QNNQniGrytlgJWHYLSq99bk5PLULG3tVKZKf8cAsI6yfdo8eLH8O1zjupeFtGcjHHKWSAoWawUc3NeMaw7WNgkd/9kjhpa2EJTV/2SmArVnav7n60ESZcXAOeSVDlNqSbR7qC0Nxu9qwc1V4CXzzdZwiUBy9lNI3D7/PS3leThexKCxk07byL5te2O9GLBTvCw0ItkvOQkNEYlJJbc0K9E+dL7iM=",
        "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": "03055bca-19d1-4de1-1379-08d6b8e379e5",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "04 Apr 2019 09:54:06.4568\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": "AM4PR05MB3139",
        "Subject": "[dpdk-dev] [PATCH v4 1/3] net/mlx5: prepare Direct Verbs for Direct\n\tRule",
        "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": "This is the first patch of a series that is designed to enable the\nDirect Rules API.\n\nThe main difference between Direct Verbs and Direct Rules from API\nprespective, is that in Direct Rules each action has it's own create\nfunction and the object itself is of type void.\n\nIn this patch I'm adding functions to generate actions that currenlty\nare done without create action, and I'm changing the action type to be\nvoid *, so in next patches only the glue functions will need to change.\n\nSigned-off-by: Ori Kam <orika@mellanox.com>\nAcked-by: Shahaf Shuler <shahafs@mellanox.com>\n---\n drivers/net/mlx5/Makefile       |   2 +-\n drivers/net/mlx5/meson.build    |   2 +-\n drivers/net/mlx5/mlx5.h         |   2 +\n drivers/net/mlx5/mlx5_flow.h    |  17 +++-\n drivers/net/mlx5/mlx5_flow_dv.c | 184 +++++++++++++++++++++++++++++-----------\n drivers/net/mlx5/mlx5_glue.c    | 141 ++++++++++++++++++++++++------\n drivers/net/mlx5/mlx5_glue.h    |  26 +++---\n 7 files changed, 280 insertions(+), 94 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile\nindex ccd179c..0d20f0f 100644\n--- a/drivers/net/mlx5/Makefile\n+++ b/drivers/net/mlx5/Makefile\n@@ -8,7 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk\n LIB = librte_pmd_mlx5.a\n LIB_GLUE = $(LIB_GLUE_BASE).$(LIB_GLUE_VERSION)\n LIB_GLUE_BASE = librte_pmd_mlx5_glue.so\n-LIB_GLUE_VERSION = 19.02.0\n+LIB_GLUE_VERSION = 19.05.0\n \n # Sources.\n SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5.c\ndiff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build\nindex a429655..a4c684e 100644\n--- a/drivers/net/mlx5/meson.build\n+++ b/drivers/net/mlx5/meson.build\n@@ -4,7 +4,7 @@\n \n pmd_dlopen = (get_option('ibverbs_link') == 'dlopen')\n LIB_GLUE_BASE = 'librte_pmd_mlx5_glue.so'\n-LIB_GLUE_VERSION = '19.02.0'\n+LIB_GLUE_VERSION = '19.05.0'\n LIB_GLUE = LIB_GLUE_BASE + '.' + LIB_GLUE_VERSION\n if pmd_dlopen\n \tdpdk_conf.set('RTE_IBVERBS_LINK_DLOPEN', 1)\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 47a7d75..784bf9b 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -309,6 +309,8 @@ struct mlx5_priv {\n \tLIST_HEAD(matchers, mlx5_flow_dv_matcher) matchers;\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+\t/* Tags resources cache. */\n \tuint32_t link_speed_capa; /* Link speed capabilities. */\n \tstruct mlx5_xstats_ctrl xstats_ctrl; /* Extended stats control. */\n \tstruct mlx5_stats_ctrl stats_ctrl; /* Stats control. */\ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex e1e798b..4f69ae2 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -214,7 +214,7 @@ struct mlx5_flow_dv_encap_decap_resource {\n \tLIST_ENTRY(mlx5_flow_dv_encap_decap_resource) next;\n \t/* Pointer to next element. */\n \trte_atomic32_t refcnt; /**< Reference counter. */\n-\tstruct ibv_flow_action *verbs_action;\n+\tvoid *verbs_action;\n \t/**< Verbs encap/decap action object. */\n \tuint8_t buf[MLX5_ENCAP_MAX_LEN];\n \tsize_t size;\n@@ -222,6 +222,16 @@ struct mlx5_flow_dv_encap_decap_resource {\n \tuint8_t ft_type;\n };\n \n+/* Tag resource structure. */\n+struct mlx5_flow_dv_tag_resource {\n+\tLIST_ENTRY(mlx5_flow_dv_tag_resource) next;\n+\t/* Pointer to next element. */\n+\trte_atomic32_t refcnt; /**< Reference counter. */\n+\tvoid *action;\n+\t/**< Verbs tag action object. */\n+\tuint32_t tag; /**< the tag value. */\n+};\n+\n /* Number of modification commands. */\n #define MLX5_MODIFY_NUM 8\n \n@@ -259,7 +269,7 @@ struct mlx5_flow_dv {\n \t/**< Pointer to modify header resource in cache. */\n \tstruct ibv_flow *flow; /**< Installed flow. */\n #ifdef HAVE_IBV_FLOW_DV_SUPPORT\n-\tstruct mlx5dv_flow_action_attr actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS];\n+\tvoid *actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS];\n \t/**< Action list. */\n #endif\n \tint actions_n; /**< number of actions. */\n@@ -332,6 +342,7 @@ struct mlx5_flow_counter {\n \t};\n \tuint64_t hits; /**< Number of packets matched by the rule. */\n \tuint64_t bytes; /**< Number of bytes matched by the rule. */\n+\tvoid *action; /**< Pointer to the dv action. */\n };\n \n /* Flow structure. */\n@@ -339,6 +350,8 @@ struct rte_flow {\n \tTAILQ_ENTRY(rte_flow) next; /**< Pointer to the next flow structure. */\n \tenum mlx5_flow_drv_type drv_type; /**< Drvier type. */\n \tstruct mlx5_flow_counter *counter; /**< Holds flow counter. */\n+\tstruct mlx5_flow_dv_tag_resource *tag_resource;\n+\t/**< pointer to the tag action. */\n \tstruct rte_flow_action_rss rss;/**< RSS context. */\n \tuint8_t key[MLX5_RSS_HASH_KEY_LEN]; /**< RSS hash key. */\n \tuint16_t (*queue)[]; /**< Destination queues to redirect traffic to. */\ndiff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c\nindex ad84dea..d9e2ac9 100644\n--- a/drivers/net/mlx5/mlx5_flow_dv.c\n+++ b/drivers/net/mlx5/mlx5_flow_dv.c\n@@ -32,7 +32,6 @@\n #include \"mlx5_prm.h\"\n #include \"mlx5_glue.h\"\n #include \"mlx5_flow.h\"\n-\n #ifdef HAVE_IBV_FLOW_DV_SUPPORT\n \n #ifndef HAVE_IBV_FLOW_DEVX_COUNTERS\n@@ -1537,6 +1536,11 @@ struct field_modify_info modify_tcp[] = {\n \t\t.id = id,\n \t\t.dcs = dcs,\n \t};\n+\ttmpl.action = mlx5_glue->dv_create_flow_action_counter(dcs->obj, 0);\n+\tif (!tmpl.action) {\n+\t\tret = errno;\n+\t\tgoto error_exit;\n+\t}\n \t*cnt = tmpl;\n \tLIST_INSERT_HEAD(&priv->flow_counters, cnt, next);\n \treturn cnt;\n@@ -2828,6 +2832,97 @@ struct field_modify_info modify_tcp[] = {\n }\n \n /**\n+ * Find existing tag 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 tag 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_tag_resource_register\n+\t\t\t(struct rte_eth_dev *dev,\n+\t\t\t struct mlx5_flow_dv_tag_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_tag_resource *cache_resource;\n+\n+\t/* Lookup a matching resource from cache. */\n+\tLIST_FOREACH(cache_resource, &priv->tags, next) {\n+\t\tif (resource->tag == cache_resource->tag) {\n+\t\t\tDRV_LOG(DEBUG, \"tag 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->flow->tag_resource = cache_resource;\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\t/* Register new  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 = mlx5_glue->dv_create_flow_action_tag\n+\t\t(resource->tag);\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->tags, cache_resource, next);\n+\tdev_flow->flow->tag_resource = cache_resource;\n+\tDRV_LOG(DEBUG, \"new tag 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+ * Release the tag.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device.\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_tag_release(struct rte_eth_dev *dev,\n+\t\t    struct mlx5_flow_dv_tag_resource *tag)\n+{\n+\tassert(tag);\n+\tDRV_LOG(DEBUG, \"port %u tag %p: refcnt %d--\",\n+\t\tdev->data->port_id, (void *)tag,\n+\t\trte_atomic32_read(&tag->refcnt));\n+\tif (rte_atomic32_dec_and_test(&tag->refcnt)) {\n+\t\tclaim_zero(mlx5_glue->destroy_flow_action(tag->action));\n+\t\tLIST_REMOVE(tag, next);\n+\t\tDRV_LOG(DEBUG, \"port %u tag %p: removed\",\n+\t\t\tdev->data->port_id, (void *)tag);\n+\t\trte_free(tag);\n+\t\treturn 0;\n+\t}\n+\treturn 1;\n+}\n+\n+/**\n  * Fill the flow with DV spec.\n  *\n  * @param[in] dev\n@@ -2872,6 +2967,7 @@ struct field_modify_info modify_tcp[] = {\n \t\t\t\t\t  MLX5DV_FLOW_TABLE_TYPE_NIC_RX\n \t};\n \tunion flow_dv_attr flow_attr = { .attr = 0 };\n+\tstruct mlx5_flow_dv_tag_resource tag_resource;\n \n \tif (priority == MLX5_FLOW_PRIO_RSVD)\n \t\tpriority = priv->config.flow_prio - 1;\n@@ -2886,26 +2982,29 @@ struct field_modify_info modify_tcp[] = {\n \t\tcase RTE_FLOW_ACTION_TYPE_VOID:\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_FLAG:\n-\t\t\tdev_flow->dv.actions[actions_n].type =\n-\t\t\t\tMLX5DV_FLOW_ACTION_TAG;\n-\t\t\tdev_flow->dv.actions[actions_n].tag_value =\n+\t\t\ttag_resource.tag =\n \t\t\t\tmlx5_flow_mark_set(MLX5_FLOW_MARK_DEFAULT);\n-\t\t\tactions_n++;\n+\t\t\tif (!flow->tag_resource)\n+\t\t\t\tif (flow_dv_tag_resource_register\n+\t\t\t\t    (dev, &tag_resource, dev_flow, error))\n+\t\t\t\t\treturn errno;\n+\t\t\tdev_flow->dv.actions[actions_n++] =\n+\t\t\t\tflow->tag_resource->action;\n \t\t\taction_flags |= MLX5_FLOW_ACTION_FLAG;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_MARK:\n-\t\t\tdev_flow->dv.actions[actions_n].type =\n-\t\t\t\tMLX5DV_FLOW_ACTION_TAG;\n-\t\t\tdev_flow->dv.actions[actions_n].tag_value =\n-\t\t\t\tmlx5_flow_mark_set\n-\t\t\t\t(((const struct rte_flow_action_mark *)\n-\t\t\t\t  (actions->conf))->id);\n-\t\t\tactions_n++;\n+\t\t\ttag_resource.tag = mlx5_flow_mark_set\n+\t\t\t      (((const struct rte_flow_action_mark *)\n+\t\t\t       (actions->conf))->id);\n+\t\t\tif (!flow->tag_resource)\n+\t\t\t\tif (flow_dv_tag_resource_register\n+\t\t\t\t    (dev, &tag_resource, dev_flow, error))\n+\t\t\t\t\treturn errno;\n+\t\t\tdev_flow->dv.actions[actions_n++] =\n+\t\t\t\tflow->tag_resource->action;\n \t\t\taction_flags |= MLX5_FLOW_ACTION_MARK;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_DROP:\n-\t\t\tdev_flow->dv.actions[actions_n].type =\n-\t\t\t\tMLX5DV_FLOW_ACTION_DROP;\n \t\t\taction_flags |= MLX5_FLOW_ACTION_DROP;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_QUEUE:\n@@ -2933,17 +3032,13 @@ struct field_modify_info modify_tcp[] = {\n \t\t\t\trte_errno = ENOTSUP;\n \t\t\t\tgoto cnt_err;\n \t\t\t}\n-\t\t\tflow->counter =\n-\t\t\t\tflow_dv_counter_new(dev,\n-\t\t\t\t\t\t    count->shared, count->id);\n+\t\t\tflow->counter = flow_dv_counter_new(dev, count->shared,\n+\t\t\t\t\t\t\t    count->id);\n \t\t\tif (flow->counter == NULL)\n \t\t\t\tgoto cnt_err;\n-\t\t\tdev_flow->dv.actions[actions_n].type =\n-\t\t\t\t\tMLX5DV_FLOW_ACTION_COUNTERS_DEVX;\n-\t\t\tdev_flow->dv.actions[actions_n].obj =\n-\t\t\t\t\t\tflow->counter->dcs->obj;\n+\t\t\tdev_flow->dv.actions[actions_n++] =\n+\t\t\t\tflow->counter->action;\n \t\t\taction_flags |= MLX5_FLOW_ACTION_COUNT;\n-\t\t\t++actions_n;\n \t\t\tbreak;\n cnt_err:\n \t\t\tif (rte_errno == ENOTSUP)\n@@ -2964,11 +3059,8 @@ struct field_modify_info modify_tcp[] = {\n \t\t\tif (flow_dv_create_action_l2_encap(dev, actions,\n \t\t\t\t\t\t\t   dev_flow, error))\n \t\t\t\treturn -rte_errno;\n-\t\t\tdev_flow->dv.actions[actions_n].type =\n-\t\t\t\tMLX5DV_FLOW_ACTION_IBV_FLOW_ACTION;\n-\t\t\tdev_flow->dv.actions[actions_n].action =\n+\t\t\tdev_flow->dv.actions[actions_n++] =\n \t\t\t\tdev_flow->dv.encap_decap->verbs_action;\n-\t\t\tactions_n++;\n \t\t\taction_flags |= actions->type ==\n \t\t\t\t\tRTE_FLOW_ACTION_TYPE_VXLAN_ENCAP ?\n \t\t\t\t\tMLX5_FLOW_ACTION_VXLAN_ENCAP :\n@@ -2979,11 +3071,8 @@ struct field_modify_info modify_tcp[] = {\n \t\t\tif (flow_dv_create_action_l2_decap(dev, dev_flow,\n \t\t\t\t\t\t\t   error))\n \t\t\t\treturn -rte_errno;\n-\t\t\tdev_flow->dv.actions[actions_n].type =\n-\t\t\t\tMLX5DV_FLOW_ACTION_IBV_FLOW_ACTION;\n-\t\t\tdev_flow->dv.actions[actions_n].action =\n+\t\t\tdev_flow->dv.actions[actions_n++] =\n \t\t\t\tdev_flow->dv.encap_decap->verbs_action;\n-\t\t\tactions_n++;\n \t\t\taction_flags |= actions->type ==\n \t\t\t\t\tRTE_FLOW_ACTION_TYPE_VXLAN_DECAP ?\n \t\t\t\t\tMLX5_FLOW_ACTION_VXLAN_DECAP :\n@@ -2995,9 +3084,7 @@ struct field_modify_info modify_tcp[] = {\n \t\t\t\tif (flow_dv_create_action_raw_encap\n \t\t\t\t\t(dev, actions, dev_flow, attr, error))\n \t\t\t\t\treturn -rte_errno;\n-\t\t\t\tdev_flow->dv.actions[actions_n].type =\n-\t\t\t\t\tMLX5DV_FLOW_ACTION_IBV_FLOW_ACTION;\n-\t\t\t\tdev_flow->dv.actions[actions_n].action =\n+\t\t\t\tdev_flow->dv.actions[actions_n++] =\n \t\t\t\t\tdev_flow->dv.encap_decap->verbs_action;\n \t\t\t} else {\n \t\t\t\t/* Handle encap without preceding decap. */\n@@ -3005,12 +3092,9 @@ struct field_modify_info modify_tcp[] = {\n \t\t\t\t\t\t\t\t   dev_flow,\n \t\t\t\t\t\t\t\t   error))\n \t\t\t\t\treturn -rte_errno;\n-\t\t\t\tdev_flow->dv.actions[actions_n].type =\n-\t\t\t\t\tMLX5DV_FLOW_ACTION_IBV_FLOW_ACTION;\n-\t\t\t\tdev_flow->dv.actions[actions_n].action =\n+\t\t\t\tdev_flow->dv.actions[actions_n++] =\n \t\t\t\t\tdev_flow->dv.encap_decap->verbs_action;\n \t\t\t}\n-\t\t\tactions_n++;\n \t\t\taction_flags |= MLX5_FLOW_ACTION_RAW_ENCAP;\n \t\t\tbreak;\n \t\tcase RTE_FLOW_ACTION_TYPE_RAW_DECAP:\n@@ -3025,11 +3109,8 @@ struct field_modify_info modify_tcp[] = {\n \t\t\t\t\t\t\t\t   dev_flow,\n \t\t\t\t\t\t\t\t   error))\n \t\t\t\t\treturn -rte_errno;\n-\t\t\t\tdev_flow->dv.actions[actions_n].type =\n-\t\t\t\t\tMLX5DV_FLOW_ACTION_IBV_FLOW_ACTION;\n-\t\t\t\tdev_flow->dv.actions[actions_n].action =\n+\t\t\t\tdev_flow->dv.actions[actions_n++] =\n \t\t\t\t\tdev_flow->dv.encap_decap->verbs_action;\n-\t\t\t\tactions_n++;\n \t\t\t}\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@@ -3098,11 +3179,8 @@ struct field_modify_info modify_tcp[] = {\n \t\t\t\t\t\t\t\t dev_flow,\n \t\t\t\t\t\t\t\t error))\n \t\t\t\t\treturn -rte_errno;\n-\t\t\t\tdev_flow->dv.actions[actions_n].type =\n-\t\t\t\t\tMLX5DV_FLOW_ACTION_IBV_FLOW_ACTION;\n-\t\t\t\tdev_flow->dv.actions[actions_n].action =\n+\t\t\t\tdev_flow->dv.actions[actions_n++] =\n \t\t\t\t\tdev_flow->dv.modify_hdr->verbs_action;\n-\t\t\t\tactions_n++;\n \t\t\t}\n \t\t\tbreak;\n \t\tdefault:\n@@ -3277,9 +3355,9 @@ struct field_modify_info modify_tcp[] = {\n \t\t\t\t\t \"cannot get drop hash queue\");\n \t\t\t\tgoto error;\n \t\t\t}\n-\t\t\tdv->actions[n].type = MLX5DV_FLOW_ACTION_DEST_IBV_QP;\n-\t\t\tdv->actions[n].qp = dv->hrxq->qp;\n-\t\t\tn++;\n+\t\t\tdv->actions[n++] =\n+\t\t\t\tmlx5_glue->dv_create_flow_action_dest_ibv_qp\n+\t\t\t\t(dv->hrxq->qp);\n \t\t} else if (flow->actions &\n \t\t\t   (MLX5_FLOW_ACTION_QUEUE | MLX5_FLOW_ACTION_RSS)) {\n \t\t\tstruct mlx5_hrxq *hrxq;\n@@ -3304,9 +3382,9 @@ struct field_modify_info modify_tcp[] = {\n \t\t\t\tgoto error;\n \t\t\t}\n \t\t\tdv->hrxq = hrxq;\n-\t\t\tdv->actions[n].type = MLX5DV_FLOW_ACTION_DEST_IBV_QP;\n-\t\t\tdv->actions[n].qp = hrxq->qp;\n-\t\t\tn++;\n+\t\t\tdv->actions[n++] =\n+\t\t\t\tmlx5_glue->dv_create_flow_action_dest_ibv_qp\n+\t\t\t\t(dv->hrxq->qp);\n \t\t}\n \t\tdv->flow =\n \t\t\tmlx5_glue->dv_create_flow(dv->matcher->matcher_object,\n@@ -3484,6 +3562,10 @@ struct field_modify_info modify_tcp[] = {\n \t\tflow_dv_counter_release(flow->counter);\n \t\tflow->counter = NULL;\n \t}\n+\tif (flow->tag_resource) {\n+\t\tflow_dv_tag_release(dev, flow->tag_resource);\n+\t\tflow->tag_resource = NULL;\n+\t}\n \twhile (!LIST_EMPTY(&flow->dev_flows)) {\n \t\tdev_flow = LIST_FIRST(&flow->dev_flows);\n \t\tLIST_REMOVE(dev_flow, next);\ndiff --git a/drivers/net/mlx5/mlx5_glue.c b/drivers/net/mlx5/mlx5_glue.c\nindex c817d86..4b5aade 100644\n--- a/drivers/net/mlx5/mlx5_glue.c\n+++ b/drivers/net/mlx5/mlx5_glue.c\n@@ -175,10 +175,20 @@\n }\n \n static int\n-mlx5_glue_destroy_flow_action(struct ibv_flow_action *action)\n+mlx5_glue_destroy_flow_action(void *action)\n {\n #ifdef HAVE_IBV_FLOW_DV_SUPPORT\n-\treturn ibv_destroy_flow_action(action);\n+\tstruct mlx5dv_flow_action_attr *attr = action;\n+\tint res = 0;\n+\tswitch (attr->type) {\n+\tcase MLX5DV_FLOW_ACTION_TAG:\n+\t\tbreak;\n+\tdefault:\n+\t\tres = ibv_destroy_flow_action(attr->action);\n+\t\tbreak;\n+\t}\n+\tfree(action);\n+\treturn res;\n #else\n \t(void)action;\n \treturn ENOTSUP;\n@@ -430,16 +440,23 @@\n mlx5_glue_dv_create_flow(struct mlx5dv_flow_matcher *matcher,\n \t\t\t struct mlx5dv_flow_match_parameters *match_value,\n \t\t\t size_t num_actions,\n-\t\t\t struct mlx5dv_flow_action_attr *actions_attr)\n+\t\t\t void *actions[])\n {\n #ifdef HAVE_IBV_FLOW_DV_SUPPORT\n+\tstruct mlx5dv_flow_action_attr actions_attr[8];\n+\n+\tif (num_actions > 8)\n+\t\treturn NULL;\n+\tfor (size_t i = 0; i < num_actions; i++)\n+\t\tactions_attr[i] =\n+\t\t\t*((struct mlx5dv_flow_action_attr *)(actions[i]));\n \treturn mlx5dv_create_flow(matcher, match_value,\n \t\t\t\t  num_actions, actions_attr);\n #else\n \t(void)matcher;\n \t(void)match_value;\n \t(void)num_actions;\n-\t(void)actions_attr;\n+\t(void)actions;\n \treturn NULL;\n #endif\n }\n@@ -455,31 +472,45 @@\n #endif\n }\n \n-static struct ibv_flow_action *\n-mlx5_glue_dv_create_flow_action_packet_reformat\n-\t\t(struct ibv_context *ctx,\n-\t\t size_t data_sz,\n-\t\t void *data,\n-\t\t enum mlx5dv_flow_action_packet_reformat_type reformat_type,\n-\t\t enum mlx5dv_flow_table_type ft_type)\n+static void *\n+mlx5_glue_dv_create_flow_action_counter(void *counter_obj, uint32_t offset)\n {\n #ifdef HAVE_IBV_FLOW_DV_SUPPORT\n-\treturn mlx5dv_create_flow_action_packet_reformat(ctx,\n-\t\t\t\t\t\t\t data_sz,\n-\t\t\t\t\t\t\t data,\n-\t\t\t\t\t\t\t reformat_type,\n-\t\t\t\t\t\t\t ft_type);\n+\tstruct mlx5dv_flow_action_attr *action;\n+\n+\t(void)offset;\n+\taction = malloc(sizeof(*action));\n+\tif (!action)\n+\t\treturn NULL;\n+\taction->type = MLX5DV_FLOW_ACTION_COUNTERS_DEVX;\n+\taction->obj = counter_obj;\n+\treturn action;\n #else\n-\t(void)ctx;\n-\t(void)data_sz;\n-\t(void)data;\n-\t(void)reformat_type;\n-\t(void)ft_type;\n+\t(void)counter_obj;\n+\t(void)offset;\n \treturn NULL;\n #endif\n }\n \n-static struct ibv_flow_action *\n+static void *\n+mlx5_glue_dv_create_flow_action_dest_ibv_qp(void *qp)\n+{\n+#ifdef HAVE_IBV_FLOW_DV_SUPPORT\n+\tstruct mlx5dv_flow_action_attr *action;\n+\n+\taction = malloc(sizeof(*action));\n+\tif (!action)\n+\t\treturn NULL;\n+\taction->type = MLX5DV_FLOW_ACTION_DEST_IBV_QP;\n+\taction->obj = qp;\n+\treturn action;\n+#else\n+\t(void)qp;\n+\treturn NULL;\n+#endif\n+}\n+\n+static void *\n mlx5_glue_dv_create_flow_action_modify_header\n \t\t\t\t\t(struct ibv_context *ctx,\n \t\t\t\t\t size_t actions_sz,\n@@ -487,8 +518,15 @@\n \t\t\t\t\t enum mlx5dv_flow_table_type ft_type)\n {\n #ifdef HAVE_IBV_FLOW_DV_SUPPORT\n-\treturn mlx5dv_create_flow_action_modify_header(ctx, actions_sz,\n-\t\t\t\t\t\t       actions, ft_type);\n+\tstruct mlx5dv_flow_action_attr *action;\n+\n+\taction = malloc(sizeof(*action));\n+\tif (!action)\n+\t\treturn NULL;\n+\taction->type = MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION;\n+\taction->action = mlx5dv_create_flow_action_modify_header\n+\t\t(ctx, actions_sz, actions, ft_type);\n+\treturn action;\n #else\n \t(void)ctx;\n \t(void)actions_sz;\n@@ -498,6 +536,50 @@\n #endif\n }\n \n+static void *\n+mlx5_glue_dv_create_flow_action_packet_reformat\n+\t\t(struct ibv_context *ctx,\n+\t\t size_t data_sz,\n+\t\t void *data,\n+\t\t enum mlx5dv_flow_action_packet_reformat_type reformat_type,\n+\t\t enum mlx5dv_flow_table_type ft_type)\n+{\n+#ifdef HAVE_IBV_FLOW_DV_SUPPORT\n+\tstruct mlx5dv_flow_action_attr *action;\n+\n+\taction = malloc(sizeof(*action));\n+\tif (!action)\n+\t\treturn NULL;\n+\taction->type = MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION;\n+\taction->action = mlx5dv_create_flow_action_packet_reformat\n+\t\t(ctx, data_sz, data, reformat_type, ft_type);\n+\treturn action;\n+#else\n+\t(void)ctx;\n+\t(void)data_sz;\n+\t(void)data;\n+\t(void)reformat_type;\n+\t(void)ft_type;\n+\treturn NULL;\n+#endif\n+}\n+\n+static void *\n+mlx5_glue_dv_create_flow_action_tag(uint32_t tag)\n+{\n+#ifdef HAVE_IBV_FLOW_DV_SUPPORT\n+\tstruct mlx5dv_flow_action_attr *action;\n+\taction = malloc(sizeof(*action));\n+\tif (!action)\n+\t\treturn NULL;\n+\taction->type = MLX5DV_FLOW_ACTION_TAG;\n+\taction->tag_value = tag;\n+\treturn action;\n+#endif\n+\t(void)tag;\n+\treturn NULL;\n+}\n+\n static struct ibv_context *\n mlx5_glue_dv_open_device(struct ibv_device *device)\n {\n@@ -645,10 +727,15 @@\n \t.dv_create_flow_matcher = mlx5_glue_dv_create_flow_matcher,\n \t.dv_destroy_flow_matcher = mlx5_glue_dv_destroy_flow_matcher,\n \t.dv_create_flow = mlx5_glue_dv_create_flow,\n-\t.dv_create_flow_action_packet_reformat =\n-\t\t\tmlx5_glue_dv_create_flow_action_packet_reformat,\n+\t.dv_create_flow_action_counter =\n+\t\tmlx5_glue_dv_create_flow_action_counter,\n+\t.dv_create_flow_action_dest_ibv_qp =\n+\t\tmlx5_glue_dv_create_flow_action_dest_ibv_qp,\n \t.dv_create_flow_action_modify_header =\n-\t\t\tmlx5_glue_dv_create_flow_action_modify_header,\n+\t\tmlx5_glue_dv_create_flow_action_modify_header,\n+\t.dv_create_flow_action_packet_reformat =\n+\t\tmlx5_glue_dv_create_flow_action_packet_reformat,\n+\t.dv_create_flow_action_tag =  mlx5_glue_dv_create_flow_action_tag,\n \t.dv_open_device = mlx5_glue_dv_open_device,\n \t.devx_obj_create = mlx5_glue_devx_obj_create,\n \t.devx_obj_destroy = mlx5_glue_devx_obj_destroy,\ndiff --git a/drivers/net/mlx5/mlx5_glue.h b/drivers/net/mlx5/mlx5_glue.h\nindex b118960..32487ea 100644\n--- a/drivers/net/mlx5/mlx5_glue.h\n+++ b/drivers/net/mlx5/mlx5_glue.h\n@@ -55,6 +55,10 @@\n enum mlx5dv_flow_table_type { flow_table_type = 0, };\n #endif\n \n+#ifndef HAVE_IBV_FLOW_DEVX_COUNTERS\n+#define MLX5DV_FLOW_ACTION_COUNTERS_DEVX 0\n+#endif\n+\n #ifndef HAVE_IBV_DEVX_OBJ\n struct mlx5dv_devx_obj;\n #endif\n@@ -98,7 +102,7 @@ struct mlx5_glue {\n \tstruct ibv_flow *(*create_flow)(struct ibv_qp *qp,\n \t\t\t\t\tstruct ibv_flow_attr *flow);\n \tint (*destroy_flow)(struct ibv_flow *flow_id);\n-\tint (*destroy_flow_action)(struct ibv_flow_action *action);\n+\tint (*destroy_flow_action)(void *action);\n \tstruct ibv_qp *(*create_qp)(struct ibv_pd *pd,\n \t\t\t\t    struct ibv_qp_init_attr *qp_init_attr);\n \tstruct ibv_qp *(*create_qp_ex)\n@@ -160,19 +164,17 @@ struct mlx5_glue {\n \tint (*dv_destroy_flow_matcher)(struct mlx5dv_flow_matcher *matcher);\n \tstruct ibv_flow *(*dv_create_flow)(struct mlx5dv_flow_matcher *matcher,\n \t\t\t  struct mlx5dv_flow_match_parameters *match_value,\n-\t\t\t  size_t num_actions,\n-\t\t\t  struct mlx5dv_flow_action_attr *actions_attr);\n-\tstruct ibv_flow_action *(*dv_create_flow_action_packet_reformat)\n-\t\t(struct ibv_context *ctx,\n-\t\t size_t data_sz,\n-\t\t void *data,\n+\t\t\t  size_t num_actions, void *actions[]);\n+\tvoid *(*dv_create_flow_action_counter)(void *obj, uint32_t  offset);\n+\tvoid *(*dv_create_flow_action_dest_ibv_qp)(void *qp);\n+\tvoid *(*dv_create_flow_action_modify_header)\n+\t\t(struct ibv_context *ctx, size_t actions_sz, uint64_t actions[],\n+\t\t enum mlx5dv_flow_table_type ft_type);\n+\tvoid *(*dv_create_flow_action_packet_reformat)\n+\t\t(struct ibv_context *ctx, size_t data_sz, void *data,\n \t\t enum mlx5dv_flow_action_packet_reformat_type reformat_type,\n \t\t enum mlx5dv_flow_table_type ft_type);\n-\tstruct ibv_flow_action *(*dv_create_flow_action_modify_header)\n-\t\t\t\t\t(struct ibv_context *ctx,\n-\t\t\t\t\t size_t actions_sz,\n-\t\t\t\t\t uint64_t actions[],\n-\t\t\t\t\t enum mlx5dv_flow_table_type ft_type);\n+\tvoid *(*dv_create_flow_action_tag)(uint32_t tag);\n \tstruct ibv_context *(*dv_open_device)(struct ibv_device *device);\n \tstruct mlx5dv_devx_obj *(*devx_obj_create)\n \t\t\t\t\t(struct ibv_context *ctx,\n",
    "prefixes": [
        "v4",
        "1/3"
    ]
}