get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 32460,
    "url": "https://patches.dpdk.org/api/patches/32460/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/bc77dcd45d3d4ca301fc4753bec25e5db93e94ec.1513681966.git.anatoly.burakov@intel.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<bc77dcd45d3d4ca301fc4753bec25e5db93e94ec.1513681966.git.anatoly.burakov@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/bc77dcd45d3d4ca301fc4753bec25e5db93e94ec.1513681966.git.anatoly.burakov@intel.com",
    "date": "2017-12-19T11:14:41",
    "name": "[dpdk-dev,RFC,v2,14/23] eal: add support for dynamic unmapping of pages",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "e4fcf2e656f1be808963971e2f5194b87607afb9",
    "submitter": {
        "id": 4,
        "url": "https://patches.dpdk.org/api/people/4/?format=api",
        "name": "Anatoly Burakov",
        "email": "anatoly.burakov@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/bc77dcd45d3d4ca301fc4753bec25e5db93e94ec.1513681966.git.anatoly.burakov@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/32460/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/32460/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 4131A1B1B8;\n\tTue, 19 Dec 2017 12:15:13 +0100 (CET)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id C2D831B021\n\tfor <dev@dpdk.org>; Tue, 19 Dec 2017 12:14:55 +0100 (CET)",
            "from orsmga003.jf.intel.com ([10.7.209.27])\n\tby orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t19 Dec 2017 03:14:55 -0800",
            "from irvmail001.ir.intel.com ([163.33.26.43])\n\tby orsmga003.jf.intel.com with ESMTP; 19 Dec 2017 03:14:53 -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\tvBJBEqtv003126; Tue, 19 Dec 2017 11:14:52 GMT",
            "from sivswdev01.ir.intel.com (localhost [127.0.0.1])\n\tby sivswdev01.ir.intel.com with ESMTP id vBJBEq7c010280;\n\tTue, 19 Dec 2017 11:14:52 GMT",
            "(from aburakov@localhost)\n\tby sivswdev01.ir.intel.com with LOCAL id vBJBEq1i010276;\n\tTue, 19 Dec 2017 11:14:52 GMT"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.45,426,1508828400\"; d=\"scan'208\";a=\"13553692\"",
        "From": "Anatoly Burakov <anatoly.burakov@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "andras.kovacs@ericsson.com, laszlo.vadkeri@ericsson.com,\n\tkeith.wiles@intel.com, benjamin.walker@intel.com,\n\tbruce.richardson@intel.com, thomas@monjalon.net",
        "Date": "Tue, 19 Dec 2017 11:14:41 +0000",
        "Message-Id": "<bc77dcd45d3d4ca301fc4753bec25e5db93e94ec.1513681966.git.anatoly.burakov@intel.com>",
        "X-Mailer": "git-send-email 1.7.0.7",
        "In-Reply-To": [
            "<cover.1513681966.git.anatoly.burakov@intel.com>",
            "<cover.1513681966.git.anatoly.burakov@intel.com>"
        ],
        "References": [
            "<cover.1513681966.git.anatoly.burakov@intel.com>",
            "<cover.1513681966.git.anatoly.burakov@intel.com>"
        ],
        "Subject": "[dpdk-dev] [RFC v2 14/23] eal: add support for dynamic unmapping of\n\tpages",
        "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/common/eal_memalloc.h       |   3 +\n lib/librte_eal/linuxapp/eal/eal_memalloc.c | 131 ++++++++++++++++++++++++++++-\n 2 files changed, 133 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/lib/librte_eal/common/eal_memalloc.h b/lib/librte_eal/common/eal_memalloc.h\nindex 59fd330..47e4367 100755\n--- a/lib/librte_eal/common/eal_memalloc.h\n+++ b/lib/librte_eal/common/eal_memalloc.h\n@@ -44,4 +44,7 @@ int\n eal_memalloc_alloc_page_bulk(struct rte_memseg **ms, int n, uint64_t size,\n \t\tint socket, bool exact);\n \n+int\n+eal_memalloc_free_page(struct rte_memseg *ms);\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 527c2f6..13172a0 100755\n--- a/lib/librte_eal/linuxapp/eal/eal_memalloc.c\n+++ b/lib/librte_eal/linuxapp/eal/eal_memalloc.c\n@@ -109,6 +109,18 @@ huge_recover_sigbus(void)\n \t}\n }\n \n+/*\n+ * uses fstat to report the size of a file on disk\n+ */\n+static bool\n+is_zero_length(int fd)\n+{\n+\tstruct stat st;\n+\tif (fstat(fd, &st) < 0)\n+\t\treturn false;\n+\treturn st.st_blocks == 0;\n+}\n+\n #ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES\n static bool\n prepare_numa(int *oldpolicy, struct bitmask *oldmask, int socket_id) {\n@@ -267,6 +279,61 @@ alloc_page(struct rte_memseg *ms, void *addr, uint64_t size, int socket_id,\n \treturn ret;\n }\n \n+static int\n+free_page(struct rte_memseg *ms, struct hugepage_info *hi, unsigned list_idx,\n+\t\tunsigned seg_idx) {\n+\tuint64_t fa_offset;\n+\tchar path[PATH_MAX];\n+\tint fd;\n+\n+\tfa_offset = seg_idx * ms->hugepage_sz;\n+\n+\tif (internal_config.single_file_segments) {\n+\t\teal_get_hugefile_path(path, sizeof(path), hi->hugedir, list_idx);\n+\t} else {\n+\t\teal_get_hugefile_path(path, sizeof(path), hi->hugedir,\n+\t\t\t\tlist_idx * RTE_MAX_MEMSEG_PER_LIST + seg_idx);\n+\t}\n+\n+\tmunmap(ms->addr, ms->hugepage_sz);\n+\n+\t// TODO: race condition?\n+\n+\tif (mmap(ms->addr, ms->hugepage_sz, 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+\tif (internal_config.single_file_segments) {\n+\t\t/* now, truncate or remove the original file */\n+\t\tfd = open(path, O_RDWR, 0600);\n+\t\tif (fd < 0) {\n+\t\t\tRTE_LOG(DEBUG, EAL, \"%s(): open failed: %s\\n\", __func__,\n+\t\t\t\t\tstrerror(errno));\n+\t\t\t// TODO: proper error handling\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,\n+\t\t\t\tfa_offset, ms->hugepage_sz)) {\n+\t\t\tRTE_LOG(DEBUG, EAL, \"Page deallocation failed: %s\\n\",\n+\t\t\t\tstrerror(errno));\n+\t\t}\n+\t\tif (is_zero_length(fd)) {\n+\t\t\tunlink(path);\n+\t\t}\n+\t\tclose(fd);\n+\t} else {\n+\t\tunlink(path);\n+\t}\n+\n+\tmemset(ms, 0, sizeof(*ms));\n+\n+\treturn 0;\n+}\n+\n int\n eal_memalloc_alloc_page_bulk(struct rte_memseg **ms, int n,\n \t\tuint64_t size, int socket, bool exact) {\n@@ -274,7 +341,7 @@ eal_memalloc_alloc_page_bulk(struct rte_memseg **ms, int n,\n \tstruct rte_memseg_list *msl = NULL;\n \tvoid *addr;\n \tunsigned msl_idx;\n-\tint cur_idx, next_idx, end_idx, i, ret = 0;\n+\tint cur_idx, next_idx, start_idx, end_idx, i, j, ret = 0;\n #ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES\n \tbool have_numa;\n \tint oldpolicy;\n@@ -366,6 +433,7 @@ eal_memalloc_alloc_page_bulk(struct rte_memseg **ms, int n,\n \t}\n \n \tend_idx = cur_idx + n;\n+\tstart_idx = cur_idx;\n \n #ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES\n \thave_numa = prepare_numa(&oldpolicy, oldmask, socket);\n@@ -387,6 +455,20 @@ eal_memalloc_alloc_page_bulk(struct rte_memseg **ms, int n,\n \t\t\t\tret = i;\n \t\t\t\tgoto restore_numa;\n \t\t\t}\n+\t\t\tRTE_LOG(DEBUG, EAL, \"exact amount of pages was requested, so returning %i allocated pages\\n\",\n+\t\t\t\ti);\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 = &msl->memseg_arr;\n+\n+\t\t\t\ttmp = rte_fbarray_get(arr, j);\n+\t\t\t\tif (free_page(tmp, hi, msl_idx, start_idx + j))\n+\t\t\t\t\trte_panic(\"Cannot free page\\n\");\n+\n+\t\t\t\trte_fbarray_set_used(arr, j, false);\n+\t\t\t}\n \t\t\tif (ms)\n \t\t\t\tmemset(ms, 0, sizeof(struct rte_memseg*) * n);\n \t\t\tret = -1;\n@@ -414,3 +496,50 @@ eal_memalloc_alloc_page(uint64_t size, int socket) {\n \t\treturn NULL;\n \treturn ms;\n }\n+\n+int\n+eal_memalloc_free_page(struct rte_memseg *ms) {\n+\tstruct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;\n+\tstruct rte_memseg_list *msl = NULL;\n+\tunsigned msl_idx, seg_idx;\n+\tstruct hugepage_info *hi = NULL;\n+\n+\t/* dynamic free not supported in legacy mode */\n+\tif (internal_config.legacy_mem)\n+\t\treturn -1;\n+\n+\tfor (int i = 0; i < (int) RTE_DIM(internal_config.hugepage_info); i++) {\n+\t\tif (ms->hugepage_sz ==\n+\t\t\t\tinternal_config.hugepage_info[i].hugepage_sz) {\n+\t\t\thi = &internal_config.hugepage_info[i];\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tif (!hi) {\n+\t\tRTE_LOG(ERR, EAL, \"Can't find relevant hugepage_info entry\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tfor (msl_idx = 0; msl_idx < RTE_MAX_MEMSEG_LISTS; msl_idx++) {\n+\t\tuintptr_t start_addr, end_addr;\n+\t\tstruct rte_memseg_list *cur = &mcfg->memsegs[msl_idx];\n+\n+\t\tstart_addr = (uintptr_t) cur->base_va;\n+\t\tend_addr = start_addr +\n+\t\t\t\tcur->memseg_arr.capacity * cur->hugepage_sz;\n+\n+\t\tif ((uintptr_t) ms->addr < start_addr ||\n+\t\t\t\t(uintptr_t) ms->addr >= end_addr) {\n+\t\t\tcontinue;\n+\t\t}\n+\t\tmsl = cur;\n+\t\tseg_idx = RTE_PTR_DIFF(ms->addr, start_addr) / ms->hugepage_sz;\n+\t\tbreak;\n+\t}\n+\tif (!msl) {\n+\t\tRTE_LOG(ERR, EAL, \"Couldn't find memseg list\\n\");\n+\t\treturn -1;\n+\t}\n+\trte_fbarray_set_used(&msl->memseg_arr, seg_idx, false);\n+\treturn free_page(ms, hi, msl_idx, seg_idx);\n+}\n",
    "prefixes": [
        "dpdk-dev",
        "RFC",
        "v2",
        "14/23"
    ]
}