get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 71717,
    "url": "http://patches.dpdk.org/api/patches/71717/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1592465084-140601-2-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": "<1592465084-140601-2-git-send-email-suanmingm@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1592465084-140601-2-git-send-email-suanmingm@mellanox.com",
    "date": "2020-06-18T07:24:42",
    "name": "[1/3] net/mlx5: add Three-Level table utility",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "20d5bc17e3aec9cb36c2baa284cae63f53c568dc",
    "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/1592465084-140601-2-git-send-email-suanmingm@mellanox.com/mbox/",
    "series": [
        {
            "id": 10496,
            "url": "http://patches.dpdk.org/api/series/10496/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=10496",
            "date": "2020-06-18T07:24:41",
            "name": "net/mlx5: optimize single counter allocate",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/10496/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/71717/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/71717/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 0B7DEA04A5;\n\tThu, 18 Jun 2020 09:25:01 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id F33B41BE88;\n\tThu, 18 Jun 2020 09:24:54 +0200 (CEST)",
            "from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130])\n by dpdk.org (Postfix) with ESMTP id 3DF37F12\n for <dev@dpdk.org>; Thu, 18 Jun 2020 09:24:53 +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, 18 Jun 2020 15:24:42 +0800",
        "Message-Id": "<1592465084-140601-2-git-send-email-suanmingm@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1592465084-140601-1-git-send-email-suanmingm@mellanox.com>",
        "References": "<1592465084-140601-1-git-send-email-suanmingm@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH 1/3] net/mlx5: add Three-Level table utility",
        "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": "For the case which data is linked with sequence increased index, the\narray table will be more efficient than hash table once need to search\none data entry in large numbers of entries. Since the traditional hash\ntables has fixed table size, when huge numbers of data saved to the hash\ntable, it also comes lots of hash conflict.\n\nBut simple array table also has fixed size, allocates all the needed\nmemory at once will waste lots of memory. For the case don't know the\nexactly number of entries will be impossible to allocate the array.\n\nThen the multiple level table helps to balance the two disadvantages.\nAllocate a global high level table with sub table entries at first,\nthe global table contains the sub table entries, and the sub table will\nbe allocated only once the corresponding index entry need to be saved.\ne.g. for up to 32-bits index, three level table with 10-10-12 splitting,\nwith sequence increased index, the memory grows with every 4K entries.\n\nThe currently implementation introduces 10-10-12 32-bits splitting\nThree-Level table to help the cases which have millions of entries to\nsave. The index entries can be addressed directly by the index, no\nsearch will be needed.\n\nSigned-off-by: Suanming Mou <suanmingm@mellanox.com>\nAcked-by: Matan Azrad <matan@mellanox.com>\nAcked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>\n---\n drivers/net/mlx5/mlx5_utils.c | 276 ++++++++++++++++++++++++++++++++++++++++++\n drivers/net/mlx5/mlx5_utils.h | 165 +++++++++++++++++++++++++\n 2 files changed, 441 insertions(+)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_utils.c b/drivers/net/mlx5/mlx5_utils.c\nindex d29fbcb..5c76b29 100644\n--- a/drivers/net/mlx5/mlx5_utils.c\n+++ b/drivers/net/mlx5/mlx5_utils.c\n@@ -482,3 +482,279 @@ struct mlx5_indexed_pool *\n \t       pool->trunk_empty, pool->trunk_avail, pool->trunk_free);\n #endif\n }\n+\n+struct mlx5_l3t_tbl *\n+mlx5_l3t_create(enum mlx5_l3t_type type)\n+{\n+\tstruct mlx5_l3t_tbl *tbl;\n+\tstruct mlx5_indexed_pool_config l3t_ip_cfg = {\n+\t\t.trunk_size = 16,\n+\t\t.grow_trunk = 6,\n+\t\t.grow_shift = 1,\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};\n+\n+\tif (type >= MLX5_L3T_TYPE_MAX) {\n+\t\trte_errno = EINVAL;\n+\t\treturn NULL;\n+\t}\n+\ttbl = rte_zmalloc(NULL, sizeof(struct mlx5_l3t_tbl), 1);\n+\tif (!tbl) {\n+\t\trte_errno = ENOMEM;\n+\t\treturn NULL;\n+\t}\n+\ttbl->type = type;\n+\tswitch (type) {\n+\tcase MLX5_L3T_TYPE_WORD:\n+\t\tl3t_ip_cfg.size = sizeof(struct mlx5_l3t_entry_word) +\n+\t\t\t\t  sizeof(uint16_t) * MLX5_L3T_ET_SIZE;\n+\t\tl3t_ip_cfg.type = \"mlx5_l3t_e_tbl_w\";\n+\t\tbreak;\n+\tcase MLX5_L3T_TYPE_DWORD:\n+\t\tl3t_ip_cfg.size = sizeof(struct mlx5_l3t_entry_dword) +\n+\t\t\t\t  sizeof(uint32_t) * MLX5_L3T_ET_SIZE;\n+\t\tl3t_ip_cfg.type = \"mlx5_l3t_e_tbl_dw\";\n+\t\tbreak;\n+\tcase MLX5_L3T_TYPE_QWORD:\n+\t\tl3t_ip_cfg.size = sizeof(struct mlx5_l3t_entry_qword) +\n+\t\t\t\t  sizeof(uint64_t) * MLX5_L3T_ET_SIZE;\n+\t\tl3t_ip_cfg.type = \"mlx5_l3t_e_tbl_qw\";\n+\t\tbreak;\n+\tdefault:\n+\t\tl3t_ip_cfg.size = sizeof(struct mlx5_l3t_entry_ptr) +\n+\t\t\t\t  sizeof(void *) * MLX5_L3T_ET_SIZE;\n+\t\tl3t_ip_cfg.type = \"mlx5_l3t_e_tbl_tpr\";\n+\t\tbreak;\n+\t}\n+\ttbl->eip = mlx5_ipool_create(&l3t_ip_cfg);\n+\tif (!tbl->eip) {\n+\t\trte_errno = ENOMEM;\n+\t\trte_free(tbl);\n+\t\ttbl = NULL;\n+\t}\n+\treturn tbl;\n+}\n+\n+void\n+mlx5_l3t_destroy(struct mlx5_l3t_tbl *tbl)\n+{\n+\tstruct mlx5_l3t_level_tbl *g_tbl, *m_tbl;\n+\tuint32_t i, j;\n+\n+\tif (!tbl)\n+\t\treturn;\n+\tg_tbl = tbl->tbl;\n+\tif (g_tbl) {\n+\t\tfor (i = 0; i < MLX5_L3T_GT_SIZE; i++) {\n+\t\t\tm_tbl = g_tbl->tbl[i];\n+\t\t\tif (!m_tbl)\n+\t\t\t\tcontinue;\n+\t\t\tfor (j = 0; j < MLX5_L3T_MT_SIZE; j++) {\n+\t\t\t\tif (!m_tbl->tbl[j])\n+\t\t\t\t\tcontinue;\n+\t\t\t\tMLX5_ASSERT(!((struct mlx5_l3t_entry_word *)\n+\t\t\t\t\t    m_tbl->tbl[j])->ref_cnt);\n+\t\t\t\tmlx5_ipool_free(tbl->eip,\n+\t\t\t\t\t\t((struct mlx5_l3t_entry_word *)\n+\t\t\t\t\t\tm_tbl->tbl[j])->idx);\n+\t\t\t\tm_tbl->tbl[j] = 0;\n+\t\t\t\tif (!(--m_tbl->ref_cnt))\n+\t\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tMLX5_ASSERT(!m_tbl->ref_cnt);\n+\t\t\trte_free(g_tbl->tbl[i]);\n+\t\t\tg_tbl->tbl[i] = 0;\n+\t\t\tif (!(--g_tbl->ref_cnt))\n+\t\t\t\tbreak;\n+\t\t}\n+\t\tMLX5_ASSERT(!g_tbl->ref_cnt);\n+\t\trte_free(tbl->tbl);\n+\t\ttbl->tbl = 0;\n+\t}\n+\tmlx5_ipool_destroy(tbl->eip);\n+\trte_free(tbl);\n+}\n+\n+uint32_t\n+mlx5_l3t_get_entry(struct mlx5_l3t_tbl *tbl, uint32_t idx,\n+\t\t   union mlx5_l3t_data *data)\n+{\n+\tstruct mlx5_l3t_level_tbl *g_tbl, *m_tbl;\n+\tvoid *e_tbl;\n+\tuint32_t entry_idx;\n+\n+\tg_tbl = tbl->tbl;\n+\tif (!g_tbl)\n+\t\treturn -1;\n+\tm_tbl = g_tbl->tbl[(idx >> MLX5_L3T_GT_OFFSET) & MLX5_L3T_GT_MASK];\n+\tif (!m_tbl)\n+\t\treturn -1;\n+\te_tbl = m_tbl->tbl[(idx >> MLX5_L3T_MT_OFFSET) & MLX5_L3T_MT_MASK];\n+\tif (!e_tbl)\n+\t\treturn -1;\n+\tentry_idx = idx & MLX5_L3T_ET_MASK;\n+\tswitch (tbl->type) {\n+\tcase MLX5_L3T_TYPE_WORD:\n+\t\tdata->word = ((struct mlx5_l3t_entry_word *)e_tbl)->entry\n+\t\t\t     [entry_idx];\n+\t\tbreak;\n+\tcase MLX5_L3T_TYPE_DWORD:\n+\t\tdata->dword = ((struct mlx5_l3t_entry_dword *)e_tbl)->entry\n+\t\t\t     [entry_idx];\n+\t\tbreak;\n+\tcase MLX5_L3T_TYPE_QWORD:\n+\t\tdata->qword = ((struct mlx5_l3t_entry_qword *)e_tbl)->entry\n+\t\t\t      [entry_idx];\n+\t\tbreak;\n+\tdefault:\n+\t\tdata->ptr = ((struct mlx5_l3t_entry_ptr *)e_tbl)->entry\n+\t\t\t    [entry_idx];\n+\t\tbreak;\n+\t}\n+\treturn 0;\n+}\n+\n+void\n+mlx5_l3t_clear_entry(struct mlx5_l3t_tbl *tbl, uint32_t idx)\n+{\n+\tstruct mlx5_l3t_level_tbl *g_tbl, *m_tbl;\n+\tstruct mlx5_l3t_entry_word *w_e_tbl;\n+\tstruct mlx5_l3t_entry_dword *dw_e_tbl;\n+\tstruct mlx5_l3t_entry_qword *qw_e_tbl;\n+\tstruct mlx5_l3t_entry_ptr *ptr_e_tbl;\n+\tvoid *e_tbl;\n+\tuint32_t entry_idx;\n+\tuint64_t ref_cnt;\n+\n+\tg_tbl = tbl->tbl;\n+\tif (!g_tbl)\n+\t\treturn;\n+\tm_tbl = g_tbl->tbl[(idx >> MLX5_L3T_GT_OFFSET) & MLX5_L3T_GT_MASK];\n+\tif (!m_tbl)\n+\t\treturn;\n+\te_tbl = m_tbl->tbl[(idx >> MLX5_L3T_MT_OFFSET) & MLX5_L3T_MT_MASK];\n+\tif (!e_tbl)\n+\t\treturn;\n+\tentry_idx = idx & MLX5_L3T_ET_MASK;\n+\tswitch (tbl->type) {\n+\tcase MLX5_L3T_TYPE_WORD:\n+\t\tw_e_tbl = (struct mlx5_l3t_entry_word *)e_tbl;\n+\t\tw_e_tbl->entry[entry_idx] = 0;\n+\t\tref_cnt = --w_e_tbl->ref_cnt;\n+\t\tbreak;\n+\tcase MLX5_L3T_TYPE_DWORD:\n+\t\tdw_e_tbl = (struct mlx5_l3t_entry_dword *)e_tbl;\n+\t\tdw_e_tbl->entry[entry_idx] = 0;\n+\t\tref_cnt = --dw_e_tbl->ref_cnt;\n+\t\tbreak;\n+\tcase MLX5_L3T_TYPE_QWORD:\n+\t\tqw_e_tbl = (struct mlx5_l3t_entry_qword *)e_tbl;\n+\t\tqw_e_tbl->entry[entry_idx] = 0;\n+\t\tref_cnt = --qw_e_tbl->ref_cnt;\n+\t\tbreak;\n+\tdefault:\n+\t\tptr_e_tbl = (struct mlx5_l3t_entry_ptr *)e_tbl;\n+\t\tptr_e_tbl->entry[entry_idx] = NULL;\n+\t\tref_cnt = --ptr_e_tbl->ref_cnt;\n+\t\tbreak;\n+\t}\n+\tif (!ref_cnt) {\n+\t\tmlx5_ipool_free(tbl->eip,\n+\t\t\t\t((struct mlx5_l3t_entry_word *)e_tbl)->idx);\n+\t\tm_tbl->tbl[(idx >> MLX5_L3T_MT_OFFSET) & MLX5_L3T_MT_MASK] =\n+\t\t\t\t\t\t\t\t\tNULL;\n+\t\tif (!(--m_tbl->ref_cnt)) {\n+\t\t\trte_free(m_tbl);\n+\t\t\tg_tbl->tbl\n+\t\t\t[(idx >> MLX5_L3T_GT_OFFSET) & MLX5_L3T_GT_MASK] = NULL;\n+\t\t\tif (!(--g_tbl->ref_cnt)) {\n+\t\t\t\trte_free(g_tbl);\n+\t\t\t\ttbl->tbl = 0;\n+\t\t\t}\n+\t\t}\n+\t}\n+}\n+\n+uint32_t\n+mlx5_l3t_set_entry(struct mlx5_l3t_tbl *tbl, uint32_t idx,\n+\t\t   union mlx5_l3t_data *data)\n+{\n+\tstruct mlx5_l3t_level_tbl *g_tbl, *m_tbl;\n+\tstruct mlx5_l3t_entry_word *w_e_tbl;\n+\tstruct mlx5_l3t_entry_dword *dw_e_tbl;\n+\tstruct mlx5_l3t_entry_qword *qw_e_tbl;\n+\tstruct mlx5_l3t_entry_ptr *ptr_e_tbl;\n+\tvoid *e_tbl;\n+\tuint32_t entry_idx, tbl_idx = 0;\n+\n+\t/* Check the global table, create it if empty. */\n+\tg_tbl = tbl->tbl;\n+\tif (!g_tbl) {\n+\t\tg_tbl = rte_zmalloc(NULL, sizeof(struct mlx5_l3t_level_tbl) +\n+\t\t\t\t    sizeof(void *) * MLX5_L3T_GT_SIZE, 1);\n+\t\tif (!g_tbl) {\n+\t\t\trte_errno = ENOMEM;\n+\t\t\treturn -1;\n+\t\t}\n+\t\ttbl->tbl = g_tbl;\n+\t}\n+\t/*\n+\t * Check the middle table, create it if empty. Ref_cnt will be\n+\t * increased if new sub table created.\n+\t */\n+\tm_tbl = g_tbl->tbl[(idx >> MLX5_L3T_GT_OFFSET) & MLX5_L3T_GT_MASK];\n+\tif (!m_tbl) {\n+\t\tm_tbl = rte_zmalloc(NULL, sizeof(struct mlx5_l3t_level_tbl) +\n+\t\t\t\t    sizeof(void *) * MLX5_L3T_MT_SIZE, 1);\n+\t\tif (!m_tbl) {\n+\t\t\trte_errno = ENOMEM;\n+\t\t\treturn -1;\n+\t\t}\n+\t\tg_tbl->tbl[(idx >> MLX5_L3T_GT_OFFSET) & MLX5_L3T_GT_MASK] =\n+\t\t\t\t\t\t\t\t\tm_tbl;\n+\t\tg_tbl->ref_cnt++;\n+\t}\n+\t/*\n+\t * Check the entry table, create it if empty. Ref_cnt will be\n+\t * increased if new sub entry table created.\n+\t */\n+\te_tbl = m_tbl->tbl[(idx >> MLX5_L3T_MT_OFFSET) & MLX5_L3T_MT_MASK];\n+\tif (!e_tbl) {\n+\t\te_tbl = mlx5_ipool_zmalloc(tbl->eip, &tbl_idx);\n+\t\tif (!e_tbl) {\n+\t\t\trte_errno = ENOMEM;\n+\t\t\treturn -1;\n+\t\t}\n+\t\t((struct mlx5_l3t_entry_word *)e_tbl)->idx = tbl_idx;\n+\t\tm_tbl->tbl[(idx >> MLX5_L3T_MT_OFFSET) & MLX5_L3T_MT_MASK] =\n+\t\t\t\t\t\t\t\t\te_tbl;\n+\t\tm_tbl->ref_cnt++;\n+\t}\n+\tentry_idx = idx & MLX5_L3T_ET_MASK;\n+\tswitch (tbl->type) {\n+\tcase MLX5_L3T_TYPE_WORD:\n+\t\tw_e_tbl = (struct mlx5_l3t_entry_word *)e_tbl;\n+\t\tw_e_tbl->entry[entry_idx] = data->word;\n+\t\tw_e_tbl->ref_cnt++;\n+\t\tbreak;\n+\tcase MLX5_L3T_TYPE_DWORD:\n+\t\tdw_e_tbl = (struct mlx5_l3t_entry_dword *)e_tbl;\n+\t\tdw_e_tbl->entry[entry_idx] = data->dword;\n+\t\tdw_e_tbl->ref_cnt++;\n+\t\tbreak;\n+\tcase MLX5_L3T_TYPE_QWORD:\n+\t\tqw_e_tbl = (struct mlx5_l3t_entry_qword *)e_tbl;\n+\t\tqw_e_tbl->entry[entry_idx] = data->qword;\n+\t\tqw_e_tbl->ref_cnt++;\n+\t\tbreak;\n+\tdefault:\n+\t\tptr_e_tbl = (struct mlx5_l3t_entry_ptr *)e_tbl;\n+\t\tptr_e_tbl->entry[entry_idx] = data->ptr;\n+\t\tptr_e_tbl->ref_cnt++;\n+\t\tbreak;\n+\t}\n+\treturn 0;\n+}\ndiff --git a/drivers/net/mlx5/mlx5_utils.h b/drivers/net/mlx5/mlx5_utils.h\nindex f4ec151..18cfc2c 100644\n--- a/drivers/net/mlx5/mlx5_utils.h\n+++ b/drivers/net/mlx5/mlx5_utils.h\n@@ -55,6 +55,106 @@\n \t (((val) & (from)) * ((to) / (from))))\n \n /*\n+ * For the case which data is linked with sequence increased index, the\n+ * array table will be more efficiect than hash table once need to serarch\n+ * one data entry in large numbers of entries. Since the traditional hash\n+ * tables has fixed table size, when huge numbers of data saved to the hash\n+ * table, it also comes lots of hash conflict.\n+ *\n+ * But simple array table also has fixed size, allocates all the needed\n+ * memory at once will waste lots of memory. For the case don't know the\n+ * exactly number of entries will be impossible to allocate the array.\n+ *\n+ * Then the mulitple level table helps to balance the two disadvantages.\n+ * Allocate a global high level table with sub table entries at first,\n+ * the global table contains the sub table entries, and the sub table will\n+ * be allocated only once the corresponding index entry need to be saved.\n+ * e.g. for up to 32-bits index, three level table with 10-10-12 splitting,\n+ * with sequence increased index, the memory grows with every 4K entries.\n+ *\n+ * The currently implementation introduces 10-10-12 32-bits splitting\n+ * Three-Level table to help the cases which have millions of enties to\n+ * save. The index entries can be addressed directly by the index, no\n+ * search will be needed.q\n+ */\n+\n+/* L3 table global table define. */\n+#define MLX5_L3T_GT_OFFSET 22\n+#define MLX5_L3T_GT_SIZE (1 << 10)\n+#define MLX5_L3T_GT_MASK (MLX5_L3T_GT_SIZE - 1)\n+\n+/* L3 table middle table define. */\n+#define MLX5_L3T_MT_OFFSET 12\n+#define MLX5_L3T_MT_SIZE (1 << 10)\n+#define MLX5_L3T_MT_MASK (MLX5_L3T_MT_SIZE - 1)\n+\n+/* L3 table entry table define. */\n+#define MLX5_L3T_ET_OFFSET 0\n+#define MLX5_L3T_ET_SIZE (1 << 12)\n+#define MLX5_L3T_ET_MASK (MLX5_L3T_ET_SIZE - 1)\n+\n+/* L3 table type. */\n+enum mlx5_l3t_type {\n+\tMLX5_L3T_TYPE_WORD = 0,\n+\tMLX5_L3T_TYPE_DWORD,\n+\tMLX5_L3T_TYPE_QWORD,\n+\tMLX5_L3T_TYPE_PTR,\n+\tMLX5_L3T_TYPE_MAX,\n+};\n+\n+struct mlx5_indexed_pool;\n+\n+/* Generic data struct. */\n+union mlx5_l3t_data {\n+\tuint16_t word;\n+\tuint32_t dword;\n+\tuint64_t qword;\n+\tvoid *ptr;\n+};\n+\n+/* L3 level table data structure. */\n+struct mlx5_l3t_level_tbl {\n+\tuint64_t ref_cnt; /* Table ref_cnt. */\n+\tvoid *tbl[]; /* Table array. */\n+};\n+\n+/* L3 word entry table data structure. */\n+struct mlx5_l3t_entry_word {\n+\tuint32_t idx; /* Table index. */\n+\tuint64_t ref_cnt; /* Table ref_cnt. */\n+\tuint16_t entry[]; /* Entry arrary. */\n+};\n+\n+/* L3 double word entry table data structure. */\n+struct mlx5_l3t_entry_dword {\n+\tuint32_t idx; /* Table index. */\n+\tuint64_t ref_cnt; /* Table ref_cnt. */\n+\tuint32_t entry[]; /* Entry arrary. */\n+};\n+\n+/* L3 quad word entry table data structure. */\n+struct mlx5_l3t_entry_qword {\n+\tuint32_t idx; /* Table index. */\n+\tuint64_t ref_cnt; /* Table ref_cnt. */\n+\tuint64_t entry[]; /* Entry arrary. */\n+};\n+\n+/* L3 pointer entry table data structure. */\n+struct mlx5_l3t_entry_ptr {\n+\tuint32_t idx; /* Table index. */\n+\tuint64_t ref_cnt; /* Table ref_cnt. */\n+\tvoid *entry[]; /* Entry arrary. */\n+};\n+\n+/* L3 table data structure. */\n+struct mlx5_l3t_tbl {\n+\tenum mlx5_l3t_type type; /* Table type. */\n+\tstruct mlx5_indexed_pool *eip;\n+\t/* Table index pool handles. */\n+\tstruct mlx5_l3t_level_tbl *tbl; /* Global table index. */\n+};\n+\n+/*\n  * The indexed memory entry index is made up of trunk index and offset of\n  * the entry in the trunk. Since the entry index is 32 bits, in case user\n  * prefers to have small trunks, user can change the macro below to a big\n@@ -345,6 +445,71 @@ struct mlx5_indexed_pool *\n  */\n void mlx5_ipool_dump(struct mlx5_indexed_pool *pool);\n \n+/**\n+ * This function allocates new empty Three-level table.\n+ *\n+ * @param type\n+ *   The l3t can set as word, double word, quad word or pointer with index.\n+ *\n+ * @return\n+ *   - Pointer to the allocated l3t.\n+ *   - NULL on error. Not enough memory, or invalid arguments.\n+ */\n+struct mlx5_l3t_tbl *mlx5_l3t_create(enum mlx5_l3t_type type);\n+\n+/**\n+ * This function destroys Three-level table.\n+ *\n+ * @param tbl\n+ *   Pointer to the l3t.\n+ */\n+void mlx5_l3t_destroy(struct mlx5_l3t_tbl *tbl);\n+\n+/**\n+ * This function gets the index entry from Three-level table.\n+ *\n+ * @param tbl\n+ *   Pointer to the l3t.\n+ * @param idx\n+ *   Index to the entry.\n+ * @param data\n+ *   Pointer to the memory which saves the entry data.\n+ *   When function call returns 0, data contains the entry data get from\n+ *   l3t.\n+ *   When function call returns -1, data is not modified.\n+ *\n+ * @return\n+ *   0 if success, -1 on error.\n+ */\n+\n+uint32_t mlx5_l3t_get_entry(struct mlx5_l3t_tbl *tbl, uint32_t idx,\n+\t\t\t    union mlx5_l3t_data *data);\n+/**\n+ * This function clears the index entry from Three-level table.\n+ *\n+ * @param tbl\n+ *   Pointer to the l3t.\n+ * @param idx\n+ *   Index to the entry.\n+ */\n+void mlx5_l3t_clear_entry(struct mlx5_l3t_tbl *tbl, uint32_t idx);\n+\n+/**\n+ * This function gets the index entry from Three-level table.\n+ *\n+ * @param tbl\n+ *   Pointer to the l3t.\n+ * @param idx\n+ *   Index to the entry.\n+ * @param data\n+ *   Pointer to the memory which contains the entry data save to l3t.\n+ *\n+ * @return\n+ *   0 if success, -1 on error.\n+ */\n+uint32_t mlx5_l3t_set_entry(struct mlx5_l3t_tbl *tbl, uint32_t idx,\n+\t\t\t    union mlx5_l3t_data *data);\n+\n /*\n  * Macros for linked list based on indexed memory.\n  * Example data structure:\n",
    "prefixes": [
        "1/3"
    ]
}