diff options
author | Adam Litke <agl@us.ibm.com> | 2008-07-17 19:14:58 +0000 |
---|---|---|
committer | Nishanth Aravamudan <nacc@us.ibm.com> | 2008-07-21 18:46:23 -0700 |
commit | 0f751044c997521b8955f50c1022f725a0cda6a1 (patch) | |
tree | a7815bfa9540470fadb6b9b9479263a67ad06cd7 /tests/testutils.c | |
parent | 170ee4e04f4d121e403d39f4ac5aef7a48189a09 (diff) | |
download | libhugetlbfs-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.c | 62 |
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; +} |