get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 68228,
    "url": "http://patchwork.dpdk.org/api/patches/68228/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/1586740309-449310-3-git-send-email-suanmingm@mellanox.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<1586740309-449310-3-git-send-email-suanmingm@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1586740309-449310-3-git-send-email-suanmingm@mellanox.com",
    "date": "2020-04-13T01:11:41",
    "name": "[02/10] net/mlx5: add trunk dynamic grow for indexed pool",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "f15d20efa5f1c0848c4b26fcff8e51c8ca2c431b",
    "submitter": {
        "id": 1358,
        "url": "http://patchwork.dpdk.org/api/people/1358/?format=api",
        "name": "Suanming Mou",
        "email": "suanmingm@mellanox.com"
    },
    "delegate": {
        "id": 3268,
        "url": "http://patchwork.dpdk.org/api/users/3268/?format=api",
        "username": "rasland",
        "first_name": "Raslan",
        "last_name": "Darawsheh",
        "email": "rasland@nvidia.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/1586740309-449310-3-git-send-email-suanmingm@mellanox.com/mbox/",
    "series": [
        {
            "id": 9321,
            "url": "http://patchwork.dpdk.org/api/series/9321/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=9321",
            "date": "2020-04-13T01:11:39",
            "name": "net/mlx5: optimize flow resource allocation",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/9321/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/68228/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/68228/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 40FF2A0577;\n\tMon, 13 Apr 2020 03:12:19 +0200 (CEST)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 026DE2C54;\n\tMon, 13 Apr 2020 03:12:02 +0200 (CEST)",
            "from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130])\n by dpdk.org (Postfix) with ESMTP id 965D72BAB\n for <dev@dpdk.org>; Mon, 13 Apr 2020 03:11:59 +0200 (CEST)"
        ],
        "From": "Suanming Mou <suanmingm@mellanox.com>",
        "To": "Matan Azrad <matan@mellanox.com>, Shahaf Shuler <shahafs@mellanox.com>,\n Viacheslav Ovsiienko <viacheslavo@mellanox.com>",
        "Cc": "rasland@mellanox.com,\n\tdev@dpdk.org",
        "Date": "Mon, 13 Apr 2020 09:11:41 +0800",
        "Message-Id": "<1586740309-449310-3-git-send-email-suanmingm@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1586740309-449310-1-git-send-email-suanmingm@mellanox.com>",
        "References": "<1586740309-449310-1-git-send-email-suanmingm@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH 02/10] net/mlx5: add trunk dynamic grow for\n\tindexed pool",
        "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 add trunk dynamic grow for the indexed pool.\n\nIn case for pools which are not sure the entry number needed, pools can\nbe configured in increase progressively mode. It means the trunk size\nwill be increased dynamically one after one, then reach a stable value.\nIt saves memory to avoid allocate a very big trunk at beginning.\n\nUser should set both the grow_shift and grow_trunk to help the trunk grow\nworks. Keep one or both grow_shift and grow_trunk as 0 makes the trunk\nwork as fixed size.\n\nSigned-off-by: Suanming Mou <suanmingm@mellanox.com>\nAcked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>\n---\n drivers/net/mlx5/mlx5_utils.c | 105 +++++++++++++++++++++++++++++++++++-------\n drivers/net/mlx5/mlx5_utils.h |  23 +++++++--\n 2 files changed, 108 insertions(+), 20 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_utils.c b/drivers/net/mlx5/mlx5_utils.c\nindex 4cab7f0..e63921d 100644\n--- a/drivers/net/mlx5/mlx5_utils.c\n+++ b/drivers/net/mlx5/mlx5_utils.c\n@@ -132,16 +132,69 @@ struct mlx5_hlist_entry *\n \t\trte_spinlock_unlock(&pool->lock);\n }\n \n+static inline uint32_t\n+mlx5_trunk_idx_get(struct mlx5_indexed_pool *pool, uint32_t entry_idx)\n+{\n+\tstruct mlx5_indexed_pool_config *cfg = &pool->cfg;\n+\tuint32_t trunk_idx = 0;\n+\tuint32_t i;\n+\n+\tif (!cfg->grow_trunk)\n+\t\treturn entry_idx / cfg->trunk_size;\n+\tif (entry_idx >= pool->grow_tbl[cfg->grow_trunk - 1]) {\n+\t\ttrunk_idx = (entry_idx - pool->grow_tbl[cfg->grow_trunk - 1]) /\n+\t\t\t    (cfg->trunk_size << (cfg->grow_shift *\n+\t\t\t    cfg->grow_trunk)) + cfg->grow_trunk;\n+\t} else {\n+\t\tfor (i = 0; i < cfg->grow_trunk; i++) {\n+\t\t\tif (entry_idx < pool->grow_tbl[i])\n+\t\t\t\tbreak;\n+\t\t}\n+\t\ttrunk_idx = i;\n+\t}\n+\treturn trunk_idx;\n+}\n+\n+static inline uint32_t\n+mlx5_trunk_size_get(struct mlx5_indexed_pool *pool, uint32_t trunk_idx)\n+{\n+\tstruct mlx5_indexed_pool_config *cfg = &pool->cfg;\n+\n+\treturn cfg->trunk_size << (cfg->grow_shift *\n+\t       (trunk_idx > cfg->grow_trunk ? cfg->grow_trunk : trunk_idx));\n+}\n+\n+static inline uint32_t\n+mlx5_trunk_idx_offset_get(struct mlx5_indexed_pool *pool, uint32_t trunk_idx)\n+{\n+\tstruct mlx5_indexed_pool_config *cfg = &pool->cfg;\n+\tuint32_t offset = 0;\n+\n+\tif (!trunk_idx)\n+\t\treturn 0;\n+\tif (!cfg->grow_trunk)\n+\t\treturn cfg->trunk_size * trunk_idx;\n+\tif (trunk_idx < cfg->grow_trunk)\n+\t\toffset = pool->grow_tbl[trunk_idx - 1];\n+\telse\n+\t\toffset = pool->grow_tbl[cfg->grow_trunk - 1] +\n+\t\t\t (cfg->trunk_size << (cfg->grow_shift *\n+\t\t\t cfg->grow_trunk)) * (trunk_idx - cfg->grow_trunk);\n+\treturn offset;\n+}\n+\n struct mlx5_indexed_pool *\n mlx5_ipool_create(struct mlx5_indexed_pool_config *cfg)\n {\n \tstruct mlx5_indexed_pool *pool;\n+\tuint32_t i;\n \n \tif (!cfg || !cfg->size || (!cfg->malloc ^ !cfg->free) ||\n \t    (cfg->trunk_size && ((cfg->trunk_size & (cfg->trunk_size - 1)) ||\n \t    ((__builtin_ffs(cfg->trunk_size) + TRUNK_IDX_BITS) > 32))))\n \t\treturn NULL;\n-\tpool = rte_zmalloc(\"mlx5_ipool\", sizeof(*pool), RTE_CACHE_LINE_SIZE);\n+\tpool = rte_zmalloc(\"mlx5_ipool\", sizeof(*pool) + cfg->grow_trunk *\n+\t\t\t\tsizeof(pool->grow_tbl[0]), RTE_CACHE_LINE_SIZE);\n \tif (!pool)\n \t\treturn NULL;\n \tpool->cfg = *cfg;\n@@ -154,6 +207,15 @@ struct mlx5_indexed_pool *\n \tpool->free_list = TRUNK_INVALID;\n \tif (pool->cfg.need_lock)\n \t\trte_spinlock_init(&pool->lock);\n+\t/*\n+\t * Initialize the dynamic grow trunk size lookup table to have a quick\n+\t * lookup for the trunk entry index offset.\n+\t */\n+\tfor (i = 0; i < cfg->grow_trunk; i++) {\n+\t\tpool->grow_tbl[i] = cfg->trunk_size << (cfg->grow_shift * i);\n+\t\tif (i > 0)\n+\t\t\tpool->grow_tbl[i] += pool->grow_tbl[i - 1];\n+\t}\n \treturn pool;\n }\n \n@@ -164,6 +226,7 @@ struct mlx5_indexed_pool *\n \tstruct mlx5_indexed_trunk **trunk_tmp;\n \tstruct mlx5_indexed_trunk **p;\n \tsize_t trunk_size = 0;\n+\tsize_t data_size;\n \tsize_t bmp_size;\n \tuint32_t idx;\n \n@@ -193,23 +256,23 @@ struct mlx5_indexed_pool *\n \t}\n \tidx = pool->n_trunk_valid;\n \ttrunk_size += sizeof(*trunk);\n-\tbmp_size = rte_bitmap_get_memory_footprint(pool->cfg.trunk_size);\n-\ttrunk_size += pool->cfg.trunk_size * pool->cfg.size + bmp_size;\n+\tdata_size = mlx5_trunk_size_get(pool, idx);\n+\tbmp_size = rte_bitmap_get_memory_footprint(data_size);\n+\ttrunk_size += data_size * pool->cfg.size + bmp_size;\n \ttrunk = pool->cfg.malloc(pool->cfg.type, trunk_size,\n \t\t\t\t RTE_CACHE_LINE_SIZE, rte_socket_id());\n \tif (!trunk)\n \t\treturn -ENOMEM;\n \tpool->trunks[idx] = trunk;\n \ttrunk->idx = idx;\n-\ttrunk->free = pool->cfg.trunk_size;\n+\ttrunk->free = data_size;\n \ttrunk->prev = TRUNK_INVALID;\n \ttrunk->next = TRUNK_INVALID;\n \tMLX5_ASSERT(pool->free_list == TRUNK_INVALID);\n \tpool->free_list = idx;\n \t/* Mark all entries as available. */\n-\ttrunk->bmp = rte_bitmap_init_with_all_set(pool->cfg.trunk_size,\n-\t\t     &trunk->data[pool->cfg.trunk_size  * pool->cfg.size],\n-\t\t     bmp_size);\n+\ttrunk->bmp = rte_bitmap_init_with_all_set(data_size,\n+\t\t     &trunk->data[data_size * pool->cfg.size], bmp_size);\n \tpool->n_trunk_valid++;\n #ifdef POOL_DEBUG\n \tpool->trunk_new++;\n@@ -244,10 +307,10 @@ struct mlx5_indexed_pool *\n \tMLX5_ASSERT(slab);\n \tiidx += __builtin_ctzll(slab);\n \tMLX5_ASSERT(iidx != UINT32_MAX);\n-\tMLX5_ASSERT(iidx < pool->cfg.trunk_size);\n+\tMLX5_ASSERT(iidx < mlx5_trunk_size_get(pool, trunk->idx));\n \trte_bitmap_clear(trunk->bmp, iidx);\n \tp = &trunk->data[iidx * pool->cfg.size];\n-\tiidx += trunk->idx * pool->cfg.trunk_size;\n+\tiidx += mlx5_trunk_idx_offset_get(pool, trunk->idx);\n \tiidx += 1; /* non-zero index. */\n \ttrunk->free--;\n #ifdef POOL_DEBUG\n@@ -286,19 +349,23 @@ struct mlx5_indexed_pool *\n {\n \tstruct mlx5_indexed_trunk *trunk;\n \tuint32_t trunk_idx;\n+\tuint32_t entry_idx;\n \n \tif (!idx)\n \t\treturn;\n \tidx -= 1;\n \tmlx5_ipool_lock(pool);\n-\ttrunk_idx = idx / pool->cfg.trunk_size;\n+\ttrunk_idx = mlx5_trunk_idx_get(pool, idx);\n \tif (trunk_idx >= pool->n_trunk_valid)\n \t\tgoto out;\n \ttrunk = pool->trunks[trunk_idx];\n-\tif (!trunk || trunk_idx != trunk->idx ||\n-\t    rte_bitmap_get(trunk->bmp, idx % pool->cfg.trunk_size))\n+\tif (!trunk)\n+\t\tgoto out;\n+\tentry_idx = idx - mlx5_trunk_idx_offset_get(pool, trunk->idx);\n+\tif (trunk_idx != trunk->idx ||\n+\t    rte_bitmap_get(trunk->bmp, entry_idx))\n \t\tgoto out;\n-\trte_bitmap_set(trunk->bmp, idx % pool->cfg.trunk_size);\n+\trte_bitmap_set(trunk->bmp, entry_idx);\n \ttrunk->free++;\n \tif (trunk->free == 1) {\n \t\t/* Put into free trunk list head. */\n@@ -326,19 +393,23 @@ struct mlx5_indexed_pool *\n \tstruct mlx5_indexed_trunk *trunk;\n \tvoid *p = NULL;\n \tuint32_t trunk_idx;\n+\tuint32_t entry_idx;\n \n \tif (!idx)\n \t\treturn NULL;\n \tidx -= 1;\n \tmlx5_ipool_lock(pool);\n-\ttrunk_idx = idx / pool->cfg.trunk_size;\n+\ttrunk_idx = mlx5_trunk_idx_get(pool, idx);\n \tif (trunk_idx >= pool->n_trunk_valid)\n \t\tgoto out;\n \ttrunk = pool->trunks[trunk_idx];\n-\tif (!trunk || trunk_idx != trunk->idx ||\n-\t    rte_bitmap_get(trunk->bmp, idx % pool->cfg.trunk_size))\n+\tif (!trunk)\n+\t\tgoto out;\n+\tentry_idx = idx - mlx5_trunk_idx_offset_get(pool, trunk->idx);\n+\tif (trunk_idx != trunk->idx ||\n+\t    rte_bitmap_get(trunk->bmp, entry_idx))\n \t\tgoto out;\n-\tp = &trunk->data[(idx % pool->cfg.trunk_size) * pool->cfg.size];\n+\tp = &trunk->data[entry_idx * pool->cfg.size];\n out:\n \tmlx5_ipool_unlock(pool);\n \treturn p;\ndiff --git a/drivers/net/mlx5/mlx5_utils.h b/drivers/net/mlx5/mlx5_utils.h\nindex e404a5c..af96a87 100644\n--- a/drivers/net/mlx5/mlx5_utils.h\n+++ b/drivers/net/mlx5/mlx5_utils.h\n@@ -81,9 +81,25 @@\n \n struct mlx5_indexed_pool_config {\n \tuint32_t size; /* Pool entry size. */\n-\tuint32_t trunk_size;\n-\t/* Trunk entry number. Must be power of 2. */\n-\tuint32_t need_lock;\n+\tuint32_t trunk_size:22;\n+\t/*\n+\t * Trunk entry number. Must be power of 2. It can be increased\n+\t * if trunk_grow enable. The trunk entry number increases with\n+\t * left shift grow_shift. Trunks with index are after grow_trunk\n+\t * will keep the entry number same with the last grow trunk.\n+\t */\n+\tuint32_t grow_trunk:4;\n+\t/*\n+\t * Trunks with entry number increase in the pool. Set it to 0\n+\t * to make the pool works as trunk entry fixed pool. It works\n+\t * only if grow_shift is not 0.\n+\t */\n+\tuint32_t grow_shift:4;\n+\t/*\n+\t * Trunk entry number increase shift value, stop after grow_trunk.\n+\t * It works only if grow_trunk is not 0.\n+\t */\n+\tuint32_t need_lock:1;\n \t/* Lock is needed for multiple thread usage. */\n \tconst char *type; /* Memory allocate type name. */\n \tvoid *(*malloc)(const char *type, size_t size, unsigned int align,\n@@ -116,6 +132,7 @@ struct mlx5_indexed_pool {\n \tint64_t trunk_empty;\n \tint64_t trunk_free;\n #endif\n+\tuint32_t grow_tbl[]; /* Save the index offset for the grow trunks. */\n };\n \n /**\n",
    "prefixes": [
        "02/10"
    ]
}