aboutsummaryrefslogtreecommitdiff
path: root/tests/testutils.c
diff options
context:
space:
mode:
authorAdam Litke <agl@us.ibm.com>2008-07-17 19:14:58 +0000
committerNishanth Aravamudan <nacc@us.ibm.com>2008-07-21 18:46:23 -0700
commit0f751044c997521b8955f50c1022f725a0cda6a1 (patch)
treea7815bfa9540470fadb6b9b9479263a67ad06cd7 /tests/testutils.c
parent170ee4e04f4d121e403d39f4ac5aef7a48189a09 (diff)
downloadlibhugetlbfs-0f751044c997521b8955f50c1022f725a0cda6a1.tar.gz
tests: Handle expected differences brought on by private reservations
The private reservations feature in new kernels changes the semantics of private huge page mappings in ways that are recognizable by the libhugetlbfs test suite. So far, counters and quota are effected. Reserved private mappings now affect the pool counters in the same way as shared mappings. FS quota is now allocated up-front (mmap time) for private mappings so going over quota will now cause the mmap to fail rather than a SIGBUS at page instantiation time. To preserve backwards compatibility, the test suite must correctly test kernels with and without private reservation support. To achieve this, a function to check the running kernel's semantics is needed. This patch adds a function that attempts to check for private reservations. Use of the pool counters in the manner employed is racy but since this is a test suite and meant to be run by itself, the counters method should work. The function is clearly commented to warn against using it for real programs. Signed-off-by: Adam Litke <agl@us.ibm.com> Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Diffstat (limited to 'tests/testutils.c')
-rw-r--r--tests/testutils.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/tests/testutils.c b/tests/testutils.c
index 9d48482..969f42c 100644
--- a/tests/testutils.c
+++ b/tests/testutils.c
@@ -33,6 +33,7 @@
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
+#include <sys/mman.h>
#include <fcntl.h>
#include "hugetests.h"
@@ -287,3 +288,64 @@ int remove_shmid(int shmid)
}
return 0;
}
+
+/* WARNING: This function relies on the hugetlb pool counters in a way that
+ * is known to be racy. Due to the expected usage of hugetlbfs test cases, the
+ * risk of a race is acceptible. This function should NOT be used for real
+ * applications.
+ */
+int kernel_has_private_reservations(int fd)
+{
+ long t, f, r, s;
+ long nt, nf, nr, ns;
+ void *map;
+
+ /* Read pool counters */
+ t = read_meminfo("HugePages_Total:");
+ f = read_meminfo("HugePages_Free:");
+ r = read_meminfo("HugePages_Rsvd:");
+ s = read_meminfo("HugePages_Surp:");
+
+ if (fd < 0) {
+ ERROR("kernel_has_private_reservations: hugetlbfs_unlinked_fd: "
+ "%s\n", strerror(errno));
+ return -1;
+ }
+ map = mmap(NULL, gethugepagesize(), PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (map == MAP_FAILED) {
+ ERROR("kernel_has_private_reservations: mmap: %s\n",
+ strerror(errno));
+ return -1;
+ }
+
+ /* Recheck the counters */
+ nt = read_meminfo("HugePages_Total:");
+ nf = read_meminfo("HugePages_Free:");
+ nr = read_meminfo("HugePages_Rsvd:");
+ ns = read_meminfo("HugePages_Surp:");
+
+ munmap(map, gethugepagesize());
+
+ /*
+ * There are only three valid cases:
+ * 1) If a surplus page was allocated to create a reservation, all
+ * four pool counters increment
+ * 2) All counters remain the same except for Hugepages_Rsvd, then
+ * a reservation was created using an existing pool page.
+ * 3) All counters remain the same, indicates that no reservation has
+ * been created
+ */
+ if ((nt == t + 1) && (nf == f + 1) && (ns == s + 1) && (nr == r + 1)) {
+ return 1;
+ } else if ((nt == t) && (nf == f) && (ns == s)) {
+ if (nr == r + 1)
+ return 1;
+ else if (nr == r)
+ return 0;
+ } else {
+ ERROR("kernel_has_private_reservations: bad counter state - "
+ "T:%li F:%li R:%li S:%li -> T:%li F:%li R:%li S:%li\n",
+ t, f, r, s, nt, nf, nr, ns);
+ }
+ return -1;
+}