get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 45880,
    "url": "http://patchwork.dpdk.org/api/patches/45880/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/dd985f2223ca36bb3216a9fedcb066776bdb83ba.1538486972.git.anatoly.burakov@intel.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": "<dd985f2223ca36bb3216a9fedcb066776bdb83ba.1538486972.git.anatoly.burakov@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/dd985f2223ca36bb3216a9fedcb066776bdb83ba.1538486972.git.anatoly.burakov@intel.com",
    "date": "2018-10-02T13:34:52",
    "name": "[v9,14/21] malloc: allow removing memory from named heaps",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "174a6c06aa03f32346b38e8c4c2cc6174c8eced3",
    "submitter": {
        "id": 4,
        "url": "http://patchwork.dpdk.org/api/people/4/?format=api",
        "name": "Anatoly Burakov",
        "email": "anatoly.burakov@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/dd985f2223ca36bb3216a9fedcb066776bdb83ba.1538486972.git.anatoly.burakov@intel.com/mbox/",
    "series": [
        {
            "id": 1643,
            "url": "http://patchwork.dpdk.org/api/series/1643/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=1643",
            "date": "2018-10-02T13:34:42",
            "name": "Support externally allocated memory in DPDK",
            "version": 9,
            "mbox": "http://patchwork.dpdk.org/series/1643/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/45880/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/45880/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 [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 404EB5F54;\n\tTue,  2 Oct 2018 15:35:19 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id C4E4D4C96\n\tfor <dev@dpdk.org>; Tue,  2 Oct 2018 15:35:10 +0200 (CEST)",
            "from fmsmga005.fm.intel.com ([10.253.24.32])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t02 Oct 2018 06:35:09 -0700",
            "from irvmail001.ir.intel.com ([163.33.26.43])\n\tby fmsmga005.fm.intel.com with ESMTP; 02 Oct 2018 06:35:06 -0700",
            "from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com\n\t[10.237.217.45])\n\tby irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id\n\tw92DZ57a009232; Tue, 2 Oct 2018 14:35:05 +0100",
            "from sivswdev01.ir.intel.com (localhost [127.0.0.1])\n\tby sivswdev01.ir.intel.com with ESMTP id w92DZ51U032206;\n\tTue, 2 Oct 2018 14:35:05 +0100",
            "(from aburakov@localhost)\n\tby sivswdev01.ir.intel.com with LOCAL id w92DZ5gb032198;\n\tTue, 2 Oct 2018 14:35:05 +0100"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.54,332,1534834800\"; d=\"scan'208\";a=\"267788302\"",
        "From": "Anatoly Burakov <anatoly.burakov@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "laszlo.madarassy@ericsson.com, laszlo.vadkerti@ericsson.com,\n\tandras.kovacs@ericsson.com, winnie.tian@ericsson.com,\n\tdaniel.andrasi@ericsson.com, janos.kobor@ericsson.com,\n\tgeza.koblo@ericsson.com, srinath.mannam@broadcom.com,\n\tscott.branden@broadcom.com, ajit.khaparde@broadcom.com,\n\tkeith.wiles@intel.com, bruce.richardson@intel.com, thomas@monjalon.net,\n\tshreyansh.jain@nxp.com, shahafs@mellanox.com,\n\tarybchenko@solarflare.com, alejandro.lucero@netronome.com",
        "Date": "Tue,  2 Oct 2018 14:34:52 +0100",
        "Message-Id": "<dd985f2223ca36bb3216a9fedcb066776bdb83ba.1538486972.git.anatoly.burakov@intel.com>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "In-Reply-To": [
            "<cover.1538486972.git.anatoly.burakov@intel.com>",
            "<cover.1538486972.git.anatoly.burakov@intel.com>"
        ],
        "References": [
            "<cover.1538486972.git.anatoly.burakov@intel.com>",
            "<cover.1538398379.git.anatoly.burakov@intel.com>\n\t<cover.1538486972.git.anatoly.burakov@intel.com>"
        ],
        "Subject": "[dpdk-dev] [PATCH v9 14/21] malloc: allow removing memory from\n\tnamed heaps",
        "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\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add an API to remove memory from specified heaps. This will first\ncheck if all elements within the region are free, and that the\nregion is the original region that was added to the heap (by\ncomparing its length to length of memory addressed by the\nunderlying memseg list).\n\nSigned-off-by: Anatoly Burakov <anatoly.burakov@intel.com>\n---\n lib/librte_eal/common/include/rte_malloc.h | 27 +++++++++++\n lib/librte_eal/common/malloc_heap.c        | 54 ++++++++++++++++++++++\n lib/librte_eal/common/malloc_heap.h        |  4 ++\n lib/librte_eal/common/rte_malloc.c         | 39 ++++++++++++++++\n lib/librte_eal/rte_eal_version.map         |  1 +\n 5 files changed, 125 insertions(+)",
    "diff": "diff --git a/lib/librte_eal/common/include/rte_malloc.h b/lib/librte_eal/common/include/rte_malloc.h\nindex fb5b6e2f7..40bae4478 100644\n--- a/lib/librte_eal/common/include/rte_malloc.h\n+++ b/lib/librte_eal/common/include/rte_malloc.h\n@@ -302,6 +302,33 @@ int __rte_experimental\n rte_malloc_heap_memory_add(const char *heap_name, void *va_addr, size_t len,\n \t\trte_iova_t iova_addrs[], unsigned int n_pages, size_t page_sz);\n \n+/**\n+ * Remove memory chunk from heap with specified name.\n+ *\n+ * @note Memory chunk being removed must be the same as one that was added;\n+ *   partially removing memory chunks is not supported\n+ *\n+ * @note Memory area must not contain any allocated elements to allow its\n+ *   removal from the heap\n+ *\n+ * @param heap_name\n+ *   Name of the heap to remove memory from\n+ * @param va_addr\n+ *   Virtual address to remove from the heap\n+ * @param len\n+ *   Length of virtual area to remove from the heap\n+ *\n+ * @return\n+ *   - 0 on success\n+ *   - -1 in case of error, with rte_errno set to one of the following:\n+ *     EINVAL - one of the parameters was invalid\n+ *     EPERM  - attempted to remove memory from a reserved heap\n+ *     ENOENT - heap or memory chunk was not found\n+ *     EBUSY  - memory chunk still contains data\n+ */\n+int __rte_experimental\n+rte_malloc_heap_memory_remove(const char *heap_name, void *va_addr, size_t len);\n+\n /**\n  * Creates a new empty malloc heap with a specified name.\n  *\ndiff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c\nindex 256c25edf..adc1669aa 100644\n--- a/lib/librte_eal/common/malloc_heap.c\n+++ b/lib/librte_eal/common/malloc_heap.c\n@@ -1023,6 +1023,32 @@ malloc_heap_dump(struct malloc_heap *heap, FILE *f)\n \trte_spinlock_unlock(&heap->lock);\n }\n \n+static int\n+destroy_seg(struct malloc_elem *elem, size_t len)\n+{\n+\tstruct malloc_heap *heap = elem->heap;\n+\tstruct rte_memseg_list *msl;\n+\n+\tmsl = elem->msl;\n+\n+\t/* this element can be removed */\n+\tmalloc_elem_free_list_remove(elem);\n+\tmalloc_elem_hide_region(elem, elem, len);\n+\n+\theap->total_size -= len;\n+\n+\tmemset(elem, 0, sizeof(*elem));\n+\n+\t/* destroy the fbarray backing this memory */\n+\tif (rte_fbarray_destroy(&msl->memseg_arr) < 0)\n+\t\treturn -1;\n+\n+\t/* reset the memseg list */\n+\tmemset(msl, 0, sizeof(*msl));\n+\n+\treturn 0;\n+}\n+\n int\n malloc_heap_add_external_memory(struct malloc_heap *heap, void *va_addr,\n \t\trte_iova_t iova_addrs[], unsigned int n_pages, size_t page_sz)\n@@ -1097,6 +1123,34 @@ malloc_heap_add_external_memory(struct malloc_heap *heap, void *va_addr,\n \treturn 0;\n }\n \n+int\n+malloc_heap_remove_external_memory(struct malloc_heap *heap, void *va_addr,\n+\t\tsize_t len)\n+{\n+\tstruct malloc_elem *elem = heap->first;\n+\n+\t/* find element with specified va address */\n+\twhile (elem != NULL && elem != va_addr) {\n+\t\telem = elem->next;\n+\t\t/* stop if we've blown past our VA */\n+\t\tif (elem > (struct malloc_elem *)va_addr) {\n+\t\t\trte_errno = ENOENT;\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\t/* check if element was found */\n+\tif (elem == NULL || elem->msl->len != len) {\n+\t\trte_errno = ENOENT;\n+\t\treturn -1;\n+\t}\n+\t/* if element's size is not equal to segment len, segment is busy */\n+\tif (elem->state == ELEM_BUSY || elem->size != len) {\n+\t\trte_errno = EBUSY;\n+\t\treturn -1;\n+\t}\n+\treturn destroy_seg(elem, len);\n+}\n+\n int\n malloc_heap_create(struct malloc_heap *heap, const char *heap_name)\n {\ndiff --git a/lib/librte_eal/common/malloc_heap.h b/lib/librte_eal/common/malloc_heap.h\nindex 237ce9dc2..e48996d52 100644\n--- a/lib/librte_eal/common/malloc_heap.h\n+++ b/lib/librte_eal/common/malloc_heap.h\n@@ -43,6 +43,10 @@ int\n malloc_heap_add_external_memory(struct malloc_heap *heap, void *va_addr,\n \t\trte_iova_t iova_addrs[], unsigned int n_pages, size_t page_sz);\n \n+int\n+malloc_heap_remove_external_memory(struct malloc_heap *heap, void *va_addr,\n+\t\tsize_t len);\n+\n int\n malloc_heap_free(struct malloc_elem *elem);\n \ndiff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c\nindex acdbd92a2..bfc49d0b7 100644\n--- a/lib/librte_eal/common/rte_malloc.c\n+++ b/lib/librte_eal/common/rte_malloc.c\n@@ -379,6 +379,45 @@ rte_malloc_heap_memory_add(const char *heap_name, void *va_addr, size_t len,\n \treturn ret;\n }\n \n+int\n+rte_malloc_heap_memory_remove(const char *heap_name, void *va_addr, size_t len)\n+{\n+\tstruct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;\n+\tstruct malloc_heap *heap = NULL;\n+\tint ret;\n+\n+\tif (heap_name == NULL || va_addr == NULL || len == 0 ||\n+\t\t\tstrnlen(heap_name, RTE_HEAP_NAME_MAX_LEN) == 0 ||\n+\t\t\tstrnlen(heap_name, RTE_HEAP_NAME_MAX_LEN) ==\n+\t\t\t\tRTE_HEAP_NAME_MAX_LEN) {\n+\t\trte_errno = EINVAL;\n+\t\treturn -1;\n+\t}\n+\trte_rwlock_write_lock(&mcfg->memory_hotplug_lock);\n+\t/* find our heap */\n+\theap = find_named_heap(heap_name);\n+\tif (heap == NULL) {\n+\t\trte_errno = ENOENT;\n+\t\tret = -1;\n+\t\tgoto unlock;\n+\t}\n+\tif (heap->socket_id < RTE_MAX_NUMA_NODES) {\n+\t\t/* cannot remove memory from internal heaps */\n+\t\trte_errno = EPERM;\n+\t\tret = -1;\n+\t\tgoto unlock;\n+\t}\n+\n+\trte_spinlock_lock(&heap->lock);\n+\tret = malloc_heap_remove_external_memory(heap, va_addr, len);\n+\trte_spinlock_unlock(&heap->lock);\n+\n+unlock:\n+\trte_rwlock_write_unlock(&mcfg->memory_hotplug_lock);\n+\n+\treturn ret;\n+}\n+\n int\n rte_malloc_heap_create(const char *heap_name)\n {\ndiff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map\nindex 02254042c..8c66d0be9 100644\n--- a/lib/librte_eal/rte_eal_version.map\n+++ b/lib/librte_eal/rte_eal_version.map\n@@ -322,6 +322,7 @@ EXPERIMENTAL {\n \trte_malloc_heap_destroy;\n \trte_malloc_heap_get_socket;\n \trte_malloc_heap_memory_add;\n+\trte_malloc_heap_memory_remove;\n \trte_malloc_heap_socket_is_external;\n \trte_mem_alloc_validator_register;\n \trte_mem_alloc_validator_unregister;\n",
    "prefixes": [
        "v9",
        "14/21"
    ]
}