Adjust the kernel's idea of the end of the data segment (the 'brk' value) to match user space when we remap the data segment onto hugepages.
Signed-off-by: Andrew Hastings <[EMAIL PROTECTED]> on behalf of Cray Inc. --- While I was running some of the libhugetlbfs linker tests under strace, I noticed brk() was failing. Poking around in /proc/self/maps I discovered why. Breaking brk() (no pun intended) is bad because (1) it causes malloc to make two system calls every time it needs to grow the heap (a failing sbrk and then an mmap) and (2) the process's address space ends up with lots of little VMAs. Tested both 32- and 64-bit binaries under SUSE 10 on x86-64. -Andrew Hastings Cray Inc. diff -ruNp libhugetlbfs-1.2/elflink.c libhugetlbfs-1.2-modified/elflink.c --- libhugetlbfs-1.2/elflink.c 2007-09-10 08:27:44.000000000 -0500 +++ libhugetlbfs-1.2-modified/elflink.c 2007-09-18 12:17:04.932081000 -0500 @@ -923,6 +923,23 @@ static void remap_segments(struct seg_in long hpage_size = gethugepagesize(); int i; void *p; + void *oldbrk, *newbrk; + + /* + * Adjust the brk value to the end of the data segment. + */ + newbrk = oldbrk = sbrk(0); + DEBUG("Current brk=%p\n", oldbrk); + for (i = 0; i < num; i++) { + unsigned long mapsize = ALIGN(seg[i].memsz, hpage_size); + + DEBUG("%p - %p\n", seg[i].vaddr, seg[i].vaddr + mapsize); + if (seg[i].vaddr <= oldbrk && oldbrk < seg[i].vaddr + mapsize) + newbrk = seg[i].vaddr + mapsize; + } + DEBUG("New brk=%p\n", newbrk); + if (newbrk != oldbrk) + brk(newbrk); /* * XXX: The bogus call to mmap below forces ld.so to resolve the diff -ruNp libhugetlbfs-1.2/tests/Makefile libhugetlbfs-1.2-modified/tests/Makefile --- libhugetlbfs-1.2/tests/Makefile 2007-09-10 08:27:44.000000000 -0500 +++ libhugetlbfs-1.2-modified/tests/Makefile 2007-09-18 12:25:43.005889000 -0500 @@ -11,7 +11,7 @@ LIB_TESTS_64 = straddle_4GB huge_at_4GB_ huge_below_4GB_normal_above NOLIB_TESTS = malloc malloc_manysmall dummy LDSCRIPT_TESTS = zero_filesize_segment -HUGELINK_TESTS = linkhuge linkhuge_nofd linkshare +HUGELINK_TESTS = linkhuge linkhuge_nofd linkshare brk-align STRESS_TESTS = mmap-gettest mmap-cow shm-gettest shm-getraw shm-fork HELPERS = get_hugetlbfs_path BADTOOLCHAIN = bad-toolchain.sh diff -ruNp libhugetlbfs-1.2/tests/brk-align.c libhugetlbfs-1.2-modified/tests/brk-align.c --- libhugetlbfs-1.2/tests/brk-align.c 1969-12-31 18:00:00.000000000 -0600 +++ libhugetlbfs-1.2-modified/tests/brk-align.c 2007-09-18 12:25:42.983191000 -0500 @@ -0,0 +1,36 @@ +/* + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file "LGPL-2.1" in the main directory of this + * archive for more details. + * + * Copyright 2007 Cray Inc. All Rights Reserved. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include "hugetests.h" + +/* + * This test verifies that libhugetlbfs adjusts the brk value to the + * end of the data segment when it remaps the data segment onto hugepages. + */ + +static int data = 1; + +int main(int argc, char **argv) +{ + int pagesize; + + test_init(argc, argv); + + if (test_addr_huge(&data) != 1) + CONFIG("Data segment not on hugepage"); + + pagesize = getpagesize(); + if (sbrk(pagesize) == (void *)-1) + FAIL("sbrk(%d) failed", pagesize); + + PASS(); +} diff -ruNp libhugetlbfs-1.2/tests/run_tests.sh libhugetlbfs-1.2-modified/tests/run_tests.sh --- libhugetlbfs-1.2/tests/run_tests.sh 2007-09-10 08:27:44.000000000 -0500 +++ libhugetlbfs-1.2-modified/tests/run_tests.sh 2007-09-18 12:04:56.933928000 -0500 @@ -169,6 +169,7 @@ functional_tests () { preload_test HUGETLB_MORECORE=yes malloc_manysmall elflink_test HUGETLB_VERBOSE=0 linkhuge_nofd # Lib error msgs expected elflink_test linkhuge + run_test xBDT.brk-align # Sharing tests elfshare_test linkshare ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ Libhugetlbfs-devel mailing list Libhugetlbfs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel