aboutsummaryrefslogtreecommitdiff
path: root/tests/testutils.c
diff options
context:
space:
mode:
authorAdam Litke <agl@us.ibm.com>2008-10-09 12:23:14 +0100
committerAndy Whitcroft <apw@shadowen.org>2008-10-14 17:36:08 +0100
commit5722a40b46908b561390028ed2c8c1dee93ad2ea (patch)
tree7ff7eb51b3519ca91fe55cfdcdde815468005a42 /tests/testutils.c
parenta371e1f1b28ab6b4f547a8fbd7835573f3e99f55 (diff)
downloadlibhugetlbfs-5722a40b46908b561390028ed2c8c1dee93ad2ea.tar.gz
utils: Make pool counter manipulation code part of the library API
The need to set and get pool counters for multiple huge page sizes is about to extend beyond just the libhugetlbfs tests. Move the counter code into hugeutils.c and make the top-level functions part of the libhugetlbfs pool and mount configuration API. This involves altering some function names and prologues to make them more consistent with the existing libhugetlbfs API. We create a new libtestutils.c for test case utilities that depend on linkage to libhugetlbfs. NOTE: This patch will cause the shmoverride test to fail compilation. This is fixed up by the next patch. [apw@shadowen.org: consolidate makefile updates in one place] Signed-off-by: Adam Litke <agl@us.ibm.com> Acked-by: Mel Gorman <mel@csn.ul.ie> Signed-off-by: Andy Whitcroft <apw@shadowen.org>
Diffstat (limited to 'tests/testutils.c')
-rw-r--r--tests/testutils.c252
1 files changed, 1 insertions, 251 deletions
diff --git a/tests/testutils.c b/tests/testutils.c
index 6534e9c..b8a1bf2 100644
--- a/tests/testutils.c
+++ b/tests/testutils.c
@@ -36,6 +36,7 @@
#include <sys/mman.h>
#include <fcntl.h>
+#include "hugetlbfs.h"
#include "hugetests.h"
#define HUGETLBFS_MAGIC 0x958458f6
@@ -45,13 +46,6 @@
int verbose_test = 1;
char *test_name;
-void check_free_huge_pages(int nr_pages_needed)
-{
- int freepages = get_pool_counter(HUGEPAGES_FREE, 0);
- if (freepages < nr_pages_needed)
- CONFIG("Must have at least %i free hugepages", nr_pages_needed);
-}
-
void check_must_be_root(void)
{
uid_t uid = getuid();
@@ -205,164 +199,6 @@ int test_addr_huge(void *p)
return (sb.f_type == HUGETLBFS_MAGIC);
}
-struct hugetlb_pool_counter_info_t hugetlb_counter_info[] = {
- [HUGEPAGES_TOTAL] = {
- .meminfo_key = "HugePages_Total:",
- .sysfs_file = "nr_hugepages",
- },
- [HUGEPAGES_FREE] = {
- .meminfo_key = "HugePages_Free:",
- .sysfs_file = "free_hugepages",
- },
- [HUGEPAGES_RSVD] = {
- .meminfo_key = "HugePages_Rsvd:",
- .sysfs_file = "resv_hugepages",
- },
- [HUGEPAGES_SURP] = {
- .meminfo_key = "HugePages_Surp:",
- .sysfs_file = "surplus_hugepages",
- },
- [HUGEPAGES_OC] = {
- .meminfo_key = NULL,
- .sysfs_file = "nr_overcommit_hugepages"
- },
-};
-
-long file_read_ulong(char *file, const char *tag)
-{
- int fd;
- char buf[MEMINFO_SZ];
- int len, readerr;
- char *p, *q;
- long val;
-
- fd = open(file, O_RDONLY);
- if (fd < 0) {
- ERROR("Couldn't open %s: %s\n", file, strerror(errno));
- return -1;
- }
-
- len = read(fd, buf, sizeof(buf));
- readerr = errno;
- close(fd);
- if (len < 0) {
- ERROR("Error reading %s: %s\n", file, strerror(errno));
- return -1;
- }
- if (len == sizeof(buf)) {
- ERROR("%s is too large\n", file);
- return -1;
- }
- buf[len] = '\0';
-
- /* Search for a tag if provided */
- if (tag) {
- p = strstr(buf, tag);
- if (!p)
- return -1; /* looks like the line we want isn't there */
- p += strlen(tag);
- } else
- p = buf;
-
- val = strtol(p, &q, 0);
- if (! isspace(*q)) {
- ERROR("Couldn't parse %s value\n", file);
- return -1;
- }
-
- return val;
-}
-
-int file_write_ulong(char *file, unsigned long val)
-{
- FILE *f;
- int ret;
-
- f = fopen(file, "w");
- if (!f) {
- ERROR("Couldn't open %s: %s\n", file, strerror(errno));
- return -1;
- }
-
- ret = fprintf(f, "%lu", val);
- fclose(f);
- return ret > 0 ? 0 : -1;
-}
-
-int select_pool_counter(unsigned int counter, unsigned long pagesize,
- char *filename, char **key)
-{
- long default_size;
- char *meminfo_key;
- char *sysfs_file;
-
- if (counter >= HUGEPAGES_MAX_COUNTERS) {
- ERROR("Invalid counter specified\n");
- return -1;
- }
-
- meminfo_key = hugetlb_counter_info[counter].meminfo_key;
- sysfs_file = hugetlb_counter_info[counter].sysfs_file;
- if (key)
- *key = NULL;
-
- /*
- * Get the meminfo page size.
- * This could be made more efficient if utility functions were shared
- * between libhugetlbfs and the test suite. For now we will just
- * read /proc/meminfo.
- */
- default_size = file_read_ulong("/proc/meminfo", "Hugepagesize:");
- default_size *= 1024; /* Convert from kB to B */
- if (default_size < 0) {
- ERROR("Cannot determine the default page size\n");
- return -1;
- }
-
- /* Convert a pagesize of 0 to the libhugetlbfs default size */
- if (pagesize == 0)
- pagesize = default_size;
-
- /* If the user is dealing in the default page size, we can use /proc */
- if (pagesize == default_size) {
- if (meminfo_key && key) {
- strcpy(filename, "/proc/meminfo");
- *key = meminfo_key;
- } else
- sprintf(filename, "/proc/sys/vm/%s", sysfs_file);
- } else /* Use the sysfs interface */
- sprintf(filename, "/sys/kernel/mm/hugepages/hugepages-%lukB/%s",
- pagesize / 1024, sysfs_file);
- return 0;
-}
-
-long get_pool_counter(unsigned int counter, unsigned long pagesize)
-{
- char file[PATH_MAX+1];
- char *key;
-
- if (select_pool_counter(counter, pagesize, file, &key))
- return -1;
-
- return file_read_ulong(file, key);
-}
-
-int set_pool_counter(unsigned int counter, unsigned long val,
- unsigned long pagesize)
-{
- char file[PATH_MAX+1];
-
- if (select_pool_counter(counter, pagesize, file, NULL))
- return -1;
-
- return file_write_ulong(file, val);
-}
-
-long read_meminfo(const char *tag)
-{
- return file_read_ulong("/proc/meminfo", tag);
-}
-
ino_t get_addr_inode(void *p)
{
char name[256];
@@ -406,89 +242,3 @@ 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 = get_pool_counter(HUGEPAGES_TOTAL, 0);
- f = get_pool_counter(HUGEPAGES_FREE, 0);
- r = get_pool_counter(HUGEPAGES_RSVD, 0);
- s = get_pool_counter(HUGEPAGES_SURP, 0);
-
-
- 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 = get_pool_counter(HUGEPAGES_TOTAL, 0);
- nf = get_pool_counter(HUGEPAGES_FREE, 0);
- nr = get_pool_counter(HUGEPAGES_RSVD, 0);
- ns = get_pool_counter(HUGEPAGES_SURP, 0);
-
- 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;
-}
-
-int using_system_hpage_size(const char *mount)
-{
- struct statfs64 sb;
- int err;
- long meminfo_size, mount_size;
-
- if (!mount)
- FAIL("using_system_hpage_size: hugetlbfs is not mounted\n");
-
- err = statfs64(mount, &sb);
- if (err)
- FAIL("statfs64: %s\n", strerror(errno));
-
- meminfo_size = file_read_ulong("/proc/meminfo", "Hugepagesize:");
- if (meminfo_size < 0)
- FAIL("using_system_hpage_size: Failed to read /proc/meminfo\n");
-
- mount_size = sb.f_bsize / 1024; /* Compare to meminfo in kB */
- if (mount_size == meminfo_size)
- return 1;
- else
- return 0;
-}