get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 68601,
    "url": "http://patches.dpdk.org/api/patches/68601/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1587004928-328077-11-git-send-email-suanmingm@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": "<1587004928-328077-11-git-send-email-suanmingm@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1587004928-328077-11-git-send-email-suanmingm@mellanox.com",
    "date": "2020-04-16T02:42:08",
    "name": "[v2,10/10] net/mlx5: convert flow dev handle to indexed",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "5ca9124161c83d33cabe2baeb270c099062eb41e",
    "submitter": {
        "id": 1358,
        "url": "http://patches.dpdk.org/api/people/1358/?format=api",
        "name": "Suanming Mou",
        "email": "suanmingm@mellanox.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/1587004928-328077-11-git-send-email-suanmingm@mellanox.com/mbox/",
    "series": [
        {
            "id": 9407,
            "url": "http://patches.dpdk.org/api/series/9407/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=9407",
            "date": "2020-04-16T02:41:58",
            "name": "net/mlx5: optimize flow resource allocation",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/9407/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/68601/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/68601/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 42F76A0588;\n\tThu, 16 Apr 2020 04:43:59 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 401A81DA4E;\n\tThu, 16 Apr 2020 04:42:40 +0200 (CEST)",
            "from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130])\n by dpdk.org (Postfix) with ESMTP id 71B391DA02\n for <dev@dpdk.org>; Thu, 16 Apr 2020 04:42:31 +0200 (CEST)"
        ],
        "From": "Suanming Mou <suanmingm@mellanox.com>",
        "To": "viacheslavo@mellanox.com,\n\tmatan@mellanox.com",
        "Cc": "rasland@mellanox.com,\n\tdev@dpdk.org",
        "Date": "Thu, 16 Apr 2020 10:42:08 +0800",
        "Message-Id": "<1587004928-328077-11-git-send-email-suanmingm@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1587004928-328077-1-git-send-email-suanmingm@mellanox.com>",
        "References": "<1586740309-449310-1-git-send-email-suanmingm@mellanox.com>\n <1587004928-328077-1-git-send-email-suanmingm@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH v2 10/10] net/mlx5: convert flow dev handle to\n\tindexed",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This commit converts flow dev handle to indexed.\n\nChange the mlx5 flow handle from pointer to uint32_t saves memory for\nflow. With million flow, it saves several MBytes memory.\n\nSigned-off-by: Suanming Mou <suanmingm@mellanox.com>\nAcked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>\n---\n drivers/net/mlx5/mlx5.c            | 30 ++++++++++++++++++++++++++++--\n drivers/net/mlx5/mlx5.h            |  3 +++\n drivers/net/mlx5/mlx5_flow.c       | 23 +++++++++++++++++------\n drivers/net/mlx5/mlx5_flow.h       |  7 ++++---\n drivers/net/mlx5/mlx5_flow_dv.c    | 35 +++++++++++++++++++++++++++--------\n drivers/net/mlx5/mlx5_flow_verbs.c | 29 ++++++++++++++++++++++-------\n 6 files changed, 101 insertions(+), 26 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex dda5f72..331318a 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -199,6 +199,7 @@ struct mlx5_dev_spawn_data {\n static pthread_mutex_t mlx5_ibv_list_mutex = PTHREAD_MUTEX_INITIALIZER;\n \n static struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = {\n+#ifdef HAVE_IBV_FLOW_DV_SUPPORT\n \t{\n \t\t.size = sizeof(struct mlx5_flow_dv_encap_decap_resource),\n \t\t.trunk_size = 64,\n@@ -254,6 +255,7 @@ struct mlx5_dev_spawn_data {\n \t\t.free = rte_free,\n \t\t.type = \"mlx5_jump_ipool\",\n \t},\n+#endif\n \t{\n \t\t.size = (sizeof(struct mlx5_hrxq) + MLX5_RSS_HASH_KEY_LEN),\n \t\t.trunk_size = 64,\n@@ -265,6 +267,17 @@ struct mlx5_dev_spawn_data {\n \t\t.free = rte_free,\n \t\t.type = \"mlx5_jump_ipool\",\n \t},\n+\t{\n+\t\t.size = sizeof(struct mlx5_flow_handle),\n+\t\t.trunk_size = 64,\n+\t\t.grow_trunk = 3,\n+\t\t.grow_shift = 2,\n+\t\t.need_lock = 0,\n+\t\t.release_mem_en = 1,\n+\t\t.malloc = rte_malloc_socket,\n+\t\t.free = rte_free,\n+\t\t.type = \"mlx5_flow_handle_ipool\",\n+\t},\n };\n \n \n@@ -491,12 +504,25 @@ struct mlx5_flow_id_pool *\n  *\n  * @param[in] sh\n  *   Pointer to mlx5_ibv_shared object.\n+ * @param[in] sh\n+ *   Pointer to user dev config.\n  */\n static void\n-mlx5_flow_ipool_create(struct mlx5_ibv_shared *sh)\n+mlx5_flow_ipool_create(struct mlx5_ibv_shared *sh,\n+\t\t       const struct mlx5_dev_config *config __rte_unused)\n {\n \tuint8_t i;\n \n+#ifdef HAVE_IBV_FLOW_DV_SUPPORT\n+\t/*\n+\t * While DV is supported, user chooses the verbs mode,\n+\t * the mlx5 flow handle size is different with the\n+\t * MLX5_FLOW_HANDLE_VERBS_SIZE.\n+\t */\n+\tif (!config->dv_flow_en)\n+\t\tmlx5_ipool_cfg[MLX5_IPOOL_MLX5_FLOW].size =\n+\t\t\t\t\tMLX5_FLOW_HANDLE_VERBS_SIZE;\n+#endif\n \tfor (i = 0; i < MLX5_IPOOL_MAX; ++i)\n \t\tsh->ipool[i] = mlx5_ipool_create(&mlx5_ipool_cfg[i]);\n }\n@@ -731,7 +757,7 @@ struct mlx5_flow_id_pool *\n \t\tgoto error;\n \t}\n \tmlx5_flow_counters_mng_init(sh);\n-\tmlx5_flow_ipool_create(sh);\n+\tmlx5_flow_ipool_create(sh, config);\n \t/* Add device to memory callback list. */\n \trte_rwlock_write_lock(&mlx5_shared_data->mem_event_rwlock);\n \tLIST_INSERT_HEAD(&mlx5_shared_data->mem_event_cb_list,\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 37ff4a0..2c4e823 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -45,12 +45,15 @@\n \n \n enum mlx5_ipool_index {\n+#ifdef HAVE_IBV_FLOW_DV_SUPPORT\n \tMLX5_IPOOL_DECAP_ENCAP = 0, /* Pool for encap/decap resource. */\n \tMLX5_IPOOL_PUSH_VLAN, /* Pool for push vlan resource. */\n \tMLX5_IPOOL_TAG, /* Pool for tag resource. */\n \tMLX5_IPOOL_PORT_ID, /* Pool for port id resource. */\n \tMLX5_IPOOL_JUMP, /* Pool for jump resource. */\n+#endif\n \tMLX5_IPOOL_HRXQ, /* Pool for hrxq resource. */\n+\tMLX5_IPOOL_MLX5_FLOW, /* Pool for mlx5 flow handle. */\n \tMLX5_IPOOL_MAX,\n };\n \ndiff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c\nindex c44bc1f..bf95a40 100644\n--- a/drivers/net/mlx5/mlx5_flow.c\n+++ b/drivers/net/mlx5/mlx5_flow.c\n@@ -775,9 +775,12 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,\n static void\n flow_rxq_flags_set(struct rte_eth_dev *dev, struct rte_flow *flow)\n {\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tuint32_t handle_idx;\n \tstruct mlx5_flow_handle *dev_handle;\n \n-\tLIST_FOREACH(dev_handle, &flow->dev_handles, next)\n+\tSILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW], flow->dev_handles,\n+\t\t       handle_idx, dev_handle, next)\n \t\tflow_drv_rxq_flags_set(dev, flow, dev_handle);\n }\n \n@@ -847,9 +850,12 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,\n static void\n flow_rxq_flags_trim(struct rte_eth_dev *dev, struct rte_flow *flow)\n {\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tuint32_t handle_idx;\n \tstruct mlx5_flow_handle *dev_handle;\n \n-\tLIST_FOREACH(dev_handle, &flow->dev_handles, next)\n+\tSILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW], flow->dev_handles,\n+\t\t       handle_idx, dev_handle, next)\n \t\tflow_drv_rxq_flags_trim(dev, flow, dev_handle);\n }\n \n@@ -2313,9 +2319,12 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,\n flow_mreg_split_qrss_release(struct rte_eth_dev *dev,\n \t\t\t     struct rte_flow *flow)\n {\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tuint32_t handle_idx;\n \tstruct mlx5_flow_handle *dev_handle;\n \n-\tLIST_FOREACH(dev_handle, &flow->dev_handles, next)\n+\tSILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW], flow->dev_handles,\n+\t\t       handle_idx, dev_handle, next)\n \t\tif (dev_handle->qrss_id)\n \t\t\tflow_qrss_free_id(dev, dev_handle->qrss_id);\n }\n@@ -3459,7 +3468,8 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,\n \tdev_flow->flow = flow;\n \tdev_flow->external = external;\n \t/* Subflow object was created, we must include one in the list. */\n-\tLIST_INSERT_HEAD(&flow->dev_handles, dev_flow->handle, next);\n+\tSILIST_INSERT(&flow->dev_handles, dev_flow->handle_idx,\n+\t\t      dev_flow->handle, next);\n \t/*\n \t * If dev_flow is as one of the suffix flow, some actions in suffix\n \t * flow may need some user defined item layer flags.\n@@ -4264,7 +4274,7 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,\n \t\t/* RSS type 0 indicates default RSS type (ETH_RSS_IP). */\n \t\tflow->rss.types = !rss->types ? ETH_RSS_IP : rss->types;\n \t}\n-\tLIST_INIT(&flow->dev_handles);\n+\tflow->dev_handles = 0;\n \tif (rss && rss->types) {\n \t\tunsigned int graph_root;\n \n@@ -4312,7 +4322,8 @@ uint32_t mlx5_flow_adjust_priority(struct rte_eth_dev *dev, int32_t priority,\n \t\t\tgoto error;\n \t\tdev_flow->flow = flow;\n \t\tdev_flow->external = 0;\n-\t\tLIST_INSERT_HEAD(&flow->dev_handles, dev_flow->handle, next);\n+\t\tSILIST_INSERT(&flow->dev_handles, dev_flow->handle_idx,\n+\t\t\t      dev_flow->handle, next);\n \t\tret = flow_drv_translate(dev, dev_flow, &attr_tx,\n \t\t\t\t\t items_tx.items,\n \t\t\t\t\t actions_hairpin_tx.actions, error);\ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex 26f8704..a2ea122 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -502,8 +502,8 @@ struct mlx5_flow_handle_dv {\n \n /** Device flow handle structure: used both for creating & destroying. */\n struct mlx5_flow_handle {\n-\tLIST_ENTRY(mlx5_flow_handle) next;\n-\t/**< Pointer to next device flow handle. */\n+\tSILIST_ENTRY(uint32_t)next;\n+\t/**< Index to next device flow handle. */\n \tuint64_t layers;\n \t/**< Bit-fields of present layers, see MLX5_FLOW_LAYER_*. */\n \tuint64_t act_flags;\n@@ -632,6 +632,7 @@ struct mlx5_flow {\n \t\tstruct mlx5_flow_verbs_workspace verbs;\n \t};\n \tstruct mlx5_flow_handle *handle;\n+\tuint32_t handle_idx; /* Index of the mlx5 flow handle memory. */\n };\n \n /* Flow meter state. */\n@@ -747,7 +748,7 @@ struct rte_flow {\n \tstruct mlx5_flow_mreg_copy_resource *mreg_copy;\n \t/**< pointer to metadata register copy table resource. */\n \tstruct mlx5_flow_meter *meter; /**< Holds flow meter. */\n-\tLIST_HEAD(dev_handles, mlx5_flow_handle) dev_handles;\n+\tuint32_t dev_handles;\n \t/**< Device flow handles that are part of the flow. */\n \tstruct mlx5_fdir *fdir; /**< Pointer to associated FDIR if any. */\n \tuint32_t hairpin_flow_id; /**< The flow id used for hairpin. */\ndiff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c\nindex 5e6143b..f001b34 100644\n--- a/drivers/net/mlx5/mlx5_flow_dv.c\n+++ b/drivers/net/mlx5/mlx5_flow_dv.c\n@@ -5333,7 +5333,7 @@ struct field_modify_info modify_tcp[] = {\n \t\tconst struct rte_flow_action actions[] __rte_unused,\n \t\tstruct rte_flow_error *error)\n {\n-\tsize_t size = sizeof(struct mlx5_flow_handle);\n+\tuint32_t handle_idx = 0;\n \tstruct mlx5_flow *dev_flow;\n \tstruct mlx5_flow_handle *dev_handle;\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n@@ -5345,7 +5345,8 @@ struct field_modify_info modify_tcp[] = {\n \t\t\t\t   \"not free temporary device flow\");\n \t\treturn NULL;\n \t}\n-\tdev_handle = rte_calloc(__func__, 1, size, 0);\n+\tdev_handle = mlx5_ipool_zmalloc(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW],\n+\t\t\t\t   &handle_idx);\n \tif (!dev_handle) {\n \t\trte_flow_error_set(error, ENOMEM,\n \t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n@@ -5355,6 +5356,7 @@ struct field_modify_info modify_tcp[] = {\n \t/* No multi-thread supporting. */\n \tdev_flow = &((struct mlx5_flow *)priv->inter_flows)[priv->flow_idx++];\n \tdev_flow->handle = dev_handle;\n+\tdev_flow->handle_idx = handle_idx;\n \tdev_flow->dv.value.size = MLX5_ST_SZ_BYTES(fte_match_param);\n \t/*\n \t * The matching value needs to be cleared to 0 before using. In the\n@@ -8088,6 +8090,7 @@ struct field_modify_info modify_tcp[] = {\n \tstruct mlx5_flow_handle_dv *dv_h;\n \tstruct mlx5_flow *dev_flow;\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tuint32_t handle_idx;\n \tint n;\n \tint err;\n \tint idx;\n@@ -8172,7 +8175,8 @@ struct field_modify_info modify_tcp[] = {\n \treturn 0;\n error:\n \terr = rte_errno; /* Save rte_errno before cleanup. */\n-\tLIST_FOREACH(dh, &flow->dev_handles, next) {\n+\tSILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW], flow->dev_handles,\n+\t\t       handle_idx, dh, next) {\n \t\tif (dh->hrxq) {\n \t\t\tif (dh->act_flags & MLX5_FLOW_ACTION_DROP)\n \t\t\t\tmlx5_hrxq_drop_release(dev);\n@@ -8429,10 +8433,17 @@ struct field_modify_info modify_tcp[] = {\n __flow_dv_remove(struct rte_eth_dev *dev, struct rte_flow *flow)\n {\n \tstruct mlx5_flow_handle *dh;\n+\tuint32_t handle_idx;\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n \n \tif (!flow)\n \t\treturn;\n-\tLIST_FOREACH(dh, &flow->dev_handles, next) {\n+\thandle_idx = flow->dev_handles;\n+\twhile (handle_idx) {\n+\t\tdh = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW],\n+\t\t\t\t    handle_idx);\n+\t\tif (!dh)\n+\t\t\treturn;\n \t\tif (dh->ib_flow) {\n \t\t\tclaim_zero(mlx5_glue->dv_destroy_flow(dh->ib_flow));\n \t\t\tdh->ib_flow = NULL;\n@@ -8446,6 +8457,7 @@ struct field_modify_info modify_tcp[] = {\n \t\t}\n \t\tif (dh->vf_vlan.tag && dh->vf_vlan.created)\n \t\t\tmlx5_vlan_vmwa_release(dev, &dh->vf_vlan);\n+\t\thandle_idx = dh->next.next;\n \t}\n }\n \n@@ -8462,6 +8474,7 @@ struct field_modify_info modify_tcp[] = {\n __flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)\n {\n \tstruct mlx5_flow_handle *dev_handle;\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n \n \tif (!flow)\n \t\treturn;\n@@ -8474,9 +8487,14 @@ struct field_modify_info modify_tcp[] = {\n \t\tmlx5_flow_meter_detach(flow->meter);\n \t\tflow->meter = NULL;\n \t}\n-\twhile (!LIST_EMPTY(&flow->dev_handles)) {\n-\t\tdev_handle = LIST_FIRST(&flow->dev_handles);\n-\t\tLIST_REMOVE(dev_handle, next);\n+\twhile (flow->dev_handles) {\n+\t\tuint32_t tmp_idx = flow->dev_handles;\n+\n+\t\tdev_handle = mlx5_ipool_get(priv->sh->ipool\n+\t\t\t\t\t    [MLX5_IPOOL_MLX5_FLOW], tmp_idx);\n+\t\tif (!dev_handle)\n+\t\t\treturn;\n+\t\tflow->dev_handles = dev_handle->next.next;\n \t\tif (dev_handle->dvh.matcher)\n \t\t\tflow_dv_matcher_release(dev, dev_handle);\n \t\tif (dev_handle->dvh.encap_decap)\n@@ -8494,7 +8512,8 @@ struct field_modify_info modify_tcp[] = {\n \t\tif (dev_handle->dvh.tag_resource)\n \t\t\tflow_dv_tag_release(dev,\n \t\t\t\t\t    dev_handle->dvh.tag_resource);\n-\t\trte_free(dev_handle);\n+\t\tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW],\n+\t\t\t   tmp_idx);\n \t}\n }\n \ndiff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c\nindex aa55f4e..9525fd4 100644\n--- a/drivers/net/mlx5/mlx5_flow_verbs.c\n+++ b/drivers/net/mlx5/mlx5_flow_verbs.c\n@@ -1505,6 +1505,7 @@\n \t\t   struct rte_flow_error *error)\n {\n \tsize_t size = 0;\n+\tuint32_t handle_idx = 0;\n \tstruct mlx5_flow *dev_flow;\n \tstruct mlx5_flow_handle *dev_handle;\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n@@ -1524,7 +1525,8 @@\n \t\t\t\t   \"not free temporary device flow\");\n \t\treturn NULL;\n \t}\n-\tdev_handle = rte_calloc(__func__, 1, MLX5_FLOW_HANDLE_VERBS_SIZE, 0);\n+\tdev_handle = mlx5_ipool_zmalloc(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW],\n+\t\t\t\t   &handle_idx);\n \tif (!dev_handle) {\n \t\trte_flow_error_set(error, ENOMEM,\n \t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n@@ -1534,6 +1536,7 @@\n \t/* No multi-thread supporting. */\n \tdev_flow = &((struct mlx5_flow *)priv->inter_flows)[priv->flow_idx++];\n \tdev_flow->handle = dev_handle;\n+\tdev_flow->handle_idx = handle_idx;\n \t/* Memcpy is used, only size needs to be cleared to 0. */\n \tdev_flow->verbs.size = 0;\n \tdev_flow->verbs.attr.num_of_specs = 0;\n@@ -1739,11 +1742,14 @@\n static void\n flow_verbs_remove(struct rte_eth_dev *dev, struct rte_flow *flow)\n {\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n \tstruct mlx5_flow_handle *handle;\n+\tuint32_t handle_idx;\n \n \tif (!flow)\n \t\treturn;\n-\tLIST_FOREACH(handle, &flow->dev_handles, next) {\n+\tSILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW], flow->dev_handles,\n+\t\t       handle_idx, handle, next) {\n \t\tif (handle->ib_flow) {\n \t\t\tclaim_zero(mlx5_glue->destroy_flow(handle->ib_flow));\n \t\t\thandle->ib_flow = NULL;\n@@ -1771,15 +1777,22 @@\n static void\n flow_verbs_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)\n {\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n \tstruct mlx5_flow_handle *handle;\n \n \tif (!flow)\n \t\treturn;\n \tflow_verbs_remove(dev, flow);\n-\twhile (!LIST_EMPTY(&flow->dev_handles)) {\n-\t\thandle = LIST_FIRST(&flow->dev_handles);\n-\t\tLIST_REMOVE(handle, next);\n-\t\trte_free(handle);\n+\twhile (flow->dev_handles) {\n+\t\tuint32_t tmp_idx = flow->dev_handles;\n+\n+\t\thandle = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW],\n+\t\t\t\t   tmp_idx);\n+\t\tif (!handle)\n+\t\t\treturn;\n+\t\tflow->dev_handles = handle->next.next;\n+\t\tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW],\n+\t\t\t   tmp_idx);\n \t}\n \tif (flow->counter) {\n \t\tflow_verbs_counter_release(dev, flow->counter);\n@@ -1808,6 +1821,7 @@\n \tstruct mlx5_flow_handle *handle;\n \tstruct mlx5_flow *dev_flow;\n \tstruct mlx5_hrxq *hrxq;\n+\tuint32_t dev_handles;\n \tint err;\n \tint idx;\n \n@@ -1875,7 +1889,8 @@\n \treturn 0;\n error:\n \terr = rte_errno; /* Save rte_errno before cleanup. */\n-\tLIST_FOREACH(handle, &flow->dev_handles, next) {\n+\tSILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_MLX5_FLOW], flow->dev_handles,\n+\t\t       dev_handles, handle, next) {\n \t\tif (handle->hrxq) {\n \t\t\tif (handle->act_flags & MLX5_FLOW_ACTION_DROP)\n \t\t\t\tmlx5_hrxq_drop_release(dev);\n",
    "prefixes": [
        "v2",
        "10/10"
    ]
}