[LTP] [PATCH 06/29] Hugetlb: Migrating libhugetlbfs fadvise_reserve
Tarun Sahu
tsahu@linux.ibm.com
Sun Oct 16 14:57:08 CEST 2022
Migrating the libhugetlbfs/testcases/fadvise_reserve.c test
Test Description: fadvise() on some kernels can cause the reservation
counter to get corrupted. The problem is that the patches are allocated for
the reservation but not faulted in at the time of allocation. The counters
do not get updated and effectively "leak". This test identifies whether the
kernel is vulnerable to the problem or not. It's fixed in kernel by 'commit
f2deae9d4e70 ("Remove implementation of readpage from the hugetlbfs_aops")'
Signed-off-by: Tarun Sahu <tsahu@linux.ibm.com>
---
runtest/hugetlb | 1 +
testcases/kernel/mem/.gitignore | 1 +
.../kernel/mem/hugetlb/hugemmap/hugemmap12.c | 114 ++++++++++++++++++
3 files changed, 116 insertions(+)
create mode 100644 testcases/kernel/mem/hugetlb/hugemmap/hugemmap12.c
diff --git a/runtest/hugetlb b/runtest/hugetlb
index b9ee7227d..b019c4195 100644
--- a/runtest/hugetlb
+++ b/runtest/hugetlb
@@ -8,6 +8,7 @@ hugemmap08 hugemmap08
hugemmap09 hugemmap09
hugemmap10 hugemmap10
hugemmap11 hugemmap11
+hugemmap12 hugemmap12
hugemmap05_1 hugemmap05 -m
hugemmap05_2 hugemmap05 -s
hugemmap05_3 hugemmap05 -s -m
diff --git a/testcases/kernel/mem/.gitignore b/testcases/kernel/mem/.gitignore
index 3e64b67be..ec250592d 100644
--- a/testcases/kernel/mem/.gitignore
+++ b/testcases/kernel/mem/.gitignore
@@ -9,6 +9,7 @@
/hugetlb/hugemmap/hugemmap09
/hugetlb/hugemmap/hugemmap10
/hugetlb/hugemmap/hugemmap11
+/hugetlb/hugemmap/hugemmap12
/hugetlb/hugeshmat/hugeshmat01
/hugetlb/hugeshmat/hugeshmat02
/hugetlb/hugeshmat/hugeshmat03
diff --git a/testcases/kernel/mem/hugetlb/hugemmap/hugemmap12.c b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap12.c
new file mode 100644
index 000000000..9773199ca
--- /dev/null
+++ b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap12.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * Copyright (C) 2005-2006 IBM Corporation.
+ *
+ * Test Name: fadvise_reserve
+ *
+ * Test Description: fadvise() on some kernels can cause the reservation
+ * counter to get corrupted. The problem is that the patches are allocated for
+ * the reservation but not faulted in at the time of allocation. The counters
+ * do not get updated and effectively "leak". This test identifies whether the
+ * kernel is vulnerable to the problem or not. It's fixed in kernel by commit
+ * f2deae9d4e70793568ef9e85d227abb7bef5b622.
+ *
+ * HISTORY
+ * Written by Mel Gorman
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <sys/mount.h>
+#include <limits.h>
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include "hugetlb.h"
+
+static long hpage_size;
+static int fd = -1;
+static char hfile[MAXPATHLEN];
+static char *verbose;
+
+static void run_test(void)
+{
+ void *p;
+ unsigned long initial_rsvd, map_rsvd, fadvise_rsvd, end_rsvd;
+
+ fd = SAFE_OPEN(hfile, O_RDWR | O_CREAT, 0600);
+ SAFE_UNLINK(hfile);
+
+ initial_rsvd = SAFE_READ_MEMINFO("HugePages_Rsvd:");
+ if (verbose)
+ tst_res(TINFO, "Reserve count before map: %lu", initial_rsvd);
+
+ /* mmap a region and record reservations */
+ p = SAFE_MMAP(NULL, hpage_size, PROT_READ|PROT_WRITE, MAP_SHARED,
+ fd, 0);
+ map_rsvd = SAFE_READ_MEMINFO("HugePages_Rsvd:");
+ if (verbose)
+ tst_res(TINFO, "Reserve count after map: %lu", map_rsvd);
+
+ /* fadvise the region and record reservations */
+ if (posix_fadvise(fd, 0, hpage_size, POSIX_FADV_WILLNEED) == -1) {
+ tst_res(TFAIL|TERRNO, "fadvise()");
+ goto fail;
+ }
+ fadvise_rsvd = SAFE_READ_MEMINFO("HugePages_Rsvd:");
+ if (verbose)
+ tst_res(TINFO, "Reserve count after fadvise: %lu", fadvise_rsvd);
+
+ /* Write the region */
+ memset(p, 1, hpage_size);
+
+ /* Free region */
+ SAFE_MUNMAP(p, hpage_size);
+ SAFE_CLOSE(fd);
+ end_rsvd = SAFE_READ_MEMINFO("HugePages_Rsvd:");
+ if (verbose)
+ tst_res(TINFO, "Reserve count after close: %lu", end_rsvd);
+
+ /* Reserve count should match initial reserve count */
+ if (end_rsvd != initial_rsvd) {
+ tst_res(TFAIL, "Reserve leaked: %lu != %lu", end_rsvd, initial_rsvd);
+ goto fail;
+ }
+ tst_res(TPASS, "Successful");
+ return;
+fail:
+ tst_brk(TBROK, "Once failed, No point in continuing the test");
+}
+
+static void setup(void)
+{
+ if (tst_hugepages < 1)
+ tst_brk(TCONF, "Not enough hugepages for testing.");
+
+ if (!Hopt)
+ Hopt = tst_get_tmpdir();
+ SAFE_MOUNT("none", Hopt, "hugetlbfs", 0, NULL);
+
+ snprintf(hfile, sizeof(hfile), "%s/ltp_hugetlbfile%d", Hopt, getpid());
+ hpage_size = SAFE_READ_MEMINFO("Hugepagesize:")*1024;
+}
+
+static void cleanup(void)
+{
+ if (fd >= 0)
+ SAFE_CLOSE(fd);
+ umount2(Hopt, MNT_DETACH);
+}
+
+static struct tst_test test = {
+ .needs_root = 1,
+ .needs_tmpdir = 1,
+ .options = (struct tst_option[]) {
+ {"v", &verbose, "Turns on verbose mode"},
+ {"H:", &Hopt, "Location of hugetlbfs, i.e. -H /var/hugetlbfs"},
+ {"s:", &nr_opt, "Set the number of the been allocated hugepages"},
+ {}
+ },
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run_test,
+ .hugepages = {1, TST_REQUEST},
+};
--
2.31.1
More information about the ltp
mailing list