From b2936251deeba22d4235cbdc4210cef07c4e99c2 Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: <6aacbbcbb67cbc45eee780eb9765bd066e299f19.1454769807.git.aquini@redhat.com> References: <6aacbbcbb67cbc45eee780eb9765bd066e299f19.1454769807.git.aquini@redhat.com> From: =?UTF-8?q?Krzysztof=20Ku=C5=82akowski?= Date: Thu, 22 Oct 2015 12:24:03 +0200 Subject: [PATCH 3/3] Fixed memkind_hugetlb_check_available() which was returning error despite the fact that nr_overcommit_hugepages was set to positive value. --- src/memkind_hugetlb.c | 67 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/src/memkind_hugetlb.c b/src/memkind_hugetlb.c index 9c8dd96..c59c97f 100644 --- a/src/memkind_hugetlb.c +++ b/src/memkind_hugetlb.c @@ -68,7 +68,6 @@ void memkind_hugetlb_init_once(void) assert(err == 0); } - int memkind_hugetlb_check_available_2mb(struct memkind *kind) { return memkind_hugetlb_check_available(kind, 2097152); @@ -86,20 +85,42 @@ static int memkind_hugetlb_check_available(struct memkind *kind, size_t huge_siz int errno_before; int num_read = 0; unsigned int node, num_node; - size_t nr_hugepages = 0; FILE *fid = NULL; nodemask_t nodemask; struct bitmask nodemask_bm = {NUMA_NUM_NODES, nodemask.n}; + char formatted_path[128]; + int snprintf_ret = 0; + size_t value_read = 0; + + size_t nr_persistent_hugepages = 0; const char *nr_path_fmt = "/sys/devices/system/node/node%u/hugepages/hugepages-%zukB/nr_hugepages"; - char nr_path[128]; - /* default huge page size is 2MB */ + size_t nr_overcommit_hugepages = 0; + const char *nr_overcommit_path_fmt = "/sys/kernel/mm/hugepages/hugepages-%zukB/nr_overcommit_hugepages"; + + /* on x86 default huge page size is 2MB */ if (huge_size == 0) { - huge_size = 2048; + huge_size = 2097152; } + /* convert input to kB */ - else { - huge_size = huge_size >> 10; + huge_size >>= 10; + + //read overcommit hugepages limit for this pagesize + snprintf_ret = snprintf(formatted_path, sizeof(formatted_path), nr_overcommit_path_fmt, huge_size); + if (snprintf_ret > 0 && snprintf_ret < sizeof(formatted_path)) { + errno_before = errno; + fid = fopen(formatted_path, "r"); + if (fid) { + num_read = fscanf(fid, "%zud", &value_read); + if(num_read) { + nr_overcommit_hugepages = value_read; + } + fclose(fid); + } + else { + errno = errno_before; + } } if (kind->ops->get_mbind_nodemask) { @@ -111,20 +132,28 @@ static int memkind_hugetlb_check_available(struct memkind *kind, size_t huge_siz num_node = numa_num_configured_nodes(); for (node = 0; !err && node < num_node; ++node) { if (numa_bitmask_isbitset(&nodemask_bm, node)) { - snprintf(nr_path, 128, nr_path_fmt, node, huge_size); - errno_before = errno; - fid = fopen(nr_path, "r"); - if (!fid) { - err = MEMKIND_ERROR_HUGETLB; - errno = errno_before; - } - else { - num_read = fscanf(fid, "%zud", &nr_hugepages); - fclose(fid); - if (!num_read || !nr_hugepages) { - err = MEMKIND_ERROR_HUGETLB; + nr_persistent_hugepages = 0; + snprintf_ret = snprintf(formatted_path, sizeof(formatted_path), nr_path_fmt, node, huge_size); + if(snprintf_ret > 0 && snprintf_ret < sizeof(formatted_path)) { + errno_before = errno; + fid = fopen(formatted_path, "r"); + if (fid) { + num_read = fscanf(fid, "%zud", &value_read); + if(num_read) { + nr_persistent_hugepages = value_read; + } + fclose(fid); + } + else { + errno = errno_before; } } + + //return error if there is no overcommit limit for that page size + //nor persistent hugepages for nodes of that kind + if (!nr_overcommit_hugepages && !nr_persistent_hugepages) { + err = MEMKIND_ERROR_HUGETLB; + } } } return err; -- 2.5.0