This testcase may still fail on x86_64 with SIGBUS, for example
with kernels 2.6.32-307.el6.x86_64 or 3.5.0-0.23.el7.x86_64.

At this moment it appears to be kernel bug at mremap():
Bug 855864 - SIGBUS after mremap() near hugepage
https://bugzilla.redhat.com/show_bug.cgi?id=855864

Regards,
Jan

----- Original Message -----
> From: "Jan Stancek" <jstan...@redhat.com>
> To: libhugetlbfs-devel@lists.sourceforge.net
> Cc: an...@redhat.com
> Sent: Monday, 10 September, 2012 4:33:15 PM
> Subject: [Libhugetlbfs-devel] [PATCH] set slice boundary at runtime
> 
> 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
> 

------------------------------------------------------------------------------
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