This testcase failed on some setups (ppc64):
  Starting testcase "./obj64/mremap-expand-slice-collision", pid 10840
  do_readback(0x20001000000, 0x1000000, "huge above")
  do_readback(0x1ffffff0000, 0x10000, "normal below")
  Attempting to remap...disallowed
  do_readback(0x20001000000, 0x10000, "normal above")
  FAIL    mmap(huge below): Device or resource busy

Problem is that SLICE_BOUNDARY was hardcoded to 0x20000000000.
When testcase tries to mmap huge page below this address (0x1ffff000000),
it fails with EBUSY because there is already heap (0x1????000000)
at this slice which may not be using huge pages.

See also kernel commit. which introduced slices on powerpc:
  commit d0f13e3c20b6fb73ccb467bdca97fa7cf5a574cd
  Author: Benjamin Herrenschmidt <b...@kernel.crashing.org>
  Date:   Tue May 8 16:27:27 2007 +1000
      [POWERPC] Introduce address space "slices"

This patch removes hardcoded SLICE_BOUNDARY address and introduces
function to find two free neighbour slices at runtime. Slice boundary
is then set to address between these slices.

With patch:
  Starting testcase "./obj64/mremap-expand-slice-collision", pid 12768
  can't use slice_boundary: 0x20000000000
  using slice_boundary: 0x30000000000
  do_readback(0x30001000000, 0x1000000, "huge above")
  do_readback(0x2ffffff0000, 0x10000, "normal below")
  Attempting to remap...disallowed
  do_readback(0x30001000000, 0x10000, "normal above")
  do_readback(0x2ffff000000, 0x1000000, "huge below")
  Attempting to remap...disallowed
  PASS

Signed-off-by: Jan Stancek <jstan...@redhat.com>
---
 tests/mremap-expand-slice-collision.c |   64 +++++++++++++++++++++++++++++----
 1 files changed, 57 insertions(+), 7 deletions(-)

diff --git a/tests/mremap-expand-slice-collision.c 
b/tests/mremap-expand-slice-collision.c
index 0cbff15..99b153a 100644
--- a/tests/mremap-expand-slice-collision.c
+++ b/tests/mremap-expand-slice-collision.c
@@ -30,13 +30,62 @@
 
 #define RANDOM_CONSTANT        0x1234ABCD
 
+unsigned long slice_boundary;
+long hpage_size, page_size;
+
+void init_slice_boundary(int fd)
+{
+       unsigned long slice_size;
+       void *p1, *p2, *heap;
+       int slices_ok, i, rc;
 #ifdef __LP64__
-#define SLICE_BOUNDARY 0x20000000000
+       /* powerpc: 1TB slices starting at 1 TB */
+       slice_boundary = 0x10000000000;
+       slice_size = 0x10000000000;
 #else
-#define SLICE_BOUNDARY 0xe0000000
+       /* powerpc: 256MB slices up to 4GB */
+       slice_boundary = 0x00000000;
+       slice_size = 0x10000000;
 #endif
 
-long hpage_size, page_size;
+       /* dummy malloc so we know where is heap */
+       heap = malloc(1);
+       free(heap);
+
+       /* find 2 neighbour slices, which are both free,
+        * 16 is the maximum number of slices (low/high) */
+       for (i = 0; i < 16-1; i++) {
+               slices_ok = 0;
+               p1 = mmap((void *)slice_boundary, hpage_size,
+                       PROT_READ, MAP_SHARED | MAP_FIXED, fd, 0);
+               p2 = mmap((void *)(slice_boundary+slice_size), hpage_size,
+                       PROT_READ, MAP_SHARED | MAP_FIXED, fd, 0);
+
+               if (p1 != MAP_FAILED) {
+                       slices_ok++;
+                       rc = munmap(p1, hpage_size);
+                       if (rc != 0)
+                               FAIL("munmap(p1): %s", strerror(errno));
+               }
+               if (p2 != MAP_FAILED) {
+                       slices_ok++;
+                       rc = munmap(p2, hpage_size);
+                       if (rc != 0)
+                               FAIL("munmap(p2): %s", strerror(errno));
+               }
+
+               slice_boundary += slice_size;
+               if (slices_ok == 2)
+                       break;
+               else
+                       verbose_printf("can't use slice_boundary: 0x%lx\n",
+                               slice_boundary);
+       }
+
+       if (slices_ok != 2)
+               FAIL("couldn't find 2 free neighbour slices");
+       verbose_printf("using slice_boundary: 0x%lx\n", slice_boundary);
+}
 
 void do_readback(void *p, size_t size, const char *stage)
 {
@@ -102,9 +151,10 @@ int main(int argc, char *argv[])
        fd = hugetlbfs_unlinked_fd();
        if (fd < 0)
                FAIL("hugetlbfs_unlinked_fd()");
+       init_slice_boundary(fd);
 
        /* First, hugepages above, normal below */
-       p = mmap((void *)(SLICE_BOUNDARY + hpage_size), hpage_size,
+       p = mmap((void *)(slice_boundary + hpage_size), hpage_size,
                 PROT_READ | PROT_WRITE,
                 MAP_SHARED | MAP_FIXED, fd, 0);
        if (p == MAP_FAILED)
@@ -112,7 +162,7 @@ int main(int argc, char *argv[])
 
        do_readback(p, hpage_size, "huge above");
 
-       q = mmap((void *)(SLICE_BOUNDARY - page_size), page_size,
+       q = mmap((void *)(slice_boundary - page_size), page_size,
                 PROT_READ | PROT_WRITE,
                 MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
        if (q == MAP_FAILED)
@@ -144,7 +194,7 @@ int main(int argc, char *argv[])
                FAIL("munmap(huge above)");
 
        /* Next, normal pages above, huge below */
-       p = mmap((void *)(SLICE_BOUNDARY + hpage_size), page_size,
+       p = mmap((void *)(slice_boundary + hpage_size), page_size,
                 PROT_READ|PROT_WRITE,
                 MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
        if (p == MAP_FAILED)
@@ -152,7 +202,7 @@ int main(int argc, char *argv[])
 
        do_readback(p, page_size, "normal above");
 
-       q = mmap((void *)(SLICE_BOUNDARY - hpage_size),
+       q = mmap((void *)(slice_boundary - hpage_size),
                 hpage_size, PROT_READ | PROT_WRITE,
                 MAP_SHARED | MAP_FIXED, fd, 0);
        if (q == MAP_FAILED)
-- 
1.7.1


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Libhugetlbfs-devel mailing list
Libhugetlbfs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel

Reply via email to