mem: check for memfd support in segment fd API
[dpdk.git] / lib / librte_eal / linuxapp / eal / eal_memalloc.c
index 7849395..a93548b 100644 (file)
 #include <sys/time.h>
 #include <signal.h>
 #include <setjmp.h>
+#ifdef F_ADD_SEALS /* if file sealing is supported, so is memfd */
+#include <linux/memfd.h>
+#define MEMFD_SUPPORTED
+#endif
 #ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
 #include <numa.h>
 #include <numaif.h>
@@ -53,8 +57,8 @@ const int anonymous_hugepages_supported =
 #endif
 
 /*
- * we don't actually care if memfd itself is supported - we only need to check
- * if memfd supports hugetlbfs, as that already implies memfd support.
+ * we've already checked memfd support at compile-time, but we also need to
+ * check if we can create hugepage files with memfd.
  *
  * also, this is not a constant, because while we may be *compiled* with memfd
  * hugetlbfs support, we might not be *running* on a system that supports memfd
@@ -63,10 +67,11 @@ const int anonymous_hugepages_supported =
  */
 static int memfd_create_supported =
 #ifdef MFD_HUGETLB
-#define MEMFD_SUPPORTED
                1;
+#define RTE_MFD_HUGETLB MFD_HUGETLB
 #else
                0;
+#define RTE_MFD_HUGETLB 4U
 #endif
 
 /*
@@ -338,12 +343,12 @@ get_seg_memfd(struct hugepage_info *hi __rte_unused,
        int fd;
        char segname[250]; /* as per manpage, limit is 249 bytes plus null */
 
+       int flags = RTE_MFD_HUGETLB | pagesz_flags(hi->hugepage_sz);
+
        if (internal_config.single_file_segments) {
                fd = fd_list[list_idx].memseg_list_fd;
 
                if (fd < 0) {
-                       int flags = MFD_HUGETLB | pagesz_flags(hi->hugepage_sz);
-
                        snprintf(segname, sizeof(segname), "seg_%i", list_idx);
                        fd = memfd_create(segname, flags);
                        if (fd < 0) {
@@ -357,8 +362,6 @@ get_seg_memfd(struct hugepage_info *hi __rte_unused,
                fd = fd_list[list_idx].fds[seg_idx];
 
                if (fd < 0) {
-                       int flags = MFD_HUGETLB | pagesz_flags(hi->hugepage_sz);
-
                        snprintf(segname, sizeof(segname), "seg_%i-%i",
                                        list_idx, seg_idx);
                        fd = memfd_create(segname, flags);
@@ -1542,6 +1545,17 @@ int
 eal_memalloc_get_seg_fd(int list_idx, int seg_idx)
 {
        int fd;
+
+       if (internal_config.in_memory || internal_config.no_hugetlbfs) {
+#ifndef MEMFD_SUPPORTED
+               /* in in-memory or no-huge mode, we rely on memfd support */
+               return -ENOTSUP;
+#endif
+               /* memfd supported, but hugetlbfs memfd may not be */
+               if (!internal_config.no_hugetlbfs && !memfd_create_supported)
+                       return -ENOTSUP;
+       }
+
        if (internal_config.single_file_segments) {
                fd = fd_list[list_idx].memseg_list_fd;
        } else if (fd_list[list_idx].len == 0) {
@@ -1565,7 +1579,7 @@ test_memfd_create(void)
                int pagesz_flag = pagesz_flags(pagesz);
                int flags;
 
-               flags = pagesz_flag | MFD_HUGETLB;
+               flags = pagesz_flag | RTE_MFD_HUGETLB;
                int fd = memfd_create("test", flags);
                if (fd < 0) {
                        /* we failed - let memalloc know this isn't working */
@@ -1589,6 +1603,16 @@ eal_memalloc_get_seg_fd_offset(int list_idx, int seg_idx, size_t *offset)
 {
        struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
 
+       if (internal_config.in_memory || internal_config.no_hugetlbfs) {
+#ifndef MEMFD_SUPPORTED
+               /* in in-memory or no-huge mode, we rely on memfd support */
+               return -ENOTSUP;
+#endif
+               /* memfd supported, but hugetlbfs memfd may not be */
+               if (!internal_config.no_hugetlbfs && !memfd_create_supported)
+                       return -ENOTSUP;
+       }
+
        /* fd_list not initialized? */
        if (fd_list[list_idx].len == 0)
                return -ENODEV;