get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 42500,
    "url": "http://patches.dpdk.org/api/patches/42500/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1b2f86a255a36135a8d718b00d609d729acabee2.1530881548.git.anatoly.burakov@intel.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": "<1b2f86a255a36135a8d718b00d609d729acabee2.1530881548.git.anatoly.burakov@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1b2f86a255a36135a8d718b00d609d729acabee2.1530881548.git.anatoly.burakov@intel.com",
    "date": "2018-07-06T13:17:30",
    "name": "[RFC,09/11] malloc: allow removing memory from named heaps",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "5fad8db90774c9dbc5d0ffd7155a8588558746ac",
    "submitter": {
        "id": 4,
        "url": "http://patches.dpdk.org/api/people/4/?format=api",
        "name": "Burakov, Anatoly",
        "email": "anatoly.burakov@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1b2f86a255a36135a8d718b00d609d729acabee2.1530881548.git.anatoly.burakov@intel.com/mbox/",
    "series": [
        {
            "id": 453,
            "url": "http://patches.dpdk.org/api/series/453/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=453",
            "date": "2018-07-06T13:17:21",
            "name": "Support externally allocated memory in DPDK",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/453/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/42500/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/42500/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 3592B1BECD;\n\tFri,  6 Jul 2018 15:17:43 +0200 (CEST)",
            "from mga07.intel.com (mga07.intel.com [134.134.136.100])\n\tby dpdk.org (Postfix) with ESMTP id 3AD7C1BE4E\n\tfor <dev@dpdk.org>; Fri,  6 Jul 2018 15:17:37 +0200 (CEST)",
            "from orsmga004.jf.intel.com ([10.7.209.38])\n\tby orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t06 Jul 2018 06:17:36 -0700",
            "from irvmail001.ir.intel.com ([163.33.26.43])\n\tby orsmga004.jf.intel.com with ESMTP; 06 Jul 2018 06:17:34 -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\tw66DHYvX027494; Fri, 6 Jul 2018 14:17:34 +0100",
            "from sivswdev01.ir.intel.com (localhost [127.0.0.1])\n\tby sivswdev01.ir.intel.com with ESMTP id w66DHY3k003811;\n\tFri, 6 Jul 2018 14:17:34 +0100",
            "(from aburakov@localhost)\n\tby sivswdev01.ir.intel.com with LOCAL id w66DHYAp003807;\n\tFri, 6 Jul 2018 14:17:34 +0100"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.51,316,1526367600\"; d=\"scan'208\";a=\"213916539\"",
        "From": "Anatoly Burakov <anatoly.burakov@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "srinath.mannam@broadcom.com, scott.branden@broadcom.com,\n\tajit.khaparde@broadcom.com",
        "Date": "Fri,  6 Jul 2018 14:17:30 +0100",
        "Message-Id": "<1b2f86a255a36135a8d718b00d609d729acabee2.1530881548.git.anatoly.burakov@intel.com>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "In-Reply-To": [
            "<cover.1530881548.git.anatoly.burakov@intel.com>",
            "<cover.1530881548.git.anatoly.burakov@intel.com>"
        ],
        "References": [
            "<cover.1530881548.git.anatoly.burakov@intel.com>",
            "<cover.1530881548.git.anatoly.burakov@intel.com>"
        ],
        "Subject": "[dpdk-dev] [RFC 09/11] malloc: allow removing memory from named\n\theaps",
        "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 | 28 ++++++++++\n lib/librte_eal/common/malloc_heap.c        | 61 ++++++++++++++++++++++\n lib/librte_eal/common/malloc_heap.h        |  4 ++\n lib/librte_eal/common/rte_malloc.c         | 28 ++++++++++\n lib/librte_eal/rte_eal_version.map         |  1 +\n 5 files changed, 122 insertions(+)",
    "diff": "diff --git a/lib/librte_eal/common/include/rte_malloc.h b/lib/librte_eal/common/include/rte_malloc.h\nindex 5f933993b..25d8d3f11 100644\n--- a/lib/librte_eal/common/include/rte_malloc.h\n+++ b/lib/librte_eal/common/include/rte_malloc.h\n@@ -318,6 +318,34 @@ int __rte_experimental\n rte_malloc_heap_add_memory(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 area from heap with specified name.\n+ *\n+ * @note Concurrently adding or removing memory from different heaps is not\n+ *   safe.\n+ *\n+ * @note This function does not need to be called in multiple processes, as\n+ *   multiprocess synchronization will happen automatically as far as heap data\n+ *   is concerned. However, before accessing pointers to memory in this heap, it\n+ *   is responsibility of the user to ensure that the heap memory is accessible\n+ *   in all processes.\n+ *\n+ * @note Memory area must be empty to allow its removal from the heap.\n+ *\n+ * @param heap_name\n+ *   Name of the heap to create.\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 successful creation.\n+ *   - -1 on error.\n+ */\n+int __rte_experimental\n+rte_malloc_heap_remove_memory(const char *heap_name, void *va_addr, size_t len);\n+\n /**\n  * If malloc debug is enabled, check a memory block for header\n  * and trailer markers to indicate that all is well with the block.\ndiff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c\nindex 29446cac9..27dbf6e60 100644\n--- a/lib/librte_eal/common/malloc_heap.c\n+++ b/lib/librte_eal/common/malloc_heap.c\n@@ -892,6 +892,44 @@ 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+\t/* check if the element is unused */\n+\tif (elem->state != ELEM_FREE) {\n+\t\trte_errno = EBUSY;\n+\t\treturn -1;\n+\t}\n+\n+\tmsl = elem->msl;\n+\n+\t/* check if element encompasses the entire memseg list */\n+\tif (elem->size != len || len != (msl->page_sz * msl->memseg_arr.len)) {\n+\t\trte_errno = EINVAL;\n+\t\treturn -1;\n+\t}\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+\t/* this element can be removed */\n+\tmalloc_elem_free_list_remove(elem);\n+\tmalloc_elem_hide_region(elem, elem, len);\n+\n+\tmemset(elem, 0, sizeof(*elem));\n+\n+\theap->total_size -= len;\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@@ -962,6 +1000,29 @@ 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\telem = NULL;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\t/* check if element was found */\n+\tif (elem == NULL) {\n+\t\trte_errno = EINVAL;\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 3be4656d0..000146365 100644\n--- a/lib/librte_eal/common/malloc_heap.h\n+++ b/lib/librte_eal/common/malloc_heap.h\n@@ -42,6 +42,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_find_named_heap_idx(const char *name);\n \ndiff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c\nindex db0f604ad..8d2eb7250 100644\n--- a/lib/librte_eal/common/rte_malloc.c\n+++ b/lib/librte_eal/common/rte_malloc.c\n@@ -313,6 +313,34 @@ rte_malloc_heap_add_memory(const char *heap_name, void *va_addr, size_t len,\n \treturn ret;\n }\n \n+int\n+rte_malloc_heap_remove_memory(const char *heap_name, void *va_addr, size_t len)\n+{\n+\tstruct malloc_heap *heap = NULL;\n+\tint ret;\n+\n+\t/* iova_addrs is allowed to be NULL */\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+\t/* find our heap */\n+\theap = malloc_heap_find_named_heap(heap_name);\n+\tif (heap == NULL) {\n+\t\trte_errno = EINVAL;\n+\t\treturn -1;\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+\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 6290cc910..7ee79051f 100644\n--- a/lib/librte_eal/rte_eal_version.map\n+++ b/lib/librte_eal/rte_eal_version.map\n@@ -282,6 +282,7 @@ EXPERIMENTAL {\n \trte_malloc_get_stats_from_heap;\n \trte_malloc_heap_add_memory;\n \trte_malloc_heap_create;\n+\trte_malloc_heap_remove_memory;\n \trte_mem_alloc_validator_register;\n \trte_mem_alloc_validator_unregister;\n \trte_mem_event_callback_register;\n",
    "prefixes": [
        "RFC",
        "09/11"
    ]
}