get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 4054,
    "url": "http://patches.dpdk.org/api/patches/4054/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1426710078-11230-1-git-send-email-vadim.suraev@gmail.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": "<1426710078-11230-1-git-send-email-vadim.suraev@gmail.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1426710078-11230-1-git-send-email-vadim.suraev@gmail.com",
    "date": "2015-03-18T20:21:18",
    "name": "[dpdk-dev,v2] rte_mbuf: mbuf bulk alloc/free functions added + unittest",
    "commit_ref": null,
    "pull_url": null,
    "state": "not-applicable",
    "archived": true,
    "hash": "aa5072e6cdde1726f500810ba55a9cbc3dd6f9f7",
    "submitter": {
        "id": 181,
        "url": "http://patches.dpdk.org/api/people/181/?format=api",
        "name": "vadim.suraev@gmail.com",
        "email": "vadim.suraev@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1426710078-11230-1-git-send-email-vadim.suraev@gmail.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/4054/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/4054/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id A39AC592B;\n\tWed, 18 Mar 2015 21:21:34 +0100 (CET)",
            "from mail-wi0-f175.google.com (mail-wi0-f175.google.com\n\t[209.85.212.175]) by dpdk.org (Postfix) with ESMTP id C1783590C\n\tfor <dev@dpdk.org>; Wed, 18 Mar 2015 21:21:33 +0100 (CET)",
            "by wixw10 with SMTP id w10so69842243wix.0\n\tfor <dev@dpdk.org>; Wed, 18 Mar 2015 13:21:33 -0700 (PDT)",
            "from ubuntu.ubuntu-domain (bzq-79-176-41-72.red.bezeqint.net.\n\t[79.176.41.72]) by mx.google.com with ESMTPSA id\n\tn1sm4601172wib.11.2015.03.18.13.21.31\n\t(version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);\n\tWed, 18 Mar 2015 13:21:32 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;\n\th=from:to:cc:subject:date:message-id;\n\tbh=MLiNLVEEkU69h5dWOm9zGqHP6m9POqKsRO3WzDuLcXI=;\n\tb=GvC/xVEnZVJTgVWvmOLmdyUdH0bNaNRZV2tMHwhJAs3FeeVV+GOKk8ucKc4AndewYA\n\tKJOip0CcHIcSlE0dkJzwkv529kJUKNZDC1GHMsVa5+L8/2lhSrzhm1M3AkycAwFcd1eo\n\tlzX1gZ/IjqkBm4reKqIk4lQQfQiGprUQ5M8gaPH3yVtTS66H9/2qxCZIsaBxsKhrLnJ8\n\twGML58rWuoTc2kJLCH4czkwz6ui4szDtAJDbDbRsOmYLB5pJrPL3EyXKMHTv1wgxiA4x\n\tKM6li4q9ZZ8ufacz8j+mtAXe8xDGlUFEgWWGsOkeeC/9PwTx1Ow170/laHITHbfUvfyn\n\tw8eg==",
        "X-Received": "by 10.194.61.161 with SMTP id q1mr148863631wjr.132.1426710093639;\n\tWed, 18 Mar 2015 13:21:33 -0700 (PDT)",
        "From": "\"vadim.suraev@gmail.com\" <vadim.suraev@gmail.com>",
        "To": "dev@dpdk.org",
        "Date": "Wed, 18 Mar 2015 22:21:18 +0200",
        "Message-Id": "<1426710078-11230-1-git-send-email-vadim.suraev@gmail.com>",
        "X-Mailer": "git-send-email 1.7.9.5",
        "Subject": "[dpdk-dev] [PATCH v2] rte_mbuf: mbuf bulk alloc/free functions\n\tadded + unittest",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: \"vadim.suraev@gmail.com\" <vadim.suraev@gmail.com>\n\nThis patch adds mbuf bulk allocation/freeing functions and unittest\n\nSigned-off-by: Vadim Suraev\n<vadim.suraev@gmail.com>\n---\nNew in v2:\n    - function rte_pktmbuf_alloc_bulk added\n    - function rte_pktmbuf_bulk_free added\n    - function rte_pktmbuf_free_chain added\n    - applied reviewers' comments\n\n app/test/test_mbuf.c       |   94 +++++++++++++++++++++++++++++++++++++++++++-\n lib/librte_mbuf/rte_mbuf.h |   91 ++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 184 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c\nindex 1ff66cb..b20c6a4 100644\n--- a/app/test/test_mbuf.c\n+++ b/app/test/test_mbuf.c\n@@ -77,6 +77,7 @@\n #define REFCNT_RING_SIZE        (REFCNT_MBUF_NUM * REFCNT_MAX_REF)\n \n #define MAKE_STRING(x)          # x\n+#define MBUF_POOL_LOCAL_CACHE_SIZE 32\n \n static struct rte_mempool *pktmbuf_pool = NULL;\n \n@@ -405,6 +406,84 @@ test_pktmbuf_pool(void)\n \treturn ret;\n }\n \n+/* test pktmbuf bulk allocation and freeing\n+*/\n+static int\n+test_pktmbuf_pool_bulk(void)\n+{\n+\tunsigned i;\n+\t/* size of mempool - size of local cache, otherwise may fail */\n+\tunsigned mbufs_to_allocate = NB_MBUF - MBUF_POOL_LOCAL_CACHE_SIZE;\n+\tstruct rte_mbuf *m[mbufs_to_allocate];\n+\tint ret = 0;\n+\tunsigned mbuf_count_before_allocation = rte_mempool_count(pktmbuf_pool);\n+\n+\tfor (i = 0; i < mbufs_to_allocate; i++)\n+\t\tm[i] = NULL;\n+\t/* alloc NB_MBUF-MBUF_POOL_LOCAL_CACHE_SIZE mbufs */\n+\tret = rte_pktmbuf_alloc_bulk(pktmbuf_pool, m, mbufs_to_allocate);\n+\tif (ret) {\n+\t\tprintf(\"cannot allocate %d mbufs bulk mempool_cnt=%d ret=%d\\n\",\n+\t\t\tmbufs_to_allocate,\n+\t\t\trte_mempool_count(pktmbuf_pool),\n+\t\t\tret);\n+\t\treturn -1;\n+\t}\n+\tif ((rte_mempool_count(pktmbuf_pool) + mbufs_to_allocate) !=\n+\t    mbuf_count_before_allocation) {\n+\t\tprintf(\"mempool count %d + allocated %d != initial %d\\n\",\n+\t\t\trte_mempool_count(pktmbuf_pool),\n+\t\t\tmbufs_to_allocate,\n+\t\t\tmbuf_count_before_allocation);\n+\t\treturn -1;\n+\t}\n+\t/* free them */\n+\trte_pktmbuf_bulk_free(m, mbufs_to_allocate);\n+\n+\tif (rte_mempool_count(pktmbuf_pool)  != mbuf_count_before_allocation) {\n+\t\tprintf(\"mempool count %d != initial %d\\n\",\n+\t\t\trte_mempool_count(pktmbuf_pool),\n+\t\t\tmbuf_count_before_allocation);\n+\t\treturn -1;\n+\t}\n+\tfor (i = 0; i < mbufs_to_allocate; i++)\n+\t\tm[i] = NULL;\n+\n+\t/* alloc NB_MBUF-MBUF_POOL_LOCAL_CACHE_SIZE mbufs */\n+\tret = rte_pktmbuf_alloc_bulk(pktmbuf_pool, m, mbufs_to_allocate);\n+\tif (ret) {\n+\t\tprintf(\"cannot allocate %d mbufs bulk mempool_cnt=%d ret=%d\\n\",\n+\t\t\tmbufs_to_allocate,\n+\t\t\trte_mempool_count(pktmbuf_pool),\n+\t\t\tret);\n+\t\treturn -1;\n+\t}\n+\tif ((rte_mempool_count(pktmbuf_pool) + mbufs_to_allocate) !=\n+\t    mbuf_count_before_allocation) {\n+\t\tprintf(\"mempool count %d + allocated %d != initial %d\\n\",\n+\t\t\trte_mempool_count(pktmbuf_pool),\n+\t\t\t\t\t  mbufs_to_allocate,\n+\t\t\t\t\t  mbuf_count_before_allocation);\n+\t\treturn -1;\n+\t}\n+\n+\t/* chain it */\n+\tfor (i = 0; i < mbufs_to_allocate - 1; i++) {\n+\t\tm[i]->next = m[i + 1];\n+\t\tm[0]->nb_segs++;\n+\t}\n+\t/* free them */\n+\trte_pktmbuf_free_chain(m[0]);\n+\n+\tif (rte_mempool_count(pktmbuf_pool)  != mbuf_count_before_allocation) {\n+\t\tprintf(\"mempool count %d != initial %d\\n\",\n+\t\t\trte_mempool_count(pktmbuf_pool),\n+\t\t\t\t\t  mbuf_count_before_allocation);\n+\t\treturn -1;\n+\t}\n+\treturn ret;\n+}\n+\n /*\n  * test that the pointer to the data on a packet mbuf is set properly\n  */\n@@ -766,7 +845,8 @@ test_mbuf(void)\n \tif (pktmbuf_pool == NULL) {\n \t\tpktmbuf_pool =\n \t\t\trte_mempool_create(\"test_pktmbuf_pool\", NB_MBUF,\n-\t\t\t\t\t   MBUF_SIZE, 32,\n+\t\t\t\t\t   MBUF_SIZE,\n+\t\t\t\t\t   MBUF_POOL_LOCAL_CACHE_SIZE,\n \t\t\t\t\t   sizeof(struct rte_pktmbuf_pool_private),\n \t\t\t\t\t   rte_pktmbuf_pool_init, NULL,\n \t\t\t\t\t   rte_pktmbuf_init, NULL,\n@@ -790,6 +870,18 @@ test_mbuf(void)\n \t\treturn -1;\n \t}\n \n+\t/* test bulk allocation and freeing */\n+\tif (test_pktmbuf_pool_bulk() < 0) {\n+\t\tprintf(\"test_pktmbuf_pool_bulk() failed\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\t/* once again to ensure all mbufs were freed */\n+\tif (test_pktmbuf_pool_bulk() < 0) {\n+\t\tprintf(\"test_pktmbuf_pool_bulk() failed\\n\");\n+\t\treturn -1;\n+\t}\n+\n \t/* test that the pointer to the data on a packet mbuf is set properly */\n \tif (test_pktmbuf_pool_ptr() < 0) {\n \t\tprintf(\"test_pktmbuf_pool_ptr() failed\\n\");\ndiff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h\nindex 17ba791..fabeae2 100644\n--- a/lib/librte_mbuf/rte_mbuf.h\n+++ b/lib/librte_mbuf/rte_mbuf.h\n@@ -825,6 +825,97 @@ static inline void rte_pktmbuf_free(struct rte_mbuf *m)\n }\n \n /**\n+ * Allocate a bulk of mbufs, initiate refcnt and resets\n+ *\n+ * @param pool\n+ *    memory pool to allocate from\n+ * @param mbufs\n+ *    Array of pointers to mbuf\n+ * @param count\n+ *    Array size\n+ */\n+static inline int rte_pktmbuf_alloc_bulk(struct rte_mempool *pool,\n+\t\t\t\t\t struct rte_mbuf **mbufs,\n+\t\t\t\t\t unsigned count)\n+{\n+\tunsigned idx;\n+\tint rc = 0;\n+\n+\trc = rte_mempool_get_bulk(pool, (void **)mbufs, count);\n+\tif (unlikely(rc))\n+\t\treturn rc;\n+\n+\tfor (idx = 0; idx < count; idx++) {\n+\t\tRTE_MBUF_ASSERT(rte_mbuf_refcnt_read(mbufs[idx]) == 0);\n+\t\trte_mbuf_refcnt_set(mbufs[idx], 1);\n+\t\trte_pktmbuf_reset(mbufs[idx]);\n+\t}\n+\treturn rc;\n+}\n+\n+/**\n+ * Free a bulk of mbufs into its original mempool.\n+ * This function assumes:\n+ * - refcnt equals 1\n+ * - mbufs are direct\n+ * - all mbufs must belong to the same mempool\n+ *\n+ * @param mbufs\n+ *    Array of pointers to mbuf\n+ * @param count\n+ *    Array size\n+ */\n+static inline void rte_pktmbuf_bulk_free(struct rte_mbuf **mbufs,\n+\t\t\t\t\t unsigned count)\n+{\n+\tunsigned idx;\n+\n+\tRTE_MBUF_ASSERT(count > 0);\n+\n+\tfor (idx = 0; idx < count; idx++) {\n+\t\tRTE_MBUF_ASSERT(mbufs[idx]->pool == mbufs[0]->pool);\n+\t\tRTE_MBUF_ASSERT(rte_mbuf_refcnt_read(mbufs[idx]) == 1);\n+\t\trte_mbuf_refcnt_set(mbufs[idx], 0);\n+\t}\n+\trte_mempool_put_bulk(mbufs[0]->pool, (void **)mbufs, count);\n+}\n+\n+/**\n+ * Free chained (scattered) mbufs into its original mempool(s).\n+ *\n+ * @param head\n+ *    The head of mbufs to be freed chain. Must not be NULL\n+ */\n+static inline void rte_pktmbuf_free_chain(struct rte_mbuf *head)\n+{\n+\tstruct rte_mbuf *mbufs[head->nb_segs];\n+\tunsigned mbufs_count = 0;\n+\tstruct rte_mbuf *next;\n+\n+\twhile (head) {\n+\t\tnext = head->next;\n+\t\thead = __rte_pktmbuf_prefree_seg(head);\n+\t\tif (likely(head != NULL)) {\n+\t\t\thead->next = NULL;\n+\t\t\tif (likely((!mbufs_count) ||\n+\t\t\t\t   (head->pool == mbufs[0]->pool)))\n+\t\t\t\tmbufs[mbufs_count++] = head;\n+\t\t\telse {\n+\t\t\t\trte_mempool_put_bulk(mbufs[0]->pool,\n+\t\t\t\t\t\t     (void **)mbufs,\n+\t\t\t\t\t\t     mbufs_count);\n+\t\t\t\tmbufs_count = 0;\n+\t\t\t}\n+\t\t}\n+\t\thead = next;\n+\t}\n+\tif (mbufs_count > 0)\n+\t\trte_mempool_put_bulk(mbufs[0]->pool,\n+\t\t\t\t     (void **)mbufs,\n+\t\t\t\t     mbufs_count);\n+}\n+\n+/**\n  * Creates a \"clone\" of the given packet mbuf.\n  *\n  * Walks through all segments of the given packet mbuf, and for each of them:\n",
    "prefixes": [
        "dpdk-dev",
        "v2"
    ]
}