get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 37038,
    "url": "http://patches.dpdk.org/api/patches/37038/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/02f3ee3f5f1d5fc0142043960f8d3fa6c8be8eb8.1522797505.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": "<02f3ee3f5f1d5fc0142043960f8d3fa6c8be8eb8.1522797505.git.anatoly.burakov@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/02f3ee3f5f1d5fc0142043960f8d3fa6c8be8eb8.1522797505.git.anatoly.burakov@intel.com",
    "date": "2018-04-03T23:22:04",
    "name": "[dpdk-dev,v3,52/68] eal: add support for unmapping pages at runtime",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "12609d99878ab078fbc9d4b1808a3be6dacca4db",
    "submitter": {
        "id": 4,
        "url": "http://patches.dpdk.org/api/people/4/?format=api",
        "name": "Anatoly Burakov",
        "email": "anatoly.burakov@intel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/02f3ee3f5f1d5fc0142043960f8d3fa6c8be8eb8.1522797505.git.anatoly.burakov@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/37038/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/37038/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 297CF1BA90;\n\tWed,  4 Apr 2018 01:23:48 +0200 (CEST)",
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n\tby dpdk.org (Postfix) with ESMTP id 96C411B890\n\tfor <dev@dpdk.org>; Wed,  4 Apr 2018 01:22:35 +0200 (CEST)",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n\tby fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t03 Apr 2018 16:22:34 -0700",
            "from irvmail001.ir.intel.com ([163.33.26.43])\n\tby fmsmga006.fm.intel.com with ESMTP; 03 Apr 2018 16:22:31 -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\tw33NMVfR013194; Wed, 4 Apr 2018 00:22:31 +0100",
            "from sivswdev01.ir.intel.com (localhost [127.0.0.1])\n\tby sivswdev01.ir.intel.com with ESMTP id w33NMVIM014966;\n\tWed, 4 Apr 2018 00:22:31 +0100",
            "(from aburakov@localhost)\n\tby sivswdev01.ir.intel.com with LOCAL id w33NMUGs014961;\n\tWed, 4 Apr 2018 00:22:30 +0100"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.48,403,1517904000\"; d=\"scan'208\";a=\"217300763\"",
        "From": "Anatoly Burakov <anatoly.burakov@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Bruce Richardson <bruce.richardson@intel.com>, keith.wiles@intel.com,\n\tjianfeng.tan@intel.com, andras.kovacs@ericsson.com,\n\tlaszlo.vadkeri@ericsson.com, benjamin.walker@intel.com,\n\tthomas@monjalon.net, konstantin.ananyev@intel.com,\n\tkuralamudhan.ramakrishnan@intel.com, louise.m.daly@intel.com,\n\tnelio.laranjeiro@6wind.com, yskoh@mellanox.com, pepperjo@japf.ch,\n\tjerin.jacob@caviumnetworks.com, hemant.agrawal@nxp.com,\n\tolivier.matz@6wind.com, shreyansh.jain@nxp.com,\n\tgowrishankar.m@linux.vnet.ibm.com",
        "Date": "Wed,  4 Apr 2018 00:22:04 +0100",
        "Message-Id": "<02f3ee3f5f1d5fc0142043960f8d3fa6c8be8eb8.1522797505.git.anatoly.burakov@intel.com>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "In-Reply-To": [
            "<cover.1522797505.git.anatoly.burakov@intel.com>",
            "<cover.1522797505.git.anatoly.burakov@intel.com>"
        ],
        "References": [
            "<cover.1522797505.git.anatoly.burakov@intel.com>",
            "<cover.1520428025.git.anatoly.burakov@intel.com>\n\t<cover.1522797505.git.anatoly.burakov@intel.com>"
        ],
        "Subject": "[dpdk-dev] [PATCH v3 52/68] eal: add support for unmapping pages at\n\truntime",
        "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://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": "<https://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": "This isn't used anywhere yet, but the support is now there. Also,\nadding cleanup to allocation procedures, so that if we fail to\nallocate everything we asked for, we can free all of it back.\n\nSigned-off-by: Anatoly Burakov <anatoly.burakov@intel.com>\n---\n lib/librte_eal/bsdapp/eal/eal_memalloc.c   |  15 +++\n lib/librte_eal/common/eal_memalloc.h       |  14 +++\n lib/librte_eal/linuxapp/eal/eal_memalloc.c | 149 ++++++++++++++++++++++++++++-\n 3 files changed, 177 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/lib/librte_eal/bsdapp/eal/eal_memalloc.c b/lib/librte_eal/bsdapp/eal/eal_memalloc.c\nindex 8c30670..e7bcd2b 100644\n--- a/lib/librte_eal/bsdapp/eal/eal_memalloc.c\n+++ b/lib/librte_eal/bsdapp/eal/eal_memalloc.c\n@@ -24,3 +24,18 @@ eal_memalloc_alloc_seg(size_t __rte_unused page_sz, int __rte_unused socket)\n \tRTE_LOG(ERR, EAL, \"Memory hotplug not supported on FreeBSD\\n\");\n \treturn NULL;\n }\n+\n+int\n+eal_memalloc_free_seg(struct rte_memseg *ms __rte_unused)\n+{\n+\tRTE_LOG(ERR, EAL, \"Memory hotplug not supported on FreeBSD\\n\");\n+\treturn -1;\n+}\n+\n+int\n+eal_memalloc_free_seg_bulk(struct rte_memseg **ms __rte_unused,\n+\t\tint n_segs __rte_unused)\n+{\n+\tRTE_LOG(ERR, EAL, \"Memory hotplug not supported on FreeBSD\\n\");\n+\treturn -1;\n+}\ndiff --git a/lib/librte_eal/common/eal_memalloc.h b/lib/librte_eal/common/eal_memalloc.h\nindex f628514..6017345 100644\n--- a/lib/librte_eal/common/eal_memalloc.h\n+++ b/lib/librte_eal/common/eal_memalloc.h\n@@ -28,4 +28,18 @@ int\n eal_memalloc_alloc_seg_bulk(struct rte_memseg **ms, int n_segs, size_t page_sz,\n \t\tint socket, bool exact);\n \n+/*\n+ * Deallocate segment\n+ */\n+int\n+eal_memalloc_free_seg(struct rte_memseg *ms);\n+\n+/*\n+ * Deallocate `n_segs` segments. Returns 0 on successful deallocation of all\n+ * segments, returns -1 on error. Any segments that could have been deallocated,\n+ * will be deallocated even in case of error.\n+ */\n+int\n+eal_memalloc_free_seg_bulk(struct rte_memseg **ms, int n_segs);\n+\n #endif // EAL_MEMALLOC_H\ndiff --git a/lib/librte_eal/linuxapp/eal/eal_memalloc.c b/lib/librte_eal/linuxapp/eal/eal_memalloc.c\nindex 45ea0ad..118b12d 100644\n--- a/lib/librte_eal/linuxapp/eal/eal_memalloc.c\n+++ b/lib/librte_eal/linuxapp/eal/eal_memalloc.c\n@@ -289,6 +289,48 @@ alloc_seg(struct rte_memseg *ms, void *addr, int socket_id,\n \treturn -1;\n }\n \n+static int\n+free_seg(struct rte_memseg *ms, struct hugepage_info *hi,\n+\t\tunsigned int list_idx, unsigned int seg_idx)\n+{\n+\tchar path[PATH_MAX];\n+\tint fd, ret;\n+\n+\t/* erase page data */\n+\tmemset(ms->addr, 0, ms->len);\n+\n+\tif (mmap(ms->addr, ms->len, PROT_READ,\n+\t\t\tMAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0) ==\n+\t\t\t\tMAP_FAILED) {\n+\t\tRTE_LOG(DEBUG, EAL, \"couldn't unmap page\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tfd = get_seg_fd(path, sizeof(path), hi, list_idx, seg_idx);\n+\tif (fd < 0)\n+\t\treturn -1;\n+\n+\t/* if we're able to take out a write lock, we're the last one\n+\t * holding onto this page.\n+\t */\n+\n+\tret = lock(fd, 0, ms->len, F_WRLCK);\n+\tif (ret >= 0) {\n+\t\t/* no one else is using this page */\n+\t\tif (ret == 1)\n+\t\t\tunlink(path);\n+\t\tret = lock(fd, 0, ms->len, F_UNLCK);\n+\t\tif (ret != 1)\n+\t\t\tRTE_LOG(ERR, EAL, \"%s(): unable to unlock file %s\\n\",\n+\t\t\t\t__func__, path);\n+\t}\n+\tclose(fd);\n+\n+\tmemset(ms, 0, sizeof(*ms));\n+\n+\treturn ret;\n+}\n+\n struct alloc_walk_param {\n \tstruct hugepage_info *hi;\n \tstruct rte_memseg **ms;\n@@ -305,7 +347,7 @@ alloc_seg_walk(const struct rte_memseg_list *msl, void *arg)\n \tstruct alloc_walk_param *wa = arg;\n \tstruct rte_memseg_list *cur_msl;\n \tsize_t page_sz;\n-\tint cur_idx;\n+\tint cur_idx, start_idx, j;\n \tunsigned int msl_idx, need, i;\n \n \tif (msl->page_sz != wa->page_sz)\n@@ -324,6 +366,7 @@ alloc_seg_walk(const struct rte_memseg_list *msl, void *arg)\n \tcur_idx = rte_fbarray_find_next_n_free(&cur_msl->memseg_arr, 0, need);\n \tif (cur_idx < 0)\n \t\treturn 0;\n+\tstart_idx = cur_idx;\n \n \tfor (i = 0; i < need; i++, cur_idx++) {\n \t\tstruct rte_memseg *cur;\n@@ -341,6 +384,25 @@ alloc_seg_walk(const struct rte_memseg_list *msl, void *arg)\n \t\t\t/* if exact number wasn't requested, stop */\n \t\t\tif (!wa->exact)\n \t\t\t\tgoto out;\n+\n+\t\t\t/* clean up */\n+\t\t\tfor (j = start_idx; j < cur_idx; j++) {\n+\t\t\t\tstruct rte_memseg *tmp;\n+\t\t\t\tstruct rte_fbarray *arr =\n+\t\t\t\t\t\t&cur_msl->memseg_arr;\n+\n+\t\t\t\ttmp = rte_fbarray_get(arr, j);\n+\t\t\t\tif (free_seg(tmp, wa->hi, msl_idx,\n+\t\t\t\t\t\tstart_idx + j)) {\n+\t\t\t\t\tRTE_LOG(ERR, EAL, \"Cannot free page\\n\");\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\n+\t\t\t\trte_fbarray_set_free(arr, j);\n+\t\t\t}\n+\t\t\t/* clear the list */\n+\t\t\tif (wa->ms)\n+\t\t\t\tmemset(wa->ms, 0, sizeof(*wa->ms) * wa->n_segs);\n \t\t\treturn -1;\n \t\t}\n \t\tif (wa->ms)\n@@ -351,7 +413,39 @@ alloc_seg_walk(const struct rte_memseg_list *msl, void *arg)\n out:\n \twa->segs_allocated = i;\n \treturn 1;\n+}\n+\n+struct free_walk_param {\n+\tstruct hugepage_info *hi;\n+\tstruct rte_memseg *ms;\n+};\n+static int\n+free_seg_walk(const struct rte_memseg_list *msl, void *arg)\n+{\n+\tstruct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;\n+\tstruct rte_memseg_list *found_msl;\n+\tstruct free_walk_param *wa = arg;\n+\tuintptr_t start_addr, end_addr;\n+\tint msl_idx, seg_idx;\n \n+\tstart_addr = (uintptr_t) msl->base_va;\n+\tend_addr = start_addr + msl->memseg_arr.len * (size_t)msl->page_sz;\n+\n+\tif ((uintptr_t)wa->ms->addr < start_addr ||\n+\t\t\t(uintptr_t)wa->ms->addr >= end_addr)\n+\t\treturn 0;\n+\n+\tmsl_idx = msl - mcfg->memsegs;\n+\tseg_idx = RTE_PTR_DIFF(wa->ms->addr, start_addr) / msl->page_sz;\n+\n+\t/* msl is const */\n+\tfound_msl = &mcfg->memsegs[msl_idx];\n+\n+\trte_fbarray_set_free(&found_msl->memseg_arr, seg_idx);\n+\tif (free_seg(wa->ms, wa->hi, msl_idx, seg_idx))\n+\t\treturn -1;\n+\n+\treturn 1;\n }\n \n int\n@@ -427,3 +521,56 @@ eal_memalloc_alloc_seg(size_t page_sz, int socket)\n \t/* return pointer to newly allocated memseg */\n \treturn ms;\n }\n+\n+int\n+eal_memalloc_free_seg_bulk(struct rte_memseg **ms, int n_segs)\n+{\n+\tint seg, ret = 0;\n+\n+\t/* dynamic free not supported in legacy mode */\n+\tif (internal_config.legacy_mem)\n+\t\treturn -1;\n+\n+\tfor (seg = 0; seg < n_segs; seg++) {\n+\t\tstruct rte_memseg *cur = ms[seg];\n+\t\tstruct hugepage_info *hi = NULL;\n+\t\tstruct free_walk_param wa;\n+\t\tint i, walk_res;\n+\n+\t\tmemset(&wa, 0, sizeof(wa));\n+\n+\t\tfor (i = 0; i < (int)RTE_DIM(internal_config.hugepage_info);\n+\t\t\t\ti++) {\n+\t\t\thi = &internal_config.hugepage_info[i];\n+\t\t\tif (cur->hugepage_sz == hi->hugepage_sz) {\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\tif (i == (int)RTE_DIM(internal_config.hugepage_info)) {\n+\t\t\tRTE_LOG(ERR, EAL, \"Can't find relevant hugepage_info entry\\n\");\n+\t\t\tret = -1;\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\twa.ms = cur;\n+\t\twa.hi = hi;\n+\n+\t\twalk_res = rte_memseg_list_walk(free_seg_walk, &wa);\n+\t\tif (walk_res == 1)\n+\t\t\tcontinue;\n+\t\tif (walk_res == 0)\n+\t\t\tRTE_LOG(ERR, EAL, \"Couldn't find memseg list\\n\");\n+\t\tret = -1;\n+\t}\n+\treturn ret;\n+}\n+\n+int\n+eal_memalloc_free_seg(struct rte_memseg *ms)\n+{\n+\t/* dynamic free not supported in legacy mode */\n+\tif (internal_config.legacy_mem)\n+\t\treturn -1;\n+\n+\treturn eal_memalloc_free_seg_bulk(&ms, 1);\n+}\n",
    "prefixes": [
        "dpdk-dev",
        "v3",
        "52/68"
    ]
}