get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 48406,
    "url": "http://patchwork.dpdk.org/api/patches/48406/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/54cb382e91119cfbef7c34db4406f8ea39428511.1543495935.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": "<54cb382e91119cfbef7c34db4406f8ea39428511.1543495935.git.anatoly.burakov@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/54cb382e91119cfbef7c34db4406f8ea39428511.1543495935.git.anatoly.burakov@intel.com",
    "date": "2018-11-29T13:48:33",
    "name": "[2/4] malloc: separate destroying memseg list and heap data",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "b2d69011dd7a58120a92097210a7287a02c4b9ac",
    "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/54cb382e91119cfbef7c34db4406f8ea39428511.1543495935.git.anatoly.burakov@intel.com/mbox/",
    "series": [
        {
            "id": 2612,
            "url": "http://patchwork.dpdk.org/api/series/2612/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=2612",
            "date": "2018-11-29T13:48:33",
            "name": "Allow using external memory without malloc",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/2612/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/48406/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/48406/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 1D3521B4AA;\n\tThu, 29 Nov 2018 14:48:40 +0100 (CET)",
            "from mga06.intel.com (mga06.intel.com [134.134.136.31])\n\tby dpdk.org (Postfix) with ESMTP id EE4F5322C\n\tfor <dev@dpdk.org>; Thu, 29 Nov 2018 14:48:38 +0100 (CET)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n\tby orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t29 Nov 2018 05:48:37 -0800",
            "from irvmail001.ir.intel.com ([163.33.26.43])\n\tby fmsmga004.fm.intel.com with ESMTP; 29 Nov 2018 05:48:36 -0800",
            "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\twATDmaF1012502; Thu, 29 Nov 2018 13:48:36 GMT",
            "from sivswdev01.ir.intel.com (localhost [127.0.0.1])\n\tby sivswdev01.ir.intel.com with ESMTP id wATDmZN7019978;\n\tThu, 29 Nov 2018 13:48:35 GMT",
            "(from aburakov@localhost)\n\tby sivswdev01.ir.intel.com with LOCAL id wATDmZMA019974;\n\tThu, 29 Nov 2018 13:48:35 GMT"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.56,294,1539673200\"; d=\"scan'208\";a=\"116348114\"",
        "From": "Anatoly Burakov <anatoly.burakov@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "shahafs@mellanox.com, yskoh@mellanox.com, thomas@monjalon.net,\n\tshreyansh.jain@nxp.com",
        "Date": "Thu, 29 Nov 2018 13:48:33 +0000",
        "Message-Id": "<54cb382e91119cfbef7c34db4406f8ea39428511.1543495935.git.anatoly.burakov@intel.com>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "In-Reply-To": [
            "<cover.1543495935.git.anatoly.burakov@intel.com>",
            "<cover.1543495935.git.anatoly.burakov@intel.com>"
        ],
        "References": [
            "<cover.1543495935.git.anatoly.burakov@intel.com>",
            "<cover.1543495935.git.anatoly.burakov@intel.com>"
        ],
        "Subject": "[dpdk-dev] [PATCH 2/4] malloc: separate destroying memseg list and\n\theap data",
        "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": "Currently, destroying external heap chunk and its memseg list is\npart of one process. When we will gain the ability to unregister\nexternal memory from DPDK that doesn't have any heap structures\nassociated with it, we need to be able to find and destroy\nmemseg lists as well as heap data separately.\n\nSigned-off-by: Anatoly Burakov <anatoly.burakov@intel.com>\n---\n lib/librte_eal/common/malloc_heap.c |  70 +++++++++++++++----\n lib/librte_eal/common/malloc_heap.h |   6 ++\n lib/librte_eal/common/rte_malloc.c  | 104 ++++++++++------------------\n 3 files changed, 102 insertions(+), 78 deletions(-)",
    "diff": "diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c\nindex 25693481f..fa0cb0799 100644\n--- a/lib/librte_eal/common/malloc_heap.c\n+++ b/lib/librte_eal/common/malloc_heap.c\n@@ -1067,12 +1067,9 @@ malloc_heap_dump(struct malloc_heap *heap, FILE *f)\n }\n \n static int\n-destroy_seg(struct malloc_elem *elem, size_t len)\n+destroy_elem(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/* notify all subscribers that a memory area is going to be removed */\n \teal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE, elem, len);\n@@ -1085,13 +1082,6 @@ destroy_seg(struct malloc_elem *elem, size_t 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@@ -1158,6 +1148,62 @@ malloc_heap_create_external_seg(void *va_addr, rte_iova_t iova_addrs[],\n \treturn msl;\n }\n \n+struct extseg_walk_arg {\n+\tvoid *va_addr;\n+\tsize_t len;\n+\tstruct rte_memseg_list *msl;\n+};\n+\n+static int\n+extseg_walk(const struct rte_memseg_list *msl, void *arg)\n+{\n+\tstruct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;\n+\tstruct extseg_walk_arg *wa = arg;\n+\n+\tif (msl->base_va == wa->va_addr && msl->len == wa->len) {\n+\t\tunsigned int found_idx;\n+\n+\t\t/* msl is const */\n+\t\tfound_idx = msl - mcfg->memsegs;\n+\t\twa->msl = &mcfg->memsegs[found_idx];\n+\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n+\n+struct rte_memseg_list *\n+malloc_heap_find_external_seg(void *va_addr, size_t len)\n+{\n+\tstruct extseg_walk_arg wa;\n+\tint res;\n+\n+\twa.va_addr = va_addr;\n+\twa.len = len;\n+\n+\tres = rte_memseg_list_walk_thread_unsafe(extseg_walk, &wa);\n+\n+\tif (res != 1) {\n+\t\t/* 0 means nothing was found, -1 shouldn't happen */\n+\t\tif (res == 0)\n+\t\t\trte_errno = ENOENT;\n+\t\treturn NULL;\n+\t}\n+\treturn wa.msl;\n+}\n+\n+int\n+malloc_heap_destroy_external_seg(struct rte_memseg_list *msl)\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,\n \t\tstruct rte_memseg_list *msl)\n@@ -1206,7 +1252,7 @@ malloc_heap_remove_external_memory(struct malloc_heap *heap, void *va_addr,\n \t\trte_errno = EBUSY;\n \t\treturn -1;\n \t}\n-\treturn destroy_seg(elem, len);\n+\treturn destroy_elem(elem, len);\n }\n \n int\ndiff --git a/lib/librte_eal/common/malloc_heap.h b/lib/librte_eal/common/malloc_heap.h\nindex 255a315b8..ca9ff666f 100644\n--- a/lib/librte_eal/common/malloc_heap.h\n+++ b/lib/librte_eal/common/malloc_heap.h\n@@ -44,6 +44,12 @@ malloc_heap_create_external_seg(void *va_addr, rte_iova_t iova_addrs[],\n \t\tunsigned int n_pages, size_t page_sz, const char *seg_name,\n \t\tunsigned int socket_id);\n \n+struct rte_memseg_list *\n+malloc_heap_find_external_seg(void *va_addr, size_t len);\n+\n+int\n+malloc_heap_destroy_external_seg(struct rte_memseg_list *msl);\n+\n int\n malloc_heap_add_external_memory(struct malloc_heap *heap,\n \t\tstruct rte_memseg_list *msl);\ndiff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c\nindex 66bfe63c3..9a82e3386 100644\n--- a/lib/librte_eal/common/rte_malloc.c\n+++ b/lib/librte_eal/common/rte_malloc.c\n@@ -396,6 +396,7 @@ 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+\tstruct rte_memseg_list *msl;\n \tint ret;\n \n \tif (heap_name == NULL || va_addr == NULL || len == 0 ||\n@@ -420,9 +421,19 @@ rte_malloc_heap_memory_remove(const char *heap_name, void *va_addr, size_t len)\n \t\tgoto unlock;\n \t}\n \n+\tmsl = malloc_heap_find_external_seg(va_addr, len);\n+\tif (msl == NULL) {\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+\tif (ret != 0)\n+\t\tgoto unlock;\n+\n+\tret = malloc_heap_destroy_external_seg(msl);\n \n unlock:\n \trte_rwlock_write_unlock(&mcfg->memory_hotplug_lock);\n@@ -430,63 +441,12 @@ rte_malloc_heap_memory_remove(const char *heap_name, void *va_addr, size_t len)\n \treturn ret;\n }\n \n-struct sync_mem_walk_arg {\n-\tvoid *va_addr;\n-\tsize_t len;\n-\tint result;\n-\tbool attach;\n-};\n-\n-static int\n-sync_mem_walk(const struct rte_memseg_list *msl, void *arg)\n-{\n-\tstruct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;\n-\tstruct sync_mem_walk_arg *wa = arg;\n-\tsize_t len = msl->page_sz * msl->memseg_arr.len;\n-\n-\tif (msl->base_va == wa->va_addr &&\n-\t\t\tlen == wa->len) {\n-\t\tstruct rte_memseg_list *found_msl;\n-\t\tint msl_idx, ret;\n-\n-\t\t/* msl is const */\n-\t\tmsl_idx = msl - mcfg->memsegs;\n-\t\tfound_msl = &mcfg->memsegs[msl_idx];\n-\n-\t\tif (wa->attach) {\n-\t\t\tret = rte_fbarray_attach(&found_msl->memseg_arr);\n-\t\t} else {\n-\t\t\t/* notify all subscribers that a memory area is about to\n-\t\t\t * be removed\n-\t\t\t */\n-\t\t\teal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE,\n-\t\t\t\t\tmsl->base_va, msl->len);\n-\t\t\tret = rte_fbarray_detach(&found_msl->memseg_arr);\n-\t\t}\n-\n-\t\tif (ret < 0) {\n-\t\t\twa->result = -rte_errno;\n-\t\t} else {\n-\t\t\t/* notify all subscribers that a new memory area was\n-\t\t\t * added\n-\t\t\t */\n-\t\t\tif (wa->attach)\n-\t\t\t\teal_memalloc_mem_event_notify(\n-\t\t\t\t\t\tRTE_MEM_EVENT_ALLOC,\n-\t\t\t\t\t\tmsl->base_va, msl->len);\n-\t\t\twa->result = 0;\n-\t\t}\n-\t\treturn 1;\n-\t}\n-\treturn 0;\n-}\n-\n static int\n sync_memory(const char *heap_name, void *va_addr, size_t len, bool attach)\n {\n \tstruct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;\n \tstruct malloc_heap *heap = NULL;\n-\tstruct sync_mem_walk_arg wa;\n+\tstruct rte_memseg_list *msl;\n \tint ret;\n \n \tif (heap_name == NULL || va_addr == NULL || len == 0 ||\n@@ -513,23 +473,35 @@ sync_memory(const char *heap_name, void *va_addr, size_t len, bool attach)\n \t}\n \n \t/* find corresponding memseg list to sync to */\n-\twa.va_addr = va_addr;\n-\twa.len = len;\n-\twa.result = -ENOENT; /* fail unless explicitly told to succeed */\n-\twa.attach = attach;\n-\n-\t/* we're already holding a read lock */\n-\trte_memseg_list_walk_thread_unsafe(sync_mem_walk, &wa);\n-\n-\tif (wa.result < 0) {\n-\t\trte_errno = -wa.result;\n+\tmsl = malloc_heap_find_external_seg(va_addr, len);\n+\tif (msl == NULL) {\n \t\tret = -1;\n-\t} else {\n-\t\t/* notify all subscribers that a new memory area was added */\n-\t\tif (attach)\n+\t\tgoto unlock;\n+\t}\n+\n+\tif (attach) {\n+\t\tret = rte_fbarray_attach(&msl->memseg_arr);\n+\t\tif (ret == 0) {\n+\t\t\t/* notify all subscribers that a new memory area was\n+\t\t\t * added.\n+\t\t\t */\n \t\t\teal_memalloc_mem_event_notify(RTE_MEM_EVENT_ALLOC,\n \t\t\t\t\tva_addr, len);\n-\t\tret = 0;\n+\t\t} else {\n+\t\t\tret = -1;\n+\t\t\tgoto unlock;\n+\t\t}\n+\t} else {\n+\t\t/* notify all subscribers that a memory area is about to\n+\t\t * be removed.\n+\t\t */\n+\t\teal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE,\n+\t\t\t\tmsl->base_va, msl->len);\n+\t\tret = rte_fbarray_detach(&msl->memseg_arr);\n+\t\tif (ret < 0) {\n+\t\t\tret = -1;\n+\t\t\tgoto unlock;\n+\t\t}\n \t}\n unlock:\n \trte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);\n",
    "prefixes": [
        "2/4"
    ]
}