get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 90907,
    "url": "http://patches.dpdk.org/api/patches/90907/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20210408204849.9543-12-shirik@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": "<20210408204849.9543-12-shirik@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210408204849.9543-12-shirik@nvidia.com",
    "date": "2021-04-08T20:48:36",
    "name": "[11/24] common/mlx5: share hash list tool",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "62e82c9f91973323fa185290968fe43ee2148320",
    "submitter": {
        "id": 1894,
        "url": "http://patches.dpdk.org/api/people/1894/?format=api",
        "name": "Shiri Kuzin",
        "email": "shirik@nvidia.com"
    },
    "delegate": {
        "id": 6690,
        "url": "http://patches.dpdk.org/api/users/6690/?format=api",
        "username": "akhil",
        "first_name": "akhil",
        "last_name": "goyal",
        "email": "gakhil@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20210408204849.9543-12-shirik@nvidia.com/mbox/",
    "series": [
        {
            "id": 16215,
            "url": "http://patches.dpdk.org/api/series/16215/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=16215",
            "date": "2021-04-08T20:48:25",
            "name": "drivers: introduce mlx5 crypto PMD",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/16215/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/90907/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/90907/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 56E43A0C46;\n\tThu,  8 Apr 2021 22:50:37 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 43DF614122F;\n\tThu,  8 Apr 2021 22:49:52 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by mails.dpdk.org (Postfix) with ESMTP id DB5481410B4\n for <dev@dpdk.org>; Thu,  8 Apr 2021 22:49:45 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n shirik@nvidia.com) with SMTP; 8 Apr 2021 23:49:42 +0300",
            "from nvidia.com (c-236-0-60-063.mtl.labs.mlnx [10.236.0.63])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 138KnAJU028067;\n Thu, 8 Apr 2021 23:49:42 +0300"
        ],
        "From": "Shiri Kuzin <shirik@nvidia.com>",
        "To": "dev@dpdk.org",
        "Cc": "matan@nvidia.com, gakhil@marvell.com, suanmingm@nvidia.com",
        "Date": "Thu,  8 Apr 2021 23:48:36 +0300",
        "Message-Id": "<20210408204849.9543-12-shirik@nvidia.com>",
        "X-Mailer": "git-send-email 2.21.0",
        "In-Reply-To": "<20210408204849.9543-1-shirik@nvidia.com>",
        "References": "<1615447568-260965-1-git-send-email-matan@nvidia.com>\n <20210408204849.9543-1-shirik@nvidia.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH 11/24] common/mlx5: share hash list tool",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "In order to use the hash list defined in net in other drivers, the\nhash list is moved to common utilities.\n\nIn addition, the log definition was moved from the common utilities to\na dedicated new log file in common in order to prevent a conflict.\n\nSigned-off-by: Shiri Kuzin <shirik@nvidia.com>\nAcked-by: Matan Azrad <matan@nvidia.com>\n---\n drivers/common/mlx5/linux/mlx5_common_os.c    |   2 +-\n drivers/common/mlx5/linux/mlx5_nl.c           |   2 +-\n drivers/common/mlx5/meson.build               |   1 +\n drivers/common/mlx5/mlx5_common.c             |   2 +-\n drivers/common/mlx5/mlx5_common_devx.c        |   2 +-\n drivers/common/mlx5/mlx5_common_log.h         |  21 ++\n drivers/common/mlx5/mlx5_common_mp.c          |   2 +-\n drivers/common/mlx5/mlx5_common_mr.c          |   2 +-\n drivers/common/mlx5/mlx5_common_pci.c         |   3 +-\n drivers/common/mlx5/mlx5_common_utils.c       | 221 ++++++++++++++++++\n drivers/common/mlx5/mlx5_common_utils.h       | 202 +++++++++++++++-\n drivers/common/mlx5/mlx5_devx_cmds.c          |   2 +-\n drivers/common/mlx5/mlx5_malloc.c             |   2 +-\n .../common/mlx5/rte_common_mlx5_exports.def   |   7 +\n drivers/common/mlx5/version.map               |   6 +\n drivers/common/mlx5/windows/mlx5_common_os.c  |   2 +-\n drivers/common/mlx5/windows/mlx5_glue.c       |   2 +-\n drivers/net/mlx5/mlx5_utils.c                 | 209 -----------------\n drivers/net/mlx5/mlx5_utils.h                 | 194 +--------------\n 19 files changed, 464 insertions(+), 420 deletions(-)\n create mode 100644 drivers/common/mlx5/mlx5_common_log.h\n create mode 100644 drivers/common/mlx5/mlx5_common_utils.c",
    "diff": "diff --git a/drivers/common/mlx5/linux/mlx5_common_os.c b/drivers/common/mlx5/linux/mlx5_common_os.c\nindex 5cf9576921..fba8245b8b 100644\n--- a/drivers/common/mlx5/linux/mlx5_common_os.c\n+++ b/drivers/common/mlx5/linux/mlx5_common_os.c\n@@ -15,7 +15,7 @@\n #include <rte_string_fns.h>\n \n #include \"mlx5_common.h\"\n-#include \"mlx5_common_utils.h\"\n+#include \"mlx5_common_log.h\"\n #include \"mlx5_glue.h\"\n \n #ifdef MLX5_GLUE\ndiff --git a/drivers/common/mlx5/linux/mlx5_nl.c b/drivers/common/mlx5/linux/mlx5_nl.c\nindex 752c57b33d..f0d04f9473 100644\n--- a/drivers/common/mlx5/linux/mlx5_nl.c\n+++ b/drivers/common/mlx5/linux/mlx5_nl.c\n@@ -20,7 +20,7 @@\n #include <rte_errno.h>\n \n #include \"mlx5_nl.h\"\n-#include \"mlx5_common_utils.h\"\n+#include \"../mlx5_common_log.h\"\n #include \"mlx5_malloc.h\"\n #ifdef HAVE_DEVLINK\n #include <linux/devlink.h>\ndiff --git a/drivers/common/mlx5/meson.build b/drivers/common/mlx5/meson.build\nindex b2efea4432..1459b9bd89 100644\n--- a/drivers/common/mlx5/meson.build\n+++ b/drivers/common/mlx5/meson.build\n@@ -16,6 +16,7 @@ sources += files(\n \t'mlx5_malloc.c',\n \t'mlx5_common_pci.c',\n \t'mlx5_common_devx.c',\n+\t'mlx5_common_utils.c',\n )\n \n cflags_options = [\ndiff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c\nindex c26a2cfa30..acb785f9ce 100644\n--- a/drivers/common/mlx5/mlx5_common.c\n+++ b/drivers/common/mlx5/mlx5_common.c\n@@ -11,7 +11,7 @@\n \n #include \"mlx5_common.h\"\n #include \"mlx5_common_os.h\"\n-#include \"mlx5_common_utils.h\"\n+#include \"mlx5_common_log.h\"\n #include \"mlx5_common_pci.h\"\n \n int mlx5_common_logtype;\ndiff --git a/drivers/common/mlx5/mlx5_common_devx.c b/drivers/common/mlx5/mlx5_common_devx.c\nindex d19be122bd..22c8d356c4 100644\n--- a/drivers/common/mlx5/mlx5_common_devx.c\n+++ b/drivers/common/mlx5/mlx5_common_devx.c\n@@ -12,7 +12,7 @@\n \n #include \"mlx5_prm.h\"\n #include \"mlx5_devx_cmds.h\"\n-#include \"mlx5_common_utils.h\"\n+#include \"mlx5_common_log.h\"\n #include \"mlx5_malloc.h\"\n #include \"mlx5_common.h\"\n #include \"mlx5_common_devx.h\"\ndiff --git a/drivers/common/mlx5/mlx5_common_log.h b/drivers/common/mlx5/mlx5_common_log.h\nnew file mode 100644\nindex 0000000000..26b13fedaf\n--- /dev/null\n+++ b/drivers/common/mlx5/mlx5_common_log.h\n@@ -0,0 +1,21 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2019 Mellanox Technologies, Ltd\n+ */\n+\n+#ifndef RTE_PMD_MLX5_COMMON_LOG_H_\n+#define RTE_PMD_MLX5_COMMON_LOG_H_\n+\n+#include \"mlx5_common.h\"\n+\n+\n+extern int mlx5_common_logtype;\n+\n+#define MLX5_COMMON_LOG_PREFIX \"mlx5_common\"\n+/* Generic printf()-like logging macro with automatic line feed. */\n+#define DRV_LOG(level, ...) \\\n+\tPMD_DRV_LOG_(level, mlx5_common_logtype, MLX5_COMMON_LOG_PREFIX, \\\n+\t\t__VA_ARGS__ PMD_DRV_LOG_STRIP PMD_DRV_LOG_OPAREN, \\\n+\t\tPMD_DRV_LOG_CPAREN)\n+\n+#endif /* RTE_PMD_MLX5_COMMON_LOG_H_ */\n+\ndiff --git a/drivers/common/mlx5/mlx5_common_mp.c b/drivers/common/mlx5/mlx5_common_mp.c\nindex 40e3956e45..673a7c31de 100644\n--- a/drivers/common/mlx5/mlx5_common_mp.c\n+++ b/drivers/common/mlx5/mlx5_common_mp.c\n@@ -10,7 +10,7 @@\n #include <rte_errno.h>\n \n #include \"mlx5_common_mp.h\"\n-#include \"mlx5_common_utils.h\"\n+#include \"mlx5_common_log.h\"\n #include \"mlx5_malloc.h\"\n \n /**\ndiff --git a/drivers/common/mlx5/mlx5_common_mr.c b/drivers/common/mlx5/mlx5_common_mr.c\nindex e1ed0caf3a..afb5b3d0a7 100644\n--- a/drivers/common/mlx5/mlx5_common_mr.c\n+++ b/drivers/common/mlx5/mlx5_common_mr.c\n@@ -11,7 +11,7 @@\n #include \"mlx5_glue.h\"\n #include \"mlx5_common_mp.h\"\n #include \"mlx5_common_mr.h\"\n-#include \"mlx5_common_utils.h\"\n+#include \"mlx5_common_log.h\"\n #include \"mlx5_malloc.h\"\n \n struct mr_find_contig_memsegs_data {\ndiff --git a/drivers/common/mlx5/mlx5_common_pci.c b/drivers/common/mlx5/mlx5_common_pci.c\nindex 21b1acdf87..177ccf62d9 100644\n--- a/drivers/common/mlx5/mlx5_common_pci.c\n+++ b/drivers/common/mlx5/mlx5_common_pci.c\n@@ -5,7 +5,8 @@\n #include <stdlib.h>\n #include <rte_malloc.h>\n #include <rte_class.h>\n-#include \"mlx5_common_utils.h\"\n+\n+#include \"mlx5_common_log.h\"\n #include \"mlx5_common_pci.h\"\n \n struct mlx5_pci_device {\ndiff --git a/drivers/common/mlx5/mlx5_common_utils.c b/drivers/common/mlx5/mlx5_common_utils.c\nnew file mode 100644\nindex 0000000000..ad2011e858\n--- /dev/null\n+++ b/drivers/common/mlx5/mlx5_common_utils.c\n@@ -0,0 +1,221 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright 2019 Mellanox Technologies, Ltd\n+ */\n+\n+#include <rte_malloc.h>\n+#include <rte_hash_crc.h>\n+#include <rte_errno.h>\n+\n+#include <mlx5_malloc.h>\n+\n+#include \"mlx5_common_utils.h\"\n+#include \"mlx5_common_log.h\"\n+\n+/********************* Hash List **********************/\n+\n+static struct mlx5_hlist_entry *\n+mlx5_hlist_default_create_cb(struct mlx5_hlist *h, uint64_t key __rte_unused,\n+\t\t\t     void *ctx __rte_unused)\n+{\n+\treturn mlx5_malloc(MLX5_MEM_ZERO, h->entry_sz, 0, SOCKET_ID_ANY);\n+}\n+\n+static void\n+mlx5_hlist_default_remove_cb(struct mlx5_hlist *h __rte_unused,\n+\t\t\t     struct mlx5_hlist_entry *entry)\n+{\n+\tmlx5_free(entry);\n+}\n+\n+struct mlx5_hlist *\n+mlx5_hlist_create(const char *name, uint32_t size, uint32_t entry_size,\n+\t\t  uint32_t flags, mlx5_hlist_create_cb cb_create,\n+\t\t  mlx5_hlist_match_cb cb_match, mlx5_hlist_remove_cb cb_remove)\n+{\n+\tstruct mlx5_hlist *h;\n+\tuint32_t act_size;\n+\tuint32_t alloc_size;\n+\tuint32_t i;\n+\n+\tif (!size || !cb_match || (!cb_create ^ !cb_remove))\n+\t\treturn NULL;\n+\t/* Align to the next power of 2, 32bits integer is enough now. */\n+\tif (!rte_is_power_of_2(size)) {\n+\t\tact_size = rte_align32pow2(size);\n+\t\tDRV_LOG(DEBUG, \"Size 0x%\" PRIX32 \" is not power of 2, \"\n+\t\t\t\"will be aligned to 0x%\" PRIX32 \".\", size, act_size);\n+\t} else {\n+\t\tact_size = size;\n+\t}\n+\talloc_size = sizeof(struct mlx5_hlist) +\n+\t\t     sizeof(struct mlx5_hlist_bucket) * act_size;\n+\t/* Using zmalloc, then no need to initialize the heads. */\n+\th = mlx5_malloc(MLX5_MEM_ZERO, alloc_size, RTE_CACHE_LINE_SIZE,\n+\t\t\tSOCKET_ID_ANY);\n+\tif (!h) {\n+\t\tDRV_LOG(ERR, \"No memory for hash list %s creation\",\n+\t\t\tname ? name : \"None\");\n+\t\treturn NULL;\n+\t}\n+\tif (name)\n+\t\tsnprintf(h->name, MLX5_HLIST_NAMESIZE, \"%s\", name);\n+\th->table_sz = act_size;\n+\th->mask = act_size - 1;\n+\th->entry_sz = entry_size;\n+\th->direct_key = !!(flags & MLX5_HLIST_DIRECT_KEY);\n+\th->write_most = !!(flags & MLX5_HLIST_WRITE_MOST);\n+\th->cb_create = cb_create ? cb_create : mlx5_hlist_default_create_cb;\n+\th->cb_match = cb_match;\n+\th->cb_remove = cb_remove ? cb_remove : mlx5_hlist_default_remove_cb;\n+\tfor (i = 0; i < act_size; i++)\n+\t\trte_rwlock_init(&h->buckets[i].lock);\n+\tDRV_LOG(DEBUG, \"Hash list with %s size 0x%\" PRIX32 \" is created.\",\n+\t\th->name, act_size);\n+\treturn h;\n+}\n+\n+static struct mlx5_hlist_entry *\n+__hlist_lookup(struct mlx5_hlist *h, uint64_t key, uint32_t idx,\n+\t       void *ctx, bool reuse)\n+{\n+\tstruct mlx5_hlist_head *first;\n+\tstruct mlx5_hlist_entry *node;\n+\n+\tMLX5_ASSERT(h);\n+\tfirst = &h->buckets[idx].head;\n+\tLIST_FOREACH(node, first, next) {\n+\t\tif (!h->cb_match(h, node, key, ctx)) {\n+\t\t\tif (reuse) {\n+\t\t\t\t__atomic_add_fetch(&node->ref_cnt, 1,\n+\t\t\t\t\t\t   __ATOMIC_RELAXED);\n+\t\t\t\tDRV_LOG(DEBUG, \"Hash list %s entry %p \"\n+\t\t\t\t\t\"reuse: %u.\",\n+\t\t\t\t\th->name, (void *)node, node->ref_cnt);\n+\t\t\t}\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\treturn node;\n+}\n+\n+static struct mlx5_hlist_entry *\n+hlist_lookup(struct mlx5_hlist *h, uint64_t key, uint32_t idx,\n+\t     void *ctx, bool reuse)\n+{\n+\tstruct mlx5_hlist_entry *node;\n+\n+\tMLX5_ASSERT(h);\n+\trte_rwlock_read_lock(&h->buckets[idx].lock);\n+\tnode = __hlist_lookup(h, key, idx, ctx, reuse);\n+\trte_rwlock_read_unlock(&h->buckets[idx].lock);\n+\treturn node;\n+}\n+\n+struct mlx5_hlist_entry *\n+mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key, void *ctx)\n+{\n+\tuint32_t idx;\n+\n+\tif (h->direct_key)\n+\t\tidx = (uint32_t)(key & h->mask);\n+\telse\n+\t\tidx = rte_hash_crc_8byte(key, 0) & h->mask;\n+\treturn hlist_lookup(h, key, idx, ctx, false);\n+}\n+\n+struct mlx5_hlist_entry*\n+mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key, void *ctx)\n+{\n+\tuint32_t idx;\n+\tstruct mlx5_hlist_head *first;\n+\tstruct mlx5_hlist_bucket *b;\n+\tstruct mlx5_hlist_entry *entry;\n+\tuint32_t prev_gen_cnt = 0;\n+\n+\tif (h->direct_key)\n+\t\tidx = (uint32_t)(key & h->mask);\n+\telse\n+\t\tidx = rte_hash_crc_8byte(key, 0) & h->mask;\n+\tMLX5_ASSERT(h);\n+\tb = &h->buckets[idx];\n+\t/* Use write lock directly for write-most list. */\n+\tif (!h->write_most) {\n+\t\tprev_gen_cnt = __atomic_load_n(&b->gen_cnt, __ATOMIC_ACQUIRE);\n+\t\tentry = hlist_lookup(h, key, idx, ctx, true);\n+\t\tif (entry)\n+\t\t\treturn entry;\n+\t}\n+\trte_rwlock_write_lock(&b->lock);\n+\t/* Check if the list changed by other threads. */\n+\tif (h->write_most ||\n+\t    prev_gen_cnt != __atomic_load_n(&b->gen_cnt, __ATOMIC_ACQUIRE)) {\n+\t\tentry = __hlist_lookup(h, key, idx, ctx, true);\n+\t\tif (entry)\n+\t\t\tgoto done;\n+\t}\n+\tfirst = &b->head;\n+\tentry = h->cb_create(h, key, ctx);\n+\tif (!entry) {\n+\t\trte_errno = ENOMEM;\n+\t\tDRV_LOG(DEBUG, \"Can't allocate hash list %s entry.\", h->name);\n+\t\tgoto done;\n+\t}\n+\tentry->idx = idx;\n+\tentry->ref_cnt = 1;\n+\tLIST_INSERT_HEAD(first, entry, next);\n+\t__atomic_add_fetch(&b->gen_cnt, 1, __ATOMIC_ACQ_REL);\n+\tDRV_LOG(DEBUG, \"Hash list %s entry %p new: %u.\",\n+\t\th->name, (void *)entry, entry->ref_cnt);\n+done:\n+\trte_rwlock_write_unlock(&b->lock);\n+\treturn entry;\n+}\n+\n+int\n+mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_hlist_entry *entry)\n+{\n+\tuint32_t idx = entry->idx;\n+\n+\trte_rwlock_write_lock(&h->buckets[idx].lock);\n+\tMLX5_ASSERT(entry && entry->ref_cnt && entry->next.le_prev);\n+\tDRV_LOG(DEBUG, \"Hash list %s entry %p deref: %u.\",\n+\t\th->name, (void *)entry, entry->ref_cnt);\n+\tif (--entry->ref_cnt) {\n+\t\trte_rwlock_write_unlock(&h->buckets[idx].lock);\n+\t\treturn 1;\n+\t}\n+\tLIST_REMOVE(entry, next);\n+\t/* Set to NULL to get rid of removing action for more than once. */\n+\tentry->next.le_prev = NULL;\n+\th->cb_remove(h, entry);\n+\trte_rwlock_write_unlock(&h->buckets[idx].lock);\n+\tDRV_LOG(DEBUG, \"Hash list %s entry %p removed.\",\n+\t\th->name, (void *)entry);\n+\treturn 0;\n+}\n+\n+void\n+mlx5_hlist_destroy(struct mlx5_hlist *h)\n+{\n+\tuint32_t idx;\n+\tstruct mlx5_hlist_entry *entry;\n+\n+\tMLX5_ASSERT(h);\n+\tfor (idx = 0; idx < h->table_sz; ++idx) {\n+\t\t/* No LIST_FOREACH_SAFE, using while instead. */\n+\t\twhile (!LIST_EMPTY(&h->buckets[idx].head)) {\n+\t\t\tentry = LIST_FIRST(&h->buckets[idx].head);\n+\t\t\tLIST_REMOVE(entry, next);\n+\t\t\t/*\n+\t\t\t * The owner of whole element which contains data entry\n+\t\t\t * is the user, so it's the user's duty to do the clean\n+\t\t\t * up and the free work because someone may not put the\n+\t\t\t * hlist entry at the beginning(suggested to locate at\n+\t\t\t * the beginning). Or else the default free function\n+\t\t\t * will be used.\n+\t\t\t */\n+\t\t\th->cb_remove(h, entry);\n+\t\t}\n+\t}\n+\tmlx5_free(h);\n+}\ndiff --git a/drivers/common/mlx5/mlx5_common_utils.h b/drivers/common/mlx5/mlx5_common_utils.h\nindex 6cba39c8cc..ed378ce9bd 100644\n--- a/drivers/common/mlx5/mlx5_common_utils.h\n+++ b/drivers/common/mlx5/mlx5_common_utils.h\n@@ -7,14 +7,202 @@\n \n #include \"mlx5_common.h\"\n \n+#define MLX5_HLIST_DIRECT_KEY 0x0001 /* Use the key directly as hash index. */\n+#define MLX5_HLIST_WRITE_MOST 0x0002 /* List mostly used for append new. */\n \n-extern int mlx5_common_logtype;\n+/** Maximum size of string for naming the hlist table. */\n+#define MLX5_HLIST_NAMESIZE\t\t\t32\n \n-#define MLX5_COMMON_LOG_PREFIX \"mlx5_common\"\n-/* Generic printf()-like logging macro with automatic line feed. */\n-#define DRV_LOG(level, ...) \\\n-\tPMD_DRV_LOG_(level, mlx5_common_logtype, MLX5_COMMON_LOG_PREFIX, \\\n-\t\t__VA_ARGS__ PMD_DRV_LOG_STRIP PMD_DRV_LOG_OPAREN, \\\n-\t\tPMD_DRV_LOG_CPAREN)\n+struct mlx5_hlist;\n+\n+/**\n+ * Structure of the entry in the hash list, user should define its own struct\n+ * that contains this in order to store the data. The 'key' is 64-bits right\n+ * now and its user's responsibility to guarantee there is no collision.\n+ */\n+struct mlx5_hlist_entry {\n+\tLIST_ENTRY(mlx5_hlist_entry) next; /* entry pointers in the list. */\n+\tuint32_t idx; /* Bucket index the entry belongs to. */\n+\tuint32_t ref_cnt; /* Reference count. */\n+};\n+\n+/** Structure for hash head. */\n+LIST_HEAD(mlx5_hlist_head, mlx5_hlist_entry);\n+\n+/**\n+ * Type of callback function for entry removal.\n+ *\n+ * @param list\n+ *   The hash list.\n+ * @param entry\n+ *   The entry in the list.\n+ */\n+typedef void (*mlx5_hlist_remove_cb)(struct mlx5_hlist *list,\n+\t\t\t\t     struct mlx5_hlist_entry *entry);\n+\n+/**\n+ * Type of function for user defined matching.\n+ *\n+ * @param list\n+ *   The hash list.\n+ * @param entry\n+ *   The entry in the list.\n+ * @param key\n+ *   The new entry key.\n+ * @param ctx\n+ *   The pointer to new entry context.\n+ *\n+ * @return\n+ *   0 if matching, non-zero number otherwise.\n+ */\n+typedef int (*mlx5_hlist_match_cb)(struct mlx5_hlist *list,\n+\t\t\t\t   struct mlx5_hlist_entry *entry,\n+\t\t\t\t   uint64_t key, void *ctx);\n+\n+/**\n+ * Type of function for user defined hash list entry creation.\n+ *\n+ * @param list\n+ *   The hash list.\n+ * @param key\n+ *   The key of the new entry.\n+ * @param ctx\n+ *   The pointer to new entry context.\n+ *\n+ * @return\n+ *   Pointer to allocated entry on success, NULL otherwise.\n+ */\n+typedef struct mlx5_hlist_entry *(*mlx5_hlist_create_cb)\n+\t\t\t\t  (struct mlx5_hlist *list,\n+\t\t\t\t   uint64_t key, void *ctx);\n+\n+/* Hash list bucket head. */\n+struct mlx5_hlist_bucket {\n+\tstruct mlx5_hlist_head head; /* List head. */\n+\trte_rwlock_t lock; /* Bucket lock. */\n+\tuint32_t gen_cnt; /* List modification will update generation count. */\n+} __rte_cache_aligned;\n+\n+/**\n+ * Hash list table structure\n+ *\n+ * Entry in hash list could be reused if entry already exists, reference\n+ * count will increase and the existing entry returns.\n+ *\n+ * When destroy an entry from list, decrease reference count and only\n+ * destroy when no further reference.\n+ */\n+struct mlx5_hlist {\n+\tchar name[MLX5_HLIST_NAMESIZE]; /**< Name of the hash list. */\n+\t/**< number of heads, need to be power of 2. */\n+\tuint32_t table_sz;\n+\tuint32_t entry_sz; /**< Size of entry, used to allocate entry. */\n+\t/**< mask to get the index of the list heads. */\n+\tuint32_t mask;\n+\tbool direct_key; /* Use the new entry key directly as hash index. */\n+\tbool write_most; /* List mostly used for append new or destroy. */\n+\tvoid *ctx;\n+\tmlx5_hlist_create_cb cb_create; /**< entry create callback. */\n+\tmlx5_hlist_match_cb cb_match; /**< entry match callback. */\n+\tmlx5_hlist_remove_cb cb_remove; /**< entry remove callback. */\n+\tstruct mlx5_hlist_bucket buckets[] __rte_cache_aligned;\n+\t/**< list bucket arrays. */\n+};\n+\n+/**\n+ * Create a hash list table, the user can specify the list heads array size\n+ * of the table, now the size should be a power of 2 in order to get better\n+ * distribution for the entries. Each entry is a part of the whole data element\n+ * and the caller should be responsible for the data element's allocation and\n+ * cleanup / free. Key of each entry will be calculated with CRC in order to\n+ * generate a little fairer distribution.\n+ *\n+ * @param name\n+ *   Name of the hash list(optional).\n+ * @param size\n+ *   Heads array size of the hash list.\n+ * @param entry_size\n+ *   Entry size to allocate if cb_create not specified.\n+ * @param flags\n+ *   The hash list attribute flags.\n+ * @param cb_create\n+ *   Callback function for entry create.\n+ * @param cb_match\n+ *   Callback function for entry match.\n+ * @param cb_destroy\n+ *   Callback function for entry destroy.\n+ * @return\n+ *   Pointer of the hash list table created, NULL on failure.\n+ */\n+__rte_internal\n+struct mlx5_hlist *mlx5_hlist_create(const char *name, uint32_t size,\n+\t\t\t\t     uint32_t entry_size, uint32_t flags,\n+\t\t\t\t     mlx5_hlist_create_cb cb_create,\n+\t\t\t\t     mlx5_hlist_match_cb cb_match,\n+\t\t\t\t     mlx5_hlist_remove_cb cb_destroy);\n+\n+/**\n+ * Search an entry matching the key.\n+ *\n+ * Result returned might be destroyed by other thread, must use\n+ * this function only in main thread.\n+ *\n+ * @param h\n+ *   Pointer to the hast list table.\n+ * @param key\n+ *   Key for the searching entry.\n+ * @param ctx\n+ *   Common context parameter used by entry callback function.\n+ *\n+ * @return\n+ *   Pointer of the hlist entry if found, NULL otherwise.\n+ */\n+__rte_internal\n+struct mlx5_hlist_entry *mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key,\n+\t\t\t\t\t   void *ctx);\n+\n+/**\n+ * Insert an entry to the hash list table, the entry is only part of whole data\n+ * element and a 64B key is used for matching. User should construct the key or\n+ * give a calculated hash signature and guarantee there is no collision.\n+ *\n+ * @param h\n+ *   Pointer to the hast list table.\n+ * @param entry\n+ *   Entry to be inserted into the hash list table.\n+ * @param ctx\n+ *   Common context parameter used by callback function.\n+ *\n+ * @return\n+ *   registered entry on success, NULL otherwise\n+ */\n+__rte_internal\n+struct mlx5_hlist_entry *mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key,\n+\t\t\t\t\t     void *ctx);\n+\n+/**\n+ * Remove an entry from the hash list table. User should guarantee the validity\n+ * of the entry.\n+ *\n+ * @param h\n+ *   Pointer to the hast list table. (not used)\n+ * @param entry\n+ *   Entry to be removed from the hash list table.\n+ * @return\n+ *   0 on entry removed, 1 on entry still referenced.\n+ */\n+__rte_internal\n+int mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_hlist_entry *entry);\n+\n+/**\n+ * Destroy the hash list table, all the entries already inserted into the lists\n+ * will be handled by the callback function provided by the user (including\n+ * free if needed) before the table is freed.\n+ *\n+ * @param h\n+ *   Pointer to the hast list table.\n+ */\n+__rte_internal\n+void mlx5_hlist_destroy(struct mlx5_hlist *h);\n \n #endif /* RTE_PMD_MLX5_COMMON_UTILS_H_ */\ndiff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c\nindex c3b3b50b51..1b1227eb16 100644\n--- a/drivers/common/mlx5/mlx5_devx_cmds.c\n+++ b/drivers/common/mlx5/mlx5_devx_cmds.c\n@@ -9,7 +9,7 @@\n \n #include \"mlx5_prm.h\"\n #include \"mlx5_devx_cmds.h\"\n-#include \"mlx5_common_utils.h\"\n+#include \"mlx5_common_log.h\"\n #include \"mlx5_malloc.h\"\n \n \ndiff --git a/drivers/common/mlx5/mlx5_malloc.c b/drivers/common/mlx5/mlx5_malloc.c\nindex 9d30cedbaa..b19501e1bc 100644\n--- a/drivers/common/mlx5/mlx5_malloc.c\n+++ b/drivers/common/mlx5/mlx5_malloc.c\n@@ -8,7 +8,7 @@\n #include <stdbool.h>\n #include <string.h>\n \n-#include \"mlx5_common_utils.h\"\n+#include \"mlx5_common_log.h\"\n #include \"mlx5_common_os.h\"\n #include \"mlx5_malloc.h\"\n \ndiff --git a/drivers/common/mlx5/rte_common_mlx5_exports.def b/drivers/common/mlx5/rte_common_mlx5_exports.def\nindex fd62b806ca..f44ae61d52 100644\n--- a/drivers/common/mlx5/rte_common_mlx5_exports.def\n+++ b/drivers/common/mlx5/rte_common_mlx5_exports.def\n@@ -73,3 +73,10 @@ EXPORTS\n \tmlx5_os_reg_mr\n \tmlx5_os_umem_reg\n \tmlx5_os_umem_dereg\n+\n+\tmlx5_hlist_create\n+\tmlx5_hlist_lookup\n+\tmlx5_hlist_register\n+\tmlx5_hlist_unregister\n+\tmlx5_hlist_destroy\n+\ndiff --git a/drivers/common/mlx5/version.map b/drivers/common/mlx5/version.map\nindex 120be7a99d..5c2cc4dca9 100644\n--- a/drivers/common/mlx5/version.map\n+++ b/drivers/common/mlx5/version.map\n@@ -108,4 +108,10 @@ INTERNAL {\n \tmlx5_free;\n \n \tmlx5_pci_driver_register;\n+\n+\tmlx5_hlist_create;\n+\tmlx5_hlist_lookup;\n+\tmlx5_hlist_register;\n+\tmlx5_hlist_unregister;\n+\tmlx5_hlist_destroy;\n };\ndiff --git a/drivers/common/mlx5/windows/mlx5_common_os.c b/drivers/common/mlx5/windows/mlx5_common_os.c\nindex f2d781a965..2e6e172a96 100644\n--- a/drivers/common/mlx5/windows/mlx5_common_os.c\n+++ b/drivers/common/mlx5/windows/mlx5_common_os.c\n@@ -11,7 +11,7 @@\n #include <rte_errno.h>\n \n #include \"mlx5_devx_cmds.h\"\n-#include \"mlx5_common_utils.h\"\n+#include \"../mlx5_common_log.h\"\n #include \"mlx5_common.h\"\n #include \"mlx5_common_os.h\"\n #include \"mlx5_malloc.h\"\ndiff --git a/drivers/common/mlx5/windows/mlx5_glue.c b/drivers/common/mlx5/windows/mlx5_glue.c\nindex aef6d3b5f4..535487a8d4 100644\n--- a/drivers/common/mlx5/windows/mlx5_glue.c\n+++ b/drivers/common/mlx5/windows/mlx5_glue.c\n@@ -12,7 +12,7 @@\n #include <rte_malloc.h>\n \n #include \"mlx5_glue.h\"\n-#include \"mlx5_common_utils.h\"\n+#include \"../mlx5_common_log.h\"\n #include \"mlx5_win_ext.h\"\n \n /*\ndiff --git a/drivers/net/mlx5/mlx5_utils.c b/drivers/net/mlx5/mlx5_utils.c\nindex a39b5edddc..18fe23e4fb 100644\n--- a/drivers/net/mlx5/mlx5_utils.c\n+++ b/drivers/net/mlx5/mlx5_utils.c\n@@ -3,220 +3,11 @@\n  */\n \n #include <rte_malloc.h>\n-#include <rte_hash_crc.h>\n \n #include <mlx5_malloc.h>\n \n #include \"mlx5_utils.h\"\n \n-/********************* Hash List **********************/\n-\n-static struct mlx5_hlist_entry *\n-mlx5_hlist_default_create_cb(struct mlx5_hlist *h, uint64_t key __rte_unused,\n-\t\t\t     void *ctx __rte_unused)\n-{\n-\treturn mlx5_malloc(MLX5_MEM_ZERO, h->entry_sz, 0, SOCKET_ID_ANY);\n-}\n-\n-static void\n-mlx5_hlist_default_remove_cb(struct mlx5_hlist *h __rte_unused,\n-\t\t\t     struct mlx5_hlist_entry *entry)\n-{\n-\tmlx5_free(entry);\n-}\n-\n-struct mlx5_hlist *\n-mlx5_hlist_create(const char *name, uint32_t size, uint32_t entry_size,\n-\t\t  uint32_t flags, mlx5_hlist_create_cb cb_create,\n-\t\t  mlx5_hlist_match_cb cb_match, mlx5_hlist_remove_cb cb_remove)\n-{\n-\tstruct mlx5_hlist *h;\n-\tuint32_t act_size;\n-\tuint32_t alloc_size;\n-\tuint32_t i;\n-\n-\tif (!size || !cb_match || (!cb_create ^ !cb_remove))\n-\t\treturn NULL;\n-\t/* Align to the next power of 2, 32bits integer is enough now. */\n-\tif (!rte_is_power_of_2(size)) {\n-\t\tact_size = rte_align32pow2(size);\n-\t\tDRV_LOG(DEBUG, \"Size 0x%\" PRIX32 \" is not power of 2, \"\n-\t\t\t\"will be aligned to 0x%\" PRIX32 \".\", size, act_size);\n-\t} else {\n-\t\tact_size = size;\n-\t}\n-\talloc_size = sizeof(struct mlx5_hlist) +\n-\t\t     sizeof(struct mlx5_hlist_bucket) * act_size;\n-\t/* Using zmalloc, then no need to initialize the heads. */\n-\th = mlx5_malloc(MLX5_MEM_ZERO, alloc_size, RTE_CACHE_LINE_SIZE,\n-\t\t\tSOCKET_ID_ANY);\n-\tif (!h) {\n-\t\tDRV_LOG(ERR, \"No memory for hash list %s creation\",\n-\t\t\tname ? name : \"None\");\n-\t\treturn NULL;\n-\t}\n-\tif (name)\n-\t\tsnprintf(h->name, MLX5_HLIST_NAMESIZE, \"%s\", name);\n-\th->table_sz = act_size;\n-\th->mask = act_size - 1;\n-\th->entry_sz = entry_size;\n-\th->direct_key = !!(flags & MLX5_HLIST_DIRECT_KEY);\n-\th->write_most = !!(flags & MLX5_HLIST_WRITE_MOST);\n-\th->cb_create = cb_create ? cb_create : mlx5_hlist_default_create_cb;\n-\th->cb_match = cb_match;\n-\th->cb_remove = cb_remove ? cb_remove : mlx5_hlist_default_remove_cb;\n-\tfor (i = 0; i < act_size; i++)\n-\t\trte_rwlock_init(&h->buckets[i].lock);\n-\tDRV_LOG(DEBUG, \"Hash list with %s size 0x%\" PRIX32 \" is created.\",\n-\t\th->name, act_size);\n-\treturn h;\n-}\n-\n-static struct mlx5_hlist_entry *\n-__hlist_lookup(struct mlx5_hlist *h, uint64_t key, uint32_t idx,\n-\t       void *ctx, bool reuse)\n-{\n-\tstruct mlx5_hlist_head *first;\n-\tstruct mlx5_hlist_entry *node;\n-\n-\tMLX5_ASSERT(h);\n-\tfirst = &h->buckets[idx].head;\n-\tLIST_FOREACH(node, first, next) {\n-\t\tif (!h->cb_match(h, node, key, ctx)) {\n-\t\t\tif (reuse) {\n-\t\t\t\t__atomic_add_fetch(&node->ref_cnt, 1,\n-\t\t\t\t\t\t   __ATOMIC_RELAXED);\n-\t\t\t\tDRV_LOG(DEBUG, \"Hash list %s entry %p \"\n-\t\t\t\t\t\"reuse: %u.\",\n-\t\t\t\t\th->name, (void *)node, node->ref_cnt);\n-\t\t\t}\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\treturn node;\n-}\n-\n-static struct mlx5_hlist_entry *\n-hlist_lookup(struct mlx5_hlist *h, uint64_t key, uint32_t idx,\n-\t     void *ctx, bool reuse)\n-{\n-\tstruct mlx5_hlist_entry *node;\n-\n-\tMLX5_ASSERT(h);\n-\trte_rwlock_read_lock(&h->buckets[idx].lock);\n-\tnode = __hlist_lookup(h, key, idx, ctx, reuse);\n-\trte_rwlock_read_unlock(&h->buckets[idx].lock);\n-\treturn node;\n-}\n-\n-struct mlx5_hlist_entry *\n-mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key, void *ctx)\n-{\n-\tuint32_t idx;\n-\n-\tif (h->direct_key)\n-\t\tidx = (uint32_t)(key & h->mask);\n-\telse\n-\t\tidx = rte_hash_crc_8byte(key, 0) & h->mask;\n-\treturn hlist_lookup(h, key, idx, ctx, false);\n-}\n-\n-struct mlx5_hlist_entry*\n-mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key, void *ctx)\n-{\n-\tuint32_t idx;\n-\tstruct mlx5_hlist_head *first;\n-\tstruct mlx5_hlist_bucket *b;\n-\tstruct mlx5_hlist_entry *entry;\n-\tuint32_t prev_gen_cnt = 0;\n-\n-\tif (h->direct_key)\n-\t\tidx = (uint32_t)(key & h->mask);\n-\telse\n-\t\tidx = rte_hash_crc_8byte(key, 0) & h->mask;\n-\tMLX5_ASSERT(h);\n-\tb = &h->buckets[idx];\n-\t/* Use write lock directly for write-most list. */\n-\tif (!h->write_most) {\n-\t\tprev_gen_cnt = __atomic_load_n(&b->gen_cnt, __ATOMIC_ACQUIRE);\n-\t\tentry = hlist_lookup(h, key, idx, ctx, true);\n-\t\tif (entry)\n-\t\t\treturn entry;\n-\t}\n-\trte_rwlock_write_lock(&b->lock);\n-\t/* Check if the list changed by other threads. */\n-\tif (h->write_most ||\n-\t    prev_gen_cnt != __atomic_load_n(&b->gen_cnt, __ATOMIC_ACQUIRE)) {\n-\t\tentry = __hlist_lookup(h, key, idx, ctx, true);\n-\t\tif (entry)\n-\t\t\tgoto done;\n-\t}\n-\tfirst = &b->head;\n-\tentry = h->cb_create(h, key, ctx);\n-\tif (!entry) {\n-\t\trte_errno = ENOMEM;\n-\t\tDRV_LOG(DEBUG, \"Can't allocate hash list %s entry.\", h->name);\n-\t\tgoto done;\n-\t}\n-\tentry->idx = idx;\n-\tentry->ref_cnt = 1;\n-\tLIST_INSERT_HEAD(first, entry, next);\n-\t__atomic_add_fetch(&b->gen_cnt, 1, __ATOMIC_ACQ_REL);\n-\tDRV_LOG(DEBUG, \"Hash list %s entry %p new: %u.\",\n-\t\th->name, (void *)entry, entry->ref_cnt);\n-done:\n-\trte_rwlock_write_unlock(&b->lock);\n-\treturn entry;\n-}\n-\n-int\n-mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_hlist_entry *entry)\n-{\n-\tuint32_t idx = entry->idx;\n-\n-\trte_rwlock_write_lock(&h->buckets[idx].lock);\n-\tMLX5_ASSERT(entry && entry->ref_cnt && entry->next.le_prev);\n-\tDRV_LOG(DEBUG, \"Hash list %s entry %p deref: %u.\",\n-\t\th->name, (void *)entry, entry->ref_cnt);\n-\tif (--entry->ref_cnt) {\n-\t\trte_rwlock_write_unlock(&h->buckets[idx].lock);\n-\t\treturn 1;\n-\t}\n-\tLIST_REMOVE(entry, next);\n-\t/* Set to NULL to get rid of removing action for more than once. */\n-\tentry->next.le_prev = NULL;\n-\th->cb_remove(h, entry);\n-\trte_rwlock_write_unlock(&h->buckets[idx].lock);\n-\tDRV_LOG(DEBUG, \"Hash list %s entry %p removed.\",\n-\t\th->name, (void *)entry);\n-\treturn 0;\n-}\n-\n-void\n-mlx5_hlist_destroy(struct mlx5_hlist *h)\n-{\n-\tuint32_t idx;\n-\tstruct mlx5_hlist_entry *entry;\n-\n-\tMLX5_ASSERT(h);\n-\tfor (idx = 0; idx < h->table_sz; ++idx) {\n-\t\t/* No LIST_FOREACH_SAFE, using while instead. */\n-\t\twhile (!LIST_EMPTY(&h->buckets[idx].head)) {\n-\t\t\tentry = LIST_FIRST(&h->buckets[idx].head);\n-\t\t\tLIST_REMOVE(entry, next);\n-\t\t\t/*\n-\t\t\t * The owner of whole element which contains data entry\n-\t\t\t * is the user, so it's the user's duty to do the clean\n-\t\t\t * up and the free work because someone may not put the\n-\t\t\t * hlist entry at the beginning(suggested to locate at\n-\t\t\t * the beginning). Or else the default free function\n-\t\t\t * will be used.\n-\t\t\t */\n-\t\t\th->cb_remove(h, entry);\n-\t\t}\n-\t}\n-\tmlx5_free(h);\n-}\n \n /********************* Cache list ************************/\n \ndiff --git a/drivers/net/mlx5/mlx5_utils.h b/drivers/net/mlx5/mlx5_utils.h\nindex 5088c95e86..008a017402 100644\n--- a/drivers/net/mlx5/mlx5_utils.h\n+++ b/drivers/net/mlx5/mlx5_utils.h\n@@ -18,6 +18,7 @@\n #include <rte_bitmap.h>\n \n #include <mlx5_common.h>\n+#include <mlx5_common_utils.h>\n \n #include \"mlx5_defs.h\"\n \n@@ -261,199 +262,6 @@ log2above(unsigned int v)\n \treturn l + r;\n }\n \n-#define MLX5_HLIST_DIRECT_KEY 0x0001 /* Use the key directly as hash index. */\n-#define MLX5_HLIST_WRITE_MOST 0x0002 /* List mostly used for append new. */\n-\n-/** Maximum size of string for naming the hlist table. */\n-#define MLX5_HLIST_NAMESIZE\t\t\t32\n-\n-struct mlx5_hlist;\n-\n-/**\n- * Structure of the entry in the hash list, user should define its own struct\n- * that contains this in order to store the data. The 'key' is 64-bits right\n- * now and its user's responsibility to guarantee there is no collision.\n- */\n-struct mlx5_hlist_entry {\n-\tLIST_ENTRY(mlx5_hlist_entry) next; /* entry pointers in the list. */\n-\tuint32_t idx; /* Bucket index the entry belongs to. */\n-\tuint32_t ref_cnt; /* Reference count. */\n-};\n-\n-/** Structure for hash head. */\n-LIST_HEAD(mlx5_hlist_head, mlx5_hlist_entry);\n-\n-/**\n- * Type of callback function for entry removal.\n- *\n- * @param list\n- *   The hash list.\n- * @param entry\n- *   The entry in the list.\n- */\n-typedef void (*mlx5_hlist_remove_cb)(struct mlx5_hlist *list,\n-\t\t\t\t     struct mlx5_hlist_entry *entry);\n-\n-/**\n- * Type of function for user defined matching.\n- *\n- * @param list\n- *   The hash list.\n- * @param entry\n- *   The entry in the list.\n- * @param key\n- *   The new entry key.\n- * @param ctx\n- *   The pointer to new entry context.\n- *\n- * @return\n- *   0 if matching, non-zero number otherwise.\n- */\n-typedef int (*mlx5_hlist_match_cb)(struct mlx5_hlist *list,\n-\t\t\t\t   struct mlx5_hlist_entry *entry,\n-\t\t\t\t   uint64_t key, void *ctx);\n-\n-/**\n- * Type of function for user defined hash list entry creation.\n- *\n- * @param list\n- *   The hash list.\n- * @param key\n- *   The key of the new entry.\n- * @param ctx\n- *   The pointer to new entry context.\n- *\n- * @return\n- *   Pointer to allocated entry on success, NULL otherwise.\n- */\n-typedef struct mlx5_hlist_entry *(*mlx5_hlist_create_cb)\n-\t\t\t\t  (struct mlx5_hlist *list,\n-\t\t\t\t   uint64_t key, void *ctx);\n-\n-/* Hash list bucket head. */\n-struct mlx5_hlist_bucket {\n-\tstruct mlx5_hlist_head head; /* List head. */\n-\trte_rwlock_t lock; /* Bucket lock. */\n-\tuint32_t gen_cnt; /* List modification will update generation count. */\n-} __rte_cache_aligned;\n-\n-/**\n- * Hash list table structure\n- *\n- * Entry in hash list could be reused if entry already exists, reference\n- * count will increase and the existing entry returns.\n- *\n- * When destroy an entry from list, decrease reference count and only\n- * destroy when no further reference.\n- */\n-struct mlx5_hlist {\n-\tchar name[MLX5_HLIST_NAMESIZE]; /**< Name of the hash list. */\n-\t/**< number of heads, need to be power of 2. */\n-\tuint32_t table_sz;\n-\tuint32_t entry_sz; /**< Size of entry, used to allocate entry. */\n-\t/**< mask to get the index of the list heads. */\n-\tuint32_t mask;\n-\tbool direct_key; /* Use the new entry key directly as hash index. */\n-\tbool write_most; /* List mostly used for append new or destroy. */\n-\tvoid *ctx;\n-\tmlx5_hlist_create_cb cb_create; /**< entry create callback. */\n-\tmlx5_hlist_match_cb cb_match; /**< entry match callback. */\n-\tmlx5_hlist_remove_cb cb_remove; /**< entry remove callback. */\n-\tstruct mlx5_hlist_bucket buckets[] __rte_cache_aligned;\n-\t/**< list bucket arrays. */\n-};\n-\n-/**\n- * Create a hash list table, the user can specify the list heads array size\n- * of the table, now the size should be a power of 2 in order to get better\n- * distribution for the entries. Each entry is a part of the whole data element\n- * and the caller should be responsible for the data element's allocation and\n- * cleanup / free. Key of each entry will be calculated with CRC in order to\n- * generate a little fairer distribution.\n- *\n- * @param name\n- *   Name of the hash list(optional).\n- * @param size\n- *   Heads array size of the hash list.\n- * @param entry_size\n- *   Entry size to allocate if cb_create not specified.\n- * @param flags\n- *   The hash list attribute flags.\n- * @param cb_create\n- *   Callback function for entry create.\n- * @param cb_match\n- *   Callback function for entry match.\n- * @param cb_destroy\n- *   Callback function for entry destroy.\n- * @return\n- *   Pointer of the hash list table created, NULL on failure.\n- */\n-struct mlx5_hlist *mlx5_hlist_create(const char *name, uint32_t size,\n-\t\t\t\t     uint32_t entry_size, uint32_t flags,\n-\t\t\t\t     mlx5_hlist_create_cb cb_create,\n-\t\t\t\t     mlx5_hlist_match_cb cb_match,\n-\t\t\t\t     mlx5_hlist_remove_cb cb_destroy);\n-\n-/**\n- * Search an entry matching the key.\n- *\n- * Result returned might be destroyed by other thread, must use\n- * this function only in main thread.\n- *\n- * @param h\n- *   Pointer to the hast list table.\n- * @param key\n- *   Key for the searching entry.\n- * @param ctx\n- *   Common context parameter used by entry callback function.\n- *\n- * @return\n- *   Pointer of the hlist entry if found, NULL otherwise.\n- */\n-struct mlx5_hlist_entry *mlx5_hlist_lookup(struct mlx5_hlist *h, uint64_t key,\n-\t\t\t\t\t   void *ctx);\n-\n-/**\n- * Insert an entry to the hash list table, the entry is only part of whole data\n- * element and a 64B key is used for matching. User should construct the key or\n- * give a calculated hash signature and guarantee there is no collision.\n- *\n- * @param h\n- *   Pointer to the hast list table.\n- * @param entry\n- *   Entry to be inserted into the hash list table.\n- * @param ctx\n- *   Common context parameter used by callback function.\n- *\n- * @return\n- *   registered entry on success, NULL otherwise\n- */\n-struct mlx5_hlist_entry *mlx5_hlist_register(struct mlx5_hlist *h, uint64_t key,\n-\t\t\t\t\t     void *ctx);\n-\n-/**\n- * Remove an entry from the hash list table. User should guarantee the validity\n- * of the entry.\n- *\n- * @param h\n- *   Pointer to the hast list table. (not used)\n- * @param entry\n- *   Entry to be removed from the hash list table.\n- * @return\n- *   0 on entry removed, 1 on entry still referenced.\n- */\n-int mlx5_hlist_unregister(struct mlx5_hlist *h, struct mlx5_hlist_entry *entry);\n-\n-/**\n- * Destroy the hash list table, all the entries already inserted into the lists\n- * will be handled by the callback function provided by the user (including\n- * free if needed) before the table is freed.\n- *\n- * @param h\n- *   Pointer to the hast list table.\n- */\n-void mlx5_hlist_destroy(struct mlx5_hlist *h);\n-\n /************************ cache list *****************************/\n \n /** Maximum size of string for naming. */\n",
    "prefixes": [
        "11/24"
    ]
}