[dpdk-dev] Hugetlbfs mounted with size option leads to mmap failure

Tan, Jianfeng jianfeng.tan at intel.com
Fri Aug 28 14:39:36 CEST 2015


Hi Monroy,

As hugetlbfs mounted with option "size=xxx", and xxx is smaller than that from
/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages, error is raised
like, EAL: map_all_hugepages(): mmap failed: Cannot allocate memory.

Although this can be avoided by the parameter of "--sock-mem=", I wrote a patch
to rectify num_pages. Any comments would be highly appreciated.

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index 18858e2..db6a4d5 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -44,6 +44,7 @@
#include <unistd.h>
#include <errno.h>
#include <sys/queue.h>
+#include <mntent.h>
 #include <rte_memory.h>
#include <rte_memzone.h>
@@ -124,6 +125,50 @@ get_default_hp_size(void)
        return size;
}
+static uint64_t
+get_hugepages_mount_size(const char *mnt_dir)
+{
+       char *start, *end, *opt_size;
+       struct mntent *ent;
+       uint64_t size;
+       FILE *f;
+       int len;
+
+       f = setmntent("/proc/mounts", "r");
+       if (f == NULL) {
+               RTE_LOG(ERR, EAL, "setmntent() error: %s\n", strerror(errno));
+               return 0;
+       }
+       while (NULL != (ent = getmntent(f))) {
+               if (! strcmp(ent->mnt_dir, mnt_dir)) {
+                       break;
+               }
+       }
+       if (ent == NULL) {
+               RTE_LOG(ERR, EAL, "no hugetlbfs found at %s\n", mnt_dir);
+               return 0;
+       }
+
+       start = hasmntopt(ent, "size");
+       if (start == NULL) {
+               RTE_LOG(DEBUG, EAL, "option size not specified for %s\n", mnt_dir);
+               return 0;
+       }
+       start += strlen("size=");
+       end = strstr(start, ",");
+       if (end != NULL) {
+               len = end - start;
+       } else {
+               len = strlen(start);
+       }
+       opt_size = strndup(start, len);
+       size = rte_str_to_size(opt_size);
+       free(opt_size);
+
+       endmntent(f);
+       return size;
+}
+
static const char *
get_hugepage_dir(uint64_t hugepage_sz)
{
@@ -333,6 +378,17 @@ eal_hugepage_info_init(void)
                 * later they will be sorted */
                hpi->num_pages[0] = get_num_hugepages(dirent->d_name);
+               /* if mount_size < total_hugepages*hugepagesz correct it */
+
+               uint64_t size, num;
+               size = get_hugepages_mount_size(hpi->hugedir);
+               if (size != 0) {
+                       num = size / hpi->hugepage_sz;
+
+                       if (num < hpi->num_pages[0])
+                               hpi->num_pages[0] = num;
+               }
+
#ifndef RTE_ARCH_64
                /* for 32-bit systems, limit number of hugepages to
                 * 1GB per page size */

Thanks,
Jianfeng


More information about the dev mailing list