From: Ackerley Tng <[email protected]>

Run the same write/read test for a file on a hugetlbfs mount, in addition
to a memfd.

Use FIXTURE_VARIANT for parametrized testing. Use an unlinked fd to make
save cleanup steps later.

Signed-off-by: Ackerley Tng <[email protected]>
---
 tools/testing/selftests/mm/hugepage-mmap.c | 85 ++++++++++++++++++++++++++++--
 1 file changed, 80 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/mm/hugepage-mmap.c 
b/tools/testing/selftests/mm/hugepage-mmap.c
index 9c8a0638d04b8..dd9fccb209b10 100644
--- a/tools/testing/selftests/mm/hugepage-mmap.c
+++ b/tools/testing/selftests/mm/hugepage-mmap.c
@@ -15,36 +15,111 @@
 #include <unistd.h>
 #include <sys/mman.h>
 #include <fcntl.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <limits.h>
 #include "kselftest_harness.h"
 
+static int hugetlbfs_unlinked_fd(const char *mount)
+{
+       char path[PATH_MAX];
+       int fd;
+
+       snprintf(path, sizeof(path), "%s/hugepage-mmap-XXXXXX", mount);
+       fd = mkstemp(path);
+       if (fd < 0)
+               return fd;
+
+       unlink(path);
+       return fd;
+}
+
 #define LENGTH (256UL*1024*1024)
 #define PROTECTION (PROT_READ | PROT_WRITE)
 
+enum fd_kind {
+       MEMFD,
+       HUGETLBFS_FD,
+};
+
 FIXTURE(hugepage_mmap)
 {
        int fd;
        char *addr;
+       char mount_dir[PATH_MAX];
+};
+
+static int fd_create(struct __test_metadata *_metadata,
+               FIXTURE_DATA(hugepage_mmap) *self, enum fd_kind fd_kind)
+{
+       switch (fd_kind) {
+       case MEMFD:
+               return memfd_create("hugepage-mmap", MFD_HUGETLB);
+       case HUGETLBFS_FD: {
+               snprintf(self->mount_dir, sizeof(self->mount_dir),
+                        "/tmp/hugepage-mmap-XXXXXX");
+               ASSERT_NE(NULL, mkdtemp(self->mount_dir))
+               {
+                       TH_LOG("mkdtemp() failed: %s", strerror(errno));
+               }
+               ASSERT_EQ(0, mount("none", self->mount_dir, "hugetlbfs", 0,
+                                  "pagesize=2M"))
+               {
+                       TH_LOG("mount() failed: %s", strerror(errno));
+               }
+               return hugetlbfs_unlinked_fd(self->mount_dir);
+       }
+       default:
+               return -1;
+       };
+}
+
+FIXTURE_VARIANT(hugepage_mmap)
+{
+       enum fd_kind fd_kind;
+};
+
+FIXTURE_VARIANT_ADD(hugepage_mmap, memfd)
+{
+       .fd_kind = MEMFD,
+};
+
+FIXTURE_VARIANT_ADD(hugepage_mmap, hugetlbfs_fd)
+{
+       .fd_kind = HUGETLBFS_FD,
 };
 
 FIXTURE_SETUP(hugepage_mmap)
 {
-       self->fd = memfd_create("hugepage-mmap", MFD_HUGETLB);
+       self->fd = -1;
+       self->addr = MAP_FAILED;
+       self->mount_dir[0] = '\0';
+       /* Enable teardown to cleanup on any assertions in FIXTURE_SETUP(). */
+       *_metadata->no_teardown = false;
+
+       self->fd = fd_create(_metadata, self, variant->fd_kind);
        ASSERT_GE(self->fd, 0) {
-               TH_LOG("memfd_create() failed: %s", strerror(errno));
+               TH_LOG("fd creation failed: %s", strerror(errno));
        }
 
        self->addr = mmap(NULL, LENGTH, PROTECTION, MAP_SHARED, self->fd, 0);
        ASSERT_NE(MAP_FAILED, self->addr) {
                TH_LOG("mmap(): %s", strerror(errno));
-               close(self->fd);
        }
        TH_LOG("Returned address is %p", self->addr);
 }
 
 FIXTURE_TEARDOWN(hugepage_mmap)
 {
-       munmap(self->addr, LENGTH);
-       close(self->fd);
+       if (self->addr != MAP_FAILED)
+               munmap(self->addr, LENGTH);
+       if (self->fd >= 0)
+               close(self->fd);
+
+       if (variant->fd_kind == HUGETLBFS_FD && self->mount_dir[0]) {
+               umount(self->mount_dir);
+               rmdir(self->mount_dir);
+       }
 }
 
 TEST_F(hugepage_mmap, read_write)

-- 
2.54.0.563.g4f69b47b94-goog



Reply via email to