get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 79770,
    "url": "http://patches.dpdk.org/api/patches/79770/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1601984948-313027-17-git-send-email-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": "<1601984948-313027-17-git-send-email-suanmingm@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1601984948-313027-17-git-send-email-suanmingm@nvidia.com",
    "date": "2020-10-06T11:48:59",
    "name": "[16/25] net/mlx5: make Rx queue thread safe",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "60443cc9e80c85514f6102c128d6e3a50be00bb6",
    "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/1601984948-313027-17-git-send-email-suanmingm@nvidia.com/mbox/",
    "series": [
        {
            "id": 12718,
            "url": "http://patches.dpdk.org/api/series/12718/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=12718",
            "date": "2020-10-06T11:48:45",
            "name": "net/mlx5: support multiple-thread flow operations",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/12718/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/79770/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/79770/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 4DAA9A04BB;\n\tTue,  6 Oct 2020 13:55:15 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 62CA11BAA8;\n\tTue,  6 Oct 2020 13:49:49 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id 261871B9EC\n for <dev@dpdk.org>; Tue,  6 Oct 2020 13:49:45 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n suanmingm@nvidia.com) with SMTP; 6 Oct 2020 14:49:42 +0300",
            "from nvidia.com (mtbc-r640-04.mtbc.labs.mlnx [10.75.70.9])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 096BnC0a028553;\n Tue, 6 Oct 2020 14:49:41 +0300"
        ],
        "From": "Suanming Mou <suanmingm@nvidia.com>",
        "To": "viacheslavo@nvidia.com, matan@nvidia.com",
        "Cc": "rasland@nvidia.com, dev@dpdk.org",
        "Date": "Tue,  6 Oct 2020 19:48:59 +0800",
        "Message-Id": "<1601984948-313027-17-git-send-email-suanmingm@nvidia.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1601984948-313027-1-git-send-email-suanmingm@nvidia.com>",
        "References": "<1601984948-313027-1-git-send-email-suanmingm@nvidia.com>",
        "Subject": "[dpdk-dev] [PATCH 16/25] net/mlx5: make Rx queue thread safe",
        "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 applies the cache linked list to Rx queue to make it thread\nsafe.\n\nSigned-off-by: Suanming Mou <suanmingm@nvidia.com>\n---\n drivers/net/mlx5/linux/mlx5_os.c   |   5 +\n drivers/net/mlx5/mlx5.c            |   1 +\n drivers/net/mlx5/mlx5.h            |  24 +++-\n drivers/net/mlx5/mlx5_flow.h       |  16 ---\n drivers/net/mlx5/mlx5_flow_dv.c    |  20 +---\n drivers/net/mlx5/mlx5_flow_verbs.c |  19 +--\n drivers/net/mlx5/mlx5_rxq.c        | 234 ++++++++++++++++++-------------------\n drivers/net/mlx5/mlx5_rxtx.h       |  20 ++--\n 8 files changed, 164 insertions(+), 175 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c\nindex 24cf348..db7b0de 100644\n--- a/drivers/net/mlx5/linux/mlx5_os.c\n+++ b/drivers/net/mlx5/linux/mlx5_os.c\n@@ -1335,6 +1335,10 @@\n \t\t\terr = ENOTSUP;\n \t\t\tgoto error;\n \t}\n+\tmlx5_cache_list_init(&priv->hrxqs, \"hrxq\", 0, eth_dev,\n+\t\t\t     mlx5_hrxq_create_cb,\n+\t\t\t     mlx5_hrxq_match_cb,\n+\t\t\t     mlx5_hrxq_remove_cb);\n \t/* Query availability of metadata reg_c's. */\n \terr = mlx5_flow_discover_mreg_c(eth_dev);\n \tif (err < 0) {\n@@ -1381,6 +1385,7 @@\n \t\t\tmlx5_vlan_vmwa_exit(priv->vmwa_context);\n \t\tif (own_domain_id)\n \t\t\tclaim_zero(rte_eth_switch_domain_free(priv->domain_id));\n+\t\tmlx5_cache_list_destroy(&priv->hrxqs);\n \t\tmlx5_free(priv);\n \t\tif (eth_dev != NULL)\n \t\t\teth_dev->data->dev_private = NULL;\ndiff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex 61e5e69..fc9c5a9 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -1219,6 +1219,7 @@ struct mlx5_dev_ctx_shared *\n \t\tclose(priv->nl_socket_rdma);\n \tif (priv->vmwa_context)\n \t\tmlx5_vlan_vmwa_exit(priv->vmwa_context);\n+\tmlx5_cache_list_destroy(&priv->hrxqs);\n \tret = mlx5_hrxq_verify(dev);\n \tif (ret)\n \t\tDRV_LOG(WARNING, \"port %u some hash Rx queue still remain\",\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex f11d783..97729a8 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -61,6 +61,13 @@ enum mlx5_reclaim_mem_mode {\n \tMLX5_RCM_AGGR, /* Reclaim PMD and rdma-core level. */\n };\n \n+/* Hash list callback context */\n+struct mlx5_flow_cb_ctx {\n+\tstruct rte_eth_dev *dev;\n+\tstruct rte_flow_error *error;\n+\tvoid *data;\n+};\n+\n /* Device attributes used in mlx5 PMD */\n struct mlx5_dev_attr {\n \tuint64_t\tdevice_cap_flags_ex;\n@@ -664,6 +671,18 @@ struct mlx5_proc_priv {\n /* MTR list. */\n TAILQ_HEAD(mlx5_flow_meters, mlx5_flow_meter);\n \n+/* RSS description. */\n+struct mlx5_flow_rss_desc {\n+\tuint32_t level;\n+\tuint32_t queue_num; /**< Number of entries in @p queue. */\n+\tuint64_t types; /**< Specific RSS hash types (see ETH_RSS_*). */\n+\tuint64_t hash_fields; /* Verbs Hash fields. */\n+\tuint8_t key[MLX5_RSS_HASH_KEY_LEN]; /**< RSS hash key. */\n+\tuint32_t key_len; /**< RSS hash key len. */\n+\tuint32_t tunnel; /**< Queue in tunnel. */\n+\tuint16_t *queue; /**< Destination queues. */\n+};\n+\n #define MLX5_PROC_PRIV(port_id) \\\n \t((struct mlx5_proc_priv *)rte_eth_devices[port_id].process_private)\n \n@@ -710,7 +729,7 @@ struct mlx5_ind_table_obj {\n \n /* Hash Rx queue. */\n struct mlx5_hrxq {\n-\tILIST_ENTRY(uint32_t)next; /* Index to the next element. */\n+\tstruct mlx5_cache_entry entry; /* Cache entry. */\n \trte_atomic32_t refcnt; /* Reference counter. */\n \tstruct mlx5_ind_table_obj *ind_table; /* Indirection table. */\n \tRTE_STD_C11\n@@ -723,6 +742,7 @@ struct mlx5_hrxq {\n #endif\n \tuint64_t hash_fields; /* Verbs Hash fields. */\n \tuint32_t rss_key_len; /* Hash key length in bytes. */\n+\tuint32_t idx; /* Hash Rx queue index*/\n \tuint8_t rss_key[]; /* Hash key. */\n };\n \n@@ -788,7 +808,7 @@ struct mlx5_priv {\n \tstruct mlx5_obj_ops obj_ops; /* HW objects operations. */\n \tLIST_HEAD(rxq, mlx5_rxq_ctrl) rxqsctrl; /* DPDK Rx queues. */\n \tLIST_HEAD(rxqobj, mlx5_rxq_obj) rxqsobj; /* Verbs/DevX Rx queues. */\n-\tuint32_t hrxqs; /* Verbs Hash Rx queues. */\n+\tstruct mlx5_cache_list hrxqs; /* Verbs Hash Rx queues. */\n \tLIST_HEAD(txq, mlx5_txq_ctrl) txqsctrl; /* DPDK Tx queues. */\n \tLIST_HEAD(txqobj, mlx5_txq_obj) txqsobj; /* Verbs/DevX Tx queues. */\n \t/* Indirection tables. */\ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex 1fe0b30..6ec0e72 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -368,13 +368,6 @@ enum mlx5_flow_fate_type {\n \tMLX5_FLOW_FATE_MAX,\n };\n \n-/* Hash list callback context */\n-struct mlx5_flow_cb_ctx {\n-\tstruct rte_eth_dev *dev;\n-\tstruct rte_flow_error *error;\n-\tvoid *data;\n-};\n-\n /* Matcher PRM representation */\n struct mlx5_flow_dv_match_params {\n \tsize_t size;\n@@ -532,15 +525,6 @@ struct ibv_spec_header {\n \tuint16_t size;\n };\n \n-/* RSS description. */\n-struct mlx5_flow_rss_desc {\n-\tuint32_t level;\n-\tuint32_t queue_num; /**< Number of entries in @p queue. */\n-\tuint64_t types; /**< Specific RSS hash types (see ETH_RSS_*). */\n-\tuint8_t key[MLX5_RSS_HASH_KEY_LEN]; /**< RSS hash key. */\n-\tuint16_t *queue; /**< Destination queues. */\n-};\n-\n /* PMD flow priority for tunnel */\n #define MLX5_TUNNEL_PRIO_GET(rss_desc) \\\n \t((rss_desc)->level >= 2 ? MLX5_PRIORITY_MAP_L2 : MLX5_PRIORITY_MAP_L4)\ndiff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c\nindex b884d8c..5092130 100644\n--- a/drivers/net/mlx5/mlx5_flow_dv.c\n+++ b/drivers/net/mlx5/mlx5_flow_dv.c\n@@ -8981,21 +8981,11 @@ struct mlx5_hlist_entry *\n \t\t\t\t\t[!!wks->flow_nested_idx];\n \n \t\t\tMLX5_ASSERT(rss_desc->queue_num);\n-\t\t\thrxq_idx = mlx5_hrxq_get(dev, rss_desc->key,\n-\t\t\t\t\t\t MLX5_RSS_HASH_KEY_LEN,\n-\t\t\t\t\t\t dev_flow->hash_fields,\n-\t\t\t\t\t\t rss_desc->queue,\n-\t\t\t\t\t\t rss_desc->queue_num);\n-\t\t\tif (!hrxq_idx) {\n-\t\t\t\thrxq_idx = mlx5_hrxq_new\n-\t\t\t\t\t\t(dev, rss_desc->key,\n-\t\t\t\t\t\t MLX5_RSS_HASH_KEY_LEN,\n-\t\t\t\t\t\t dev_flow->hash_fields,\n-\t\t\t\t\t\t rss_desc->queue,\n-\t\t\t\t\t\t rss_desc->queue_num,\n-\t\t\t\t\t\t !!(dh->layers &\n-\t\t\t\t\t\t MLX5_FLOW_LAYER_TUNNEL));\n-\t\t\t}\n+\t\t\trss_desc->key_len = MLX5_RSS_HASH_KEY_LEN;\n+\t\t\trss_desc->hash_fields = dev_flow->hash_fields;\n+\t\t\trss_desc->tunnel = !!(dh->layers &\n+\t\t\t\t\t      MLX5_FLOW_LAYER_TUNNEL);\n+\t\t\thrxq_idx = mlx5_hrxq_get(dev, rss_desc);\n \t\t\thrxq = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_HRXQ],\n \t\t\t\t\t      hrxq_idx);\n \t\t\tif (!hrxq) {\ndiff --git a/drivers/net/mlx5/mlx5_flow_verbs.c b/drivers/net/mlx5/mlx5_flow_verbs.c\nindex b649960..905da8a 100644\n--- a/drivers/net/mlx5/mlx5_flow_verbs.c\n+++ b/drivers/net/mlx5/mlx5_flow_verbs.c\n@@ -1984,20 +1984,11 @@\n \t\t\t\t&wks->rss_desc[!!wks->flow_nested_idx];\n \n \t\t\tMLX5_ASSERT(rss_desc->queue_num);\n-\t\t\thrxq_idx = mlx5_hrxq_get(dev, rss_desc->key,\n-\t\t\t\t\t\t MLX5_RSS_HASH_KEY_LEN,\n-\t\t\t\t\t\t dev_flow->hash_fields,\n-\t\t\t\t\t\t rss_desc->queue,\n-\t\t\t\t\t\t rss_desc->queue_num);\n-\t\t\tif (!hrxq_idx)\n-\t\t\t\thrxq_idx = mlx5_hrxq_new\n-\t\t\t\t\t\t(dev, rss_desc->key,\n-\t\t\t\t\t\t MLX5_RSS_HASH_KEY_LEN,\n-\t\t\t\t\t\t dev_flow->hash_fields,\n-\t\t\t\t\t\t rss_desc->queue,\n-\t\t\t\t\t\t rss_desc->queue_num,\n-\t\t\t\t\t\t !!(handle->layers &\n-\t\t\t\t\t\t MLX5_FLOW_LAYER_TUNNEL));\n+\t\t\trss_desc->key_len = MLX5_RSS_HASH_KEY_LEN;\n+\t\t\trss_desc->hash_fields = dev_flow->hash_fields;\n+\t\t\trss_desc->tunnel = !!(handle->layers &\n+\t\t\t\t\t      MLX5_FLOW_LAYER_TUNNEL);\n+\t\t\thrxq_idx = mlx5_hrxq_get(dev, rss_desc);\n \t\t\thrxq = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_HRXQ],\n \t\t\t\t\t      hrxq_idx);\n \t\t\tif (!hrxq) {\ndiff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c\nindex c059e21..0c45ca0 100644\n--- a/drivers/net/mlx5/mlx5_rxq.c\n+++ b/drivers/net/mlx5/mlx5_rxq.c\n@@ -1853,156 +1853,164 @@ struct mlx5_ind_table_obj *\n }\n \n /**\n- * Get an Rx Hash queue.\n+ * Match an Rx Hash queue.\n  *\n- * @param dev\n- *   Pointer to Ethernet device.\n- * @param rss_conf\n- *   RSS configuration for the Rx hash queue.\n- * @param queues\n- *   Queues entering in hash queue. In case of empty hash_fields only the\n- *   first queue index will be taken for the indirection table.\n- * @param queues_n\n- *   Number of queues.\n+ * @param list\n+ *   Cache list pointer.\n+ * @param entry\n+ *   Hash queue entry pointer.\n+ * @param cb_ctx\n+ *   Context of the callback function.\n  *\n  * @return\n- *   An hash Rx queue index on success.\n+ *   0 if match, none zero if not match.\n  */\n-uint32_t\n-mlx5_hrxq_get(struct rte_eth_dev *dev,\n-\t      const uint8_t *rss_key, uint32_t rss_key_len,\n-\t      uint64_t hash_fields,\n-\t      const uint16_t *queues, uint32_t queues_n)\n+int\n+mlx5_hrxq_match_cb(struct mlx5_cache_list *list,\n+\t\t   struct mlx5_cache_entry *entry,\n+\t\t   void *cb_ctx)\n {\n-\tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_hrxq *hrxq;\n-\tuint32_t idx;\n-\n-\tqueues_n = hash_fields ? queues_n : 1;\n-\tILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_HRXQ], priv->hrxqs, idx,\n-\t\t      hrxq, next) {\n-\t\tstruct mlx5_ind_table_obj *ind_tbl;\n+\tstruct rte_eth_dev *dev = list->ctx;\n+\tstruct mlx5_flow_cb_ctx *ctx = cb_ctx;\n+\tstruct mlx5_flow_rss_desc *rss_desc = ctx->data;\n+\tstruct mlx5_hrxq *hrxq = container_of(entry, typeof(*hrxq), entry);\n+\tstruct mlx5_ind_table_obj *ind_tbl;\n+\tuint32_t queues_n;\n \n-\t\tif (hrxq->rss_key_len != rss_key_len)\n-\t\t\tcontinue;\n-\t\tif (memcmp(hrxq->rss_key, rss_key, rss_key_len))\n-\t\t\tcontinue;\n-\t\tif (hrxq->hash_fields != hash_fields)\n-\t\t\tcontinue;\n-\t\tind_tbl = mlx5_ind_table_obj_get(dev, queues, queues_n);\n-\t\tif (!ind_tbl)\n-\t\t\tcontinue;\n-\t\tif (ind_tbl != hrxq->ind_table) {\n-\t\t\tmlx5_ind_table_obj_release(dev, ind_tbl);\n-\t\t\tcontinue;\n-\t\t}\n-\t\trte_atomic32_inc(&hrxq->refcnt);\n-\t\treturn idx;\n-\t}\n-\treturn 0;\n+\tif (hrxq->rss_key_len != rss_desc->key_len ||\n+\t    memcmp(hrxq->rss_key, rss_desc->key, rss_desc->key_len) ||\n+\t    hrxq->hash_fields != rss_desc->hash_fields)\n+\t\treturn 1;\n+\tqueues_n = rss_desc->hash_fields ? rss_desc->queue_num : 1;\n+\tind_tbl = mlx5_ind_table_obj_get(dev, rss_desc->queue, queues_n);\n+\tif (ind_tbl)\n+\t\tmlx5_ind_table_obj_release(dev, ind_tbl);\n+\treturn ind_tbl != hrxq->ind_table;\n }\n \n /**\n- * Release the hash Rx queue.\n- *\n- * @param dev\n- *   Pointer to Ethernet device.\n- * @param hrxq\n- *   Index to Hash Rx queue to release.\n+ * Remove the Rx Hash queue.\n  *\n- * @return\n- *   1 while a reference on it exists, 0 when freed.\n+ * @param list\n+ *   Cache list pointer.\n+ * @param entry\n+ *   Hash queue entry pointer.\n  */\n-int\n-mlx5_hrxq_release(struct rte_eth_dev *dev, uint32_t hrxq_idx)\n+void\n+mlx5_hrxq_remove_cb(struct mlx5_cache_list *list,\n+\t\t    struct mlx5_cache_entry *entry)\n {\n+\tstruct rte_eth_dev *dev = list->ctx;\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_hrxq *hrxq;\n+\tstruct mlx5_hrxq *hrxq = container_of(entry, typeof(*hrxq), entry);\n \n-\thrxq = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_HRXQ], hrxq_idx);\n-\tif (!hrxq)\n-\t\treturn 0;\n-\tif (rte_atomic32_dec_and_test(&hrxq->refcnt)) {\n #ifdef HAVE_IBV_FLOW_DV_SUPPORT\n-\t\tmlx5_glue->destroy_flow_action(hrxq->action);\n+\tmlx5_glue->destroy_flow_action(hrxq->action);\n #endif\n-\t\tpriv->obj_ops.hrxq_destroy(hrxq);\n-\t\tmlx5_ind_table_obj_release(dev, hrxq->ind_table);\n-\t\tILIST_REMOVE(priv->sh->ipool[MLX5_IPOOL_HRXQ], &priv->hrxqs,\n-\t\t\t     hrxq_idx, hrxq, next);\n-\t\tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_HRXQ], hrxq_idx);\n-\t\treturn 0;\n-\t}\n-\tclaim_nonzero(mlx5_ind_table_obj_release(dev, hrxq->ind_table));\n-\treturn 1;\n+\tpriv->obj_ops.hrxq_destroy(hrxq);\n+\tmlx5_ind_table_obj_release(dev, hrxq->ind_table);\n+\tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_HRXQ], hrxq->idx);\n }\n \n /**\n  * Create an Rx Hash queue.\n  *\n- * @param dev\n- *   Pointer to Ethernet device.\n- * @param rss_key\n- *   RSS key for the Rx hash queue.\n- * @param rss_key_len\n- *   RSS key length.\n- * @param hash_fields\n- *   Verbs protocol hash field to make the RSS on.\n- * @param queues\n- *   Queues entering in hash queue. In case of empty hash_fields only the\n- *   first queue index will be taken for the indirection table.\n- * @param queues_n\n- *   Number of queues.\n- * @param tunnel\n- *   Tunnel type.\n+ * @param list\n+ *   Cache list pointer.\n+ * @param entry\n+ *   Hash queue entry pointer.\n+ * @param cb_ctx\n+ *   Context of the callback function.\n  *\n  * @return\n- *   The DevX object initialized index, 0 otherwise and rte_errno is set.\n+ *   queue entry on success, NULL otherwise.\n  */\n-uint32_t\n-mlx5_hrxq_new(struct rte_eth_dev *dev,\n-\t      const uint8_t *rss_key, uint32_t rss_key_len,\n-\t      uint64_t hash_fields,\n-\t      const uint16_t *queues, uint32_t queues_n,\n-\t      int tunnel __rte_unused)\n+struct mlx5_cache_entry *\n+mlx5_hrxq_create_cb(struct mlx5_cache_list *list,\n+\t\t    struct mlx5_cache_entry *entry __rte_unused,\n+\t\t    void *cb_ctx)\n {\n+\tstruct rte_eth_dev *dev = list->ctx;\n \tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_flow_cb_ctx *ctx = cb_ctx;\n+\tstruct mlx5_flow_rss_desc *rss_desc = ctx->data;\n+\tconst uint8_t *rss_key = rss_desc->key;\n+\tuint32_t rss_key_len =  rss_desc->key_len;\n+\tconst uint16_t *queues = rss_desc->queue;\n+\tuint32_t queues_n = rss_desc->queue_num;\n \tstruct mlx5_hrxq *hrxq = NULL;\n \tuint32_t hrxq_idx = 0;\n \tstruct mlx5_ind_table_obj *ind_tbl;\n \tint ret;\n \n-\tqueues_n = hash_fields ? queues_n : 1;\n+\tqueues_n = rss_desc->hash_fields ? queues_n : 1;\n \tind_tbl = mlx5_ind_table_obj_get(dev, queues, queues_n);\n \tif (!ind_tbl)\n \t\tind_tbl = mlx5_ind_table_obj_new(dev, queues, queues_n);\n-\tif (!ind_tbl) {\n-\t\trte_errno = ENOMEM;\n-\t\treturn 0;\n-\t}\n+\tif (!ind_tbl)\n+\t\treturn NULL;\n \thrxq = mlx5_ipool_zmalloc(priv->sh->ipool[MLX5_IPOOL_HRXQ], &hrxq_idx);\n \tif (!hrxq)\n \t\tgoto error;\n+\thrxq->idx = hrxq_idx;\n \thrxq->ind_table = ind_tbl;\n \thrxq->rss_key_len = rss_key_len;\n-\thrxq->hash_fields = hash_fields;\n+\thrxq->hash_fields = rss_desc->hash_fields;\n \tmemcpy(hrxq->rss_key, rss_key, rss_key_len);\n-\tret = priv->obj_ops.hrxq_new(dev, hrxq, tunnel);\n-\tif (ret < 0) {\n-\t\trte_errno = errno;\n+\tret = priv->obj_ops.hrxq_new(dev, hrxq, rss_desc->tunnel);\n+\tif (ret < 0)\n \t\tgoto error;\n-\t}\n-\trte_atomic32_inc(&hrxq->refcnt);\n-\tILIST_INSERT(priv->sh->ipool[MLX5_IPOOL_HRXQ], &priv->hrxqs, hrxq_idx,\n-\t\t     hrxq, next);\n-\treturn hrxq_idx;\n+\treturn &hrxq->entry;\n error:\n-\tret = rte_errno; /* Save rte_errno before cleanup. */\n \tmlx5_ind_table_obj_release(dev, ind_tbl);\n \tif (hrxq)\n \t\tmlx5_ipool_free(priv->sh->ipool[MLX5_IPOOL_HRXQ], hrxq_idx);\n-\trte_errno = ret; /* Restore rte_errno. */\n-\treturn 0;\n+\treturn NULL;\n+}\n+\n+/**\n+ * Get an Rx Hash queue.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device.\n+ * @param rss_desc\n+ *   RSS configuration for the Rx hash queue.\n+ *\n+ * @return\n+ *   An hash Rx queue index on success.\n+ */\n+uint32_t mlx5_hrxq_get(struct rte_eth_dev *dev,\n+\t\t       struct mlx5_flow_rss_desc *rss_desc)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_hrxq *hrxq;\n+\tstruct mlx5_cache_entry *entry;\n+\tstruct mlx5_flow_cb_ctx ctx = {\n+\t\t.data = rss_desc,\n+\t};\n+\n+\tentry = mlx5_cache_register(&priv->hrxqs, &ctx);\n+\tif (!entry)\n+\t\treturn 0;\n+\thrxq = container_of(entry, typeof(*hrxq), entry);\n+\treturn hrxq->idx;\n+}\n+\n+/**\n+ * Release the hash Rx queue.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device.\n+ * @param hrxq_idx\n+ *   Index to Hash Rx queue to release.\n+ */\n+void mlx5_hrxq_release(struct rte_eth_dev *dev, uint32_t hrxq_idx)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_hrxq *hrxq;\n+\n+\thrxq = mlx5_ipool_get(priv->sh->ipool[MLX5_IPOOL_HRXQ], hrxq_idx);\n+\tmlx5_cache_unregister(&priv->hrxqs, &hrxq->entry);\n }\n \n /**\n@@ -2087,21 +2095,9 @@ struct mlx5_hrxq *\n  *   The number of object not released.\n  */\n int\n-mlx5_hrxq_verify(struct rte_eth_dev *dev)\n+mlx5_hrxq_verify(struct rte_eth_dev *dev __rte_unused)\n {\n-\tstruct mlx5_priv *priv = dev->data->dev_private;\n-\tstruct mlx5_hrxq *hrxq;\n-\tuint32_t idx;\n-\tint ret = 0;\n-\n-\tILIST_FOREACH(priv->sh->ipool[MLX5_IPOOL_HRXQ], priv->hrxqs, idx,\n-\t\t      hrxq, next) {\n-\t\tDRV_LOG(DEBUG,\n-\t\t\t\"port %u hash Rx queue %p still referenced\",\n-\t\t\tdev->data->port_id, (void *)hrxq);\n-\t\t++ret;\n-\t}\n-\treturn ret;\n+\treturn 0;\n }\n \n /**\ndiff --git a/drivers/net/mlx5/mlx5_rxtx.h b/drivers/net/mlx5/mlx5_rxtx.h\nindex 9ffa028..6f603e2 100644\n--- a/drivers/net/mlx5/mlx5_rxtx.h\n+++ b/drivers/net/mlx5/mlx5_rxtx.h\n@@ -370,17 +370,19 @@ struct mlx5_ind_table_obj *mlx5_ind_table_obj_get(struct rte_eth_dev *dev,\n \t\t\t\t\t\t  uint32_t queues_n);\n int mlx5_ind_table_obj_release(struct rte_eth_dev *dev,\n \t\t\t       struct mlx5_ind_table_obj *ind_tbl);\n-uint32_t mlx5_hrxq_new(struct rte_eth_dev *dev,\n-\t\t       const uint8_t *rss_key, uint32_t rss_key_len,\n-\t\t       uint64_t hash_fields,\n-\t\t       const uint16_t *queues, uint32_t queues_n,\n-\t\t       int tunnel __rte_unused);\n+struct mlx5_cache_entry *mlx5_hrxq_create_cb(struct mlx5_cache_list *list,\n+\t\tstruct mlx5_cache_entry *entry __rte_unused, void *cb_ctx);\n+int mlx5_hrxq_match_cb(struct mlx5_cache_list *list,\n+\t\t       struct mlx5_cache_entry *entry,\n+\t\t       void *cb_ctx);\n+void mlx5_hrxq_remove_cb(struct mlx5_cache_list *list,\n+\t\t\t struct mlx5_cache_entry *entry);\n uint32_t mlx5_hrxq_get(struct rte_eth_dev *dev,\n-\t\t       const uint8_t *rss_key, uint32_t rss_key_len,\n-\t\t       uint64_t hash_fields,\n-\t\t       const uint16_t *queues, uint32_t queues_n);\n-int mlx5_hrxq_release(struct rte_eth_dev *dev, uint32_t hxrq_idx);\n+\t\t       struct mlx5_flow_rss_desc *rss_desc);\n+void mlx5_hrxq_release(struct rte_eth_dev *dev, uint32_t hxrq_idx);\n int mlx5_hrxq_verify(struct rte_eth_dev *dev);\n+\n+\n enum mlx5_rxq_type mlx5_rxq_get_type(struct rte_eth_dev *dev, uint16_t idx);\n struct mlx5_hrxq *mlx5_drop_action_create(struct rte_eth_dev *dev);\n void mlx5_drop_action_destroy(struct rte_eth_dev *dev);\n",
    "prefixes": [
        "16/25"
    ]
}