aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Stancek <jstancek@redhat.com>2012-09-12 12:02:46 +0200
committerEric B Munson <emunson@mgebm.net>2012-11-06 08:17:53 -0500
commitcd0eeae19135263d33b7d142143a7d7c48e6d1c2 (patch)
treecef80b5205ce184f06b5b2cd541470b34313c0b3
parent8ee2462f3f6eea72067641a197214610443576b8 (diff)
downloadlibhugetlbfs-cd0eeae19135263d33b7d142143a7d7c48e6d1c2.tar.gz
fail test only when MAP_FIXED fails on free slices
huge_at_4GB_normal_below, huge_below_4GB_normal_above, straddle_4GB are tests to test corner cases on powerpc. powerpc manages memory using slices: low (0-4G) and high (4G-). These tests are using MAP_FIXED and try to mmap hugepage at various locations. Issue is that kernel or ld.so can be already using region that these tests want to use. At the moment it ends with failure: # ./obj64/straddle_4GB Starting testcase "./obj64/straddle_4GB", pid 25949 Mapping without MAP_FIXED at ff000000...got 0xefffe000000 instead, never mind Mapping with MAP_FIXED at ff000000 FAIL mmap() FIXED failed: Device or resource busy Looking at mappings prior to failed mmap, there are already some libraries mapped to first high slice (0). 10010000-10020000 r--p 00000000 fd:01 2893006 /root/libhugetlbfs/tests/obj64/straddle_4GB 10020000-10030000 rw-p 00010000 fd:01 2893006 /root/libhugetlbfs/tests/obj64/straddle_4GB 8015160000-8015190000 r-xp 00000000 fd:01 1857222 /usr/lib64/ld-2.15.so 8015190000-80151a0000 r--p 00020000 fd:01 1857222 /usr/lib64/ld-2.15.so 80151a0000-80151b0000 rw-p 00030000 fd:01 1857222 /usr/lib64/ld-2.15.so 80151d0000-8015390000 r-xp 00000000 fd:01 1857223 /usr/lib64/libc-2.15.so 8015390000-80153a0000 r--p 001b0000 fd:01 1857223 /usr/lib64/libc-2.15.so 80153a0000-80153c0000 rw-p 001c0000 fd:01 1857223 /usr/lib64/libc-2.15.so 80153c0000-80153e0000 r-xp 00000000 fd:01 1835789 /usr/lib64/libpthread-2.15.so 80153e0000-80153f0000 r--p 00010000 fd:01 1835789 /usr/lib64/libpthread-2.15.so 80153f0000-8015400000 rw-p 00020000 fd:01 1835789 /usr/lib64/libpthread-2.15.so 8015400000-8015410000 r-xp 00000000 fd:01 1842374 /usr/lib64/libdl-2.15.so 8015410000-8015420000 r--p 00000000 fd:01 1842374 /usr/lib64/libdl-2.15.so 8015420000-8015430000 rw-p 00010000 fd:01 1842374 /usr/lib64/libdl-2.15.so 10022e00000-10022e30000 rw-p 00000000 00:00 0 [heap] fff8e650000-fff8e670000 r-xp 00000000 fd:01 1837902 /usr/lib64/libhugetlbfs.so fff8e670000-fff8e680000 r--p 00010000 fd:01 1837902 /usr/lib64/libhugetlbfs.so fff8e680000-fff8e690000 rw-p 00020000 fd:01 1837902 /usr/lib64/libhugetlbfs.so fff8e690000-fff8e6a0000 r-xp 00000000 fd:01 1842940 /usr/lib64/libhugetlbfs_privutils.so fff8e6a0000-fff8e6b0000 r--p 00000000 fd:01 1842940 /usr/lib64/libhugetlbfs_privutils.so fff8e6b0000-fff8e6c0000 rw-p 00010000 fd:01 1842940 /usr/lib64/libhugetlbfs_privutils.so fff8e6c0000-fff8e6d0000 rw-p 00000000 00:00 0 fff8e6d0000-fff8e6f0000 r-xp 00000000 00:00 0 [vdso] fffc7110000-fffc7140000 rw-p 00000000 00:00 0 [stack] This patch checks that slices used by tests are actually free (not mapped). If they are not free and mmap fails, test will PASS as inconclusive. Signed-off-by: Jan Stancek <jstancek@redhat.com> Signed-off-by: Eric B Munson <emunson@mgebm.net>
-rw-r--r--tests/huge_at_4GB_normal_below.c25
-rw-r--r--tests/huge_below_4GB_normal_above.c37
-rw-r--r--tests/hugetests.h1
-rw-r--r--tests/straddle_4GB.c13
-rw-r--r--tests/testutils.c43
5 files changed, 107 insertions, 12 deletions
diff --git a/tests/huge_at_4GB_normal_below.c b/tests/huge_at_4GB_normal_below.c
index 4134d03..0f5d8b7 100644
--- a/tests/huge_at_4GB_normal_below.c
+++ b/tests/huge_at_4GB_normal_below.c
@@ -66,8 +66,17 @@ int main(int argc, char *argv[])
p = mmap((void *)FOURGB, hpage_size, PROT_READ|PROT_WRITE,
MAP_SHARED | MAP_FIXED, fd, 0);
- if (p == MAP_FAILED)
- FAIL("mmap() huge: %s", strerror(errno));
+ if (p == MAP_FAILED) {
+ /* slice 0 (high) spans from 4G-1T */
+ unsigned long below_start = FOURGB;
+ unsigned long above_end = 1024L*1024*1024*1024;
+ if (range_is_mapped(below_start, above_end) == 1) {
+ verbose_printf("region 4G-1T is not free\n");
+ verbose_printf("mmap() failed: %s\n", strerror(errno));
+ PASS_INCONCLUSIVE();
+ } else
+ FAIL("mmap() huge: %s\n", strerror(errno));
+ }
if (p != (void *)FOURGB)
FAIL("Wrong address with MAP_FIXED huge");
@@ -83,8 +92,16 @@ int main(int argc, char *argv[])
lowaddr = FOURGB - page_size;
q = mmap((void *)lowaddr, page_size, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_FIXED|MAP_ANONYMOUS, 0, 0);
- if (q == MAP_FAILED)
- FAIL("mmap() normal: %s", strerror(errno));
+ if (p == MAP_FAILED) {
+ unsigned long below_start = FOURGB - page_size;
+ unsigned long above_end = FOURGB;
+ if (range_is_mapped(below_start, above_end) == 1) {
+ verbose_printf("region (4G-page)-4G is not free\n");
+ verbose_printf("mmap() failed: %s\n", strerror(errno));
+ PASS_INCONCLUSIVE();
+ } else
+ FAIL("mmap() normal: %s\n", strerror(errno));
+ }
if (q != (void *)lowaddr)
FAIL("Wrong address with MAP_FIXED normal");
diff --git a/tests/huge_below_4GB_normal_above.c b/tests/huge_below_4GB_normal_above.c
index 7747894..b78bee8 100644
--- a/tests/huge_below_4GB_normal_above.c
+++ b/tests/huge_below_4GB_normal_above.c
@@ -72,8 +72,17 @@ int main(int argc, char *argv[])
verbose_printf("Mapping hugepage at at %lx...", lowaddr);
p = mmap((void *)lowaddr, hpage_size, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_FIXED, fd, 0);
- if (p == MAP_FAILED)
- FAIL("mmap() huge: %s", strerror(errno));
+ if (p == MAP_FAILED) {
+ /* This is last low slice - 256M just before 4G */
+ unsigned long below_start = FOURGB - 256L*1024*1024;
+ unsigned long above_end = FOURGB;
+ if (range_is_mapped(below_start, above_end) == 1) {
+ verbose_printf("region (4G-256M)-4G is not free\n");
+ verbose_printf("mmap() failed: %s\n", strerror(errno));
+ PASS_INCONCLUSIVE();
+ } else
+ FAIL("mmap() huge: %s\n", strerror(errno));
+ }
if (p != (void *)lowaddr)
FAIL("Wrong address with MAP_FIXED huge");
verbose_printf("done\n");
@@ -89,8 +98,16 @@ int main(int argc, char *argv[])
verbose_printf("Mapping normal page at %lx...", highaddr);
q = mmap((void *)highaddr, page_size, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_FIXED|MAP_ANONYMOUS, 0, 0);
- if (q == MAP_FAILED)
- FAIL("mmap() normal 1: %s", strerror(errno));
+ if (p == MAP_FAILED) {
+ unsigned long below_start = FOURGB;
+ unsigned long above_end = FOURGB + page_size;
+ if (range_is_mapped(below_start, above_end) == 1) {
+ verbose_printf("region 4G-(4G+page) is not free\n");
+ verbose_printf("mmap() failed: %s\n", strerror(errno));
+ PASS_INCONCLUSIVE();
+ } else
+ FAIL("mmap() normal 1: %s\n", strerror(errno));
+ }
if (q != (void *)highaddr)
FAIL("Wrong address with MAP_FIXED normal 2");
verbose_printf("done\n");
@@ -105,8 +122,16 @@ int main(int argc, char *argv[])
verbose_printf("Mapping normal page at %lx...", highaddr);
q = mmap((void *)highaddr, page_size, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_FIXED|MAP_ANONYMOUS, 0, 0);
- if (q == MAP_FAILED)
- FAIL("mmap() normal 2: %s", strerror(errno));
+ if (p == MAP_FAILED) {
+ unsigned long below_start = highaddr;
+ unsigned long above_end = highaddr + page_size;
+ if (range_is_mapped(below_start, above_end) == 1) {
+ verbose_printf("region haddr-(haddr+page) not free\n");
+ verbose_printf("mmap() failed: %s\n", strerror(errno));
+ PASS_INCONCLUSIVE();
+ } else
+ FAIL("mmap() normal 2: %s\n", strerror(errno));
+ }
if (q != (void *)highaddr)
FAIL("Wrong address with MAP_FIXED normal 2");
verbose_printf("done\n");
diff --git a/tests/hugetests.h b/tests/hugetests.h
index cdcb41b..67af49f 100644
--- a/tests/hugetests.h
+++ b/tests/hugetests.h
@@ -49,6 +49,7 @@ unsigned long long get_mapping_page_size(void *p);
long read_meminfo(const char *tag);
ino_t get_addr_inode(void *p);
int consume_heap(long max);
+int range_is_mapped(unsigned long low, unsigned long high);
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define PALIGN(p, a) ((void *)ALIGN((unsigned long)(p), (a)))
diff --git a/tests/straddle_4GB.c b/tests/straddle_4GB.c
index da59fbf..e068a72 100644
--- a/tests/straddle_4GB.c
+++ b/tests/straddle_4GB.c
@@ -80,8 +80,17 @@ int main(int argc, char *argv[])
verbose_printf("Mapping with MAP_FIXED at %lx...", straddle_addr);
p = mmap((void *)straddle_addr, 2*hpage_size, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_FIXED, fd, 0);
- if (p == MAP_FAILED)
- FAIL("mmap() FIXED: %s", strerror(errno));
+ if (p == MAP_FAILED) {
+ /* this area crosses last low slice and first high slice */
+ unsigned long below_start = FOURGB - 256L*1024*1024;
+ unsigned long above_end = 1024L*1024*1024*1024;
+ if (range_is_mapped(below_start, above_end) == 1) {
+ verbose_printf("region (4G-256M)-1T is not free\n");
+ verbose_printf("mmap() failed: %s\n", strerror(errno));
+ PASS_INCONCLUSIVE();
+ } else
+ FAIL("mmap() FIXED failed: %s\n", strerror(errno));
+ }
if (p != (void *)straddle_addr) {
verbose_printf("got %p instead\n", p);
FAIL("Wrong address with MAP_FIXED");
diff --git a/tests/testutils.c b/tests/testutils.c
index 2dc5d5d..933562f 100644
--- a/tests/testutils.c
+++ b/tests/testutils.c
@@ -162,6 +162,49 @@ static int read_maps(unsigned long addr, char *buf)
return 0;
}
+int range_is_mapped(unsigned long low, unsigned long high)
+{
+ FILE *f;
+ char line[MAPS_BUF_SZ];
+ char *tmp;
+
+ f = fopen("/proc/self/maps", "r");
+ if (!f) {
+ ERROR("Failed to open /proc/self/maps: %s\n", strerror(errno));
+ return -1;
+ }
+
+ while (1) {
+ unsigned long start, end;
+ int ret;
+
+ tmp = fgets(line, MAPS_BUF_SZ, f);
+ if (!tmp)
+ break;
+
+ ret = sscanf(line, "%lx-%lx", &start, &end);
+ if (ret != 2) {
+ ERROR("Couldn't parse /proc/self/maps line: %s\n",
+ line);
+ fclose(f);
+ return -1;
+ }
+
+ if ((start >= low) && (start < high)) {
+ fclose(f);
+ return 1;
+ }
+ if ((end >= low) && (end < high)) {
+ fclose(f);
+ return 1;
+ }
+
+ }
+
+ fclose(f);
+ return 0;
+}
+
/* malloc memory one byte at a time until:
* - max limit is reached
* - malloc-ed memory is no longer on heap