aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric B Munson <emunson@mgebm.net>2010-11-23 08:52:13 -0700
committerEric B Munson <emunson@mgebm.net>2010-11-29 13:41:17 -0700
commit8007365d1bd2b84f2e3f665460add279900b005e (patch)
treeb7271ee68a525245af4c204d83e8f54973cefc71
parentda9280b07cd1c3bc1249129617dbad0867d6a334 (diff)
downloadlibhugetlbfs-8007365d1bd2b84f2e3f665460add279900b005e.tar.gz
Read /proc/self/smaps to test page size of mapping
When MAP_HUGETLB is used, the standard test for a mapping being backed by huge pages fails because the mapping will not be on hugetlbfs. Instead of testing the filesystem backing the mapping, this patch adds a check of reported MMU page size from /proc/self/smaps. get_mapping_page_size returns the page size that is being used for the specified mapping in bytes. Signed-off-by: Eric B Munson <emunson@mgebm.net> Acked-by: Mel Gorman <mel@csn.ul.ie>
-rw-r--r--tests/hugetests.h1
-rw-r--r--tests/testutils.c54
2 files changed, 55 insertions, 0 deletions
diff --git a/tests/hugetests.h b/tests/hugetests.h
index 85f5b4f..a5a54d6 100644
--- a/tests/hugetests.h
+++ b/tests/hugetests.h
@@ -45,6 +45,7 @@ void check_must_be_root(void);
void check_hugetlb_shm_group(void);
void test_init(int argc, char *argv[]);
int test_addr_huge(void *p);
+unsigned long long get_mapping_page_size(void *p);
long read_meminfo(const char *tag);
ino_t get_addr_inode(void *p);
diff --git a/tests/testutils.c b/tests/testutils.c
index b8a1bf2..68d8e62 100644
--- a/tests/testutils.c
+++ b/tests/testutils.c
@@ -162,6 +162,60 @@ static int read_maps(unsigned long addr, char *buf)
return 0;
}
+/*
+ * With the inclusion of MAP_HUGETLB it is now possible to have huge pages
+ * without using hugetlbfs, so not all huge page regions will show with the
+ * test that reads /proc/self/maps. Instead we ask /proc/self/smaps for
+ * the KernelPageSize. On success we return the page size (in bytes) for the
+ * mapping that contains addr, on failure we return 0
+ */
+unsigned long long get_mapping_page_size(void *p)
+{
+ FILE *f;
+ char line[MAPS_BUF_SZ];
+ char *tmp;
+ unsigned long addr = (unsigned long)p;
+
+ f = fopen("/proc/self/smaps", "r");
+ if (!f) {
+ ERROR("Unable to open /proc/self/smaps\n");
+ return 0;
+ }
+
+ while ((tmp = fgets(line, MAPS_BUF_SZ, f))) {
+ unsigned long start, end, dummy;
+ char map_name[256];
+ char buf[64];
+ int ret;
+
+ ret = sscanf(line, "%lx-%lx %s %lx %s %ld %s", &start, &end,
+ buf, &dummy, buf, &dummy, map_name);
+ if (ret < 7 || start > addr || end <= addr)
+ continue;
+
+ while ((tmp = fgets(line, MAPS_BUF_SZ, f))) {
+ unsigned long long page_size;
+
+ ret = sscanf(line, "KernelPageSize: %lld kB",
+ &page_size);
+ if (ret == 0 )
+ continue;
+ if (ret < 1 || page_size <= 0) {
+ ERROR("Cannot parse /proc/self/smaps\n");
+ page_size = 0;
+ }
+
+ fclose(f);
+ /* page_size is reported in kB, we return B */
+ return page_size * 1024;
+ }
+ }
+
+ /* We couldn't find an entry for this addr in smaps */
+ fclose(f);
+ return 0;
+}
+
/* We define this function standalone, rather than in terms of
* hugetlbfs_test_path() so that we can use it without -lhugetlbfs for
* testing PRELOAD */