There are applications that are not hugepage-aware but use shared memory such as the postgres database. It is possible that the SHM_HUGETLB flag could be added to such an application via libhugetlbfs and overriding shmget() to add the SHM_HUGETLB to the flags. This patch enables libhugetlbfs to add the SHM_HUGETLB when a HUGETLB_SHM environment variable is set to "yes". It will work whether the application is linked to libhugetlbfs or loaded via LD_PRELOAD.
Signed-off-by: Mel Gorman <[EMAIL PROTECTED]> --- HOWTO | 32 ++++++++++++++++++ Makefile | 4 +- shm.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/Makefile | 7 ++-- tests/run_tests.sh | 4 ++ 5 files changed, 125 insertions(+), 4 deletions(-) diff -rup -X /usr/src/patchset-0.6/bin//dontdiff libhugetlbfs-gitlatest-0010-private-export/HOWTO libhugetlbfs-gitlatest-0020-shmget-override/HOWTO --- libhugetlbfs-gitlatest-0010-private-export/HOWTO 2008-07-29 19:52:52.000000000 +0100 +++ libhugetlbfs-gitlatest-0020-shmget-override/HOWTO 2008-07-30 11:01:03.000000000 +0100 @@ -275,6 +275,38 @@ By default, the hugepage heap does not s shrinking, set HUGETLB_MORECORE_SHRINK=yes. NB: We have been seeing some unexpected behavior from glibc's malloc when this is enabled. +Using hugepage shared memory +---------------------------- + +Hugepages are used for shared memory segments if the SHM_HUGETLB flag is +set when calling shmget() and the pool is large enough. For hugepage-unaware +applications, libhugetlbfs overrides shmget and adds the SHM_HUGETLB if the +environment variable HUGETLB_SHM is set to "yes". The steps to use hugepages +with applications not linked to libhugetlbfs are similar to morecore except +for step 3. + +1. Set LD_PRELOAD=libhugetlbfs.so + This tells the dynamic linker to load the libhugetlbfs shared + library, even though the program wasn't originally linked against it. + + Note: If the program is linked against libhugetlbfs, preloading the + library may lead to application crashes. You should skip this + step in that case. + +2. Set LD_LIBRARY_PATH to the directory containing libhugetlbfs.so + This is only necessary if you haven't installed libhugetlbfs.so to a + system default path. If you set LD_LIBRARY_PATH, make sure the + directory referenced contains the right version of the library + (32-bit or 64-bit) as appropriate to the binary you want to run. + +3. Set HUGETLB_SHM=yes + The shmget() call is overridden whether the application is linked or the + libhugetlbfs library is preloaded. When this environment variable is set, + the SHM_HUGETLB flag is added to the call and the size parameter is aligned + to back the shared memory segment with huge pages. In the event hugepages + cannot be used, small pages will be used instead and a warning will be + printed to explain the failure. + Using hugepage text, data, or BSS --------------------------------- diff -rup -X /usr/src/patchset-0.6/bin//dontdiff libhugetlbfs-gitlatest-0010-private-export/Makefile libhugetlbfs-gitlatest-0020-shmget-override/Makefile --- libhugetlbfs-gitlatest-0010-private-export/Makefile 2008-07-29 19:52:52.000000000 +0100 +++ libhugetlbfs-gitlatest-0020-shmget-override/Makefile 2008-07-30 09:12:08.000000000 +0100 @@ -1,7 +1,7 @@ PREFIX = /usr/local EXEDIR = /bin -LIBOBJS = hugeutils.o version.o init.o morecore.o debug.o alloc.o +LIBOBJS = hugeutils.o version.o init.o morecore.o debug.o alloc.o shm.o INSTALL_OBJ_LIBS = libhugetlbfs.so libhugetlbfs.a BIN_OBJ_DIR=obj INSTALL_BIN = hugectl hugeedit @@ -16,7 +16,7 @@ NODEPTARGETS=<version.h> <clean> INSTALL = install -LDFLAGS += --no-undefined-version -Wl,--version-script=version.lds +LDFLAGS += --no-undefined-version -Wl,--version-script=version.lds -ldl CFLAGS ?= -O2 -g CFLAGS += -Wall -fPIC CPPFLAGS += -D__LIBHUGETLBFS__ diff -rup -X /usr/src/patchset-0.6/bin//dontdiff libhugetlbfs-gitlatest-0010-private-export/shm.c libhugetlbfs-gitlatest-0020-shmget-override/shm.c --- libhugetlbfs-gitlatest-0010-private-export/shm.c 2008-07-30 09:48:17.000000000 +0100 +++ libhugetlbfs-gitlatest-0020-shmget-override/shm.c 2008-07-30 11:04:01.000000000 +0100 @@ -0,0 +1,82 @@ +/* + * libhugetlbfs - Easy use of Linux hugepages + * Copyright (C) 2005-2006 David Gibson & Adam Litke, IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#define _GNU_SOURCE +#include <dlfcn.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/types.h> +#include "libhugetlbfs_internal.h" +#include "hugetlbfs.h" + +int shmget(key_t key, size_t size, int shmflg) +{ + static int (*real_shmget)(key_t key, size_t size, int shmflg) = NULL; + char *error; + int retval; + char *hugetlbshm_env; + size_t aligned_size = size; + int hugetlbshm_enabled = 0; + + DEBUG("hugetlb_shmem: entering overridden shmget() call\n"); + + /* Get a handle to the "real" shmget system call */ + if (!real_shmget) { + real_shmget = dlsym(RTLD_NEXT, "shmget"); + if ((error = dlerror()) != NULL) { + ERROR("%s", error); + return -1; + } + } + + /* Determine if shmget() calls should be overridden */ + hugetlbshm_env = getenv("HUGETLB_SHM"); + if (hugetlbshm_env && !strcmp(hugetlbshm_env, "yes")) + hugetlbshm_enabled = 1; + + /* Align the size and set SHM_HUGETLB on request */ + if (hugetlbshm_enabled) { + aligned_size = ALIGN(size, gethugepagesize()); + if (size != aligned_size) { + DEBUG("hugetlb_shmem: size growth align %zd -> %zd\n", + size, aligned_size); + } + + DEBUG("hugetlb_shmem: Adding SHM_HUGETLB flag\n"); + shmflg |= SHM_HUGETLB; + } else { + DEBUG("hugetlb_shmem: shmget override not requested\n"); + } + + /* Call the "real" shmget. If hugepages fail, use small pages */ + retval = real_shmget(key, aligned_size, shmflg); + if (retval == -1 && hugetlbshm_enabled) { + WARNING("While overriding shmget(%zd) to add SHM_HUGETLB: %s\n", + aligned_size, strerror(errno)); + shmflg &= ~SHM_HUGETLB; + retval = real_shmget(key, size, shmflg); + DEBUG("Using small pages for shmget despite HUGETLB_SHM\n"); + } + + return retval; +} diff -rup -X /usr/src/patchset-0.6/bin//dontdiff libhugetlbfs-gitlatest-0010-private-export/tests/Makefile libhugetlbfs-gitlatest-0020-shmget-override/tests/Makefile --- libhugetlbfs-gitlatest-0010-private-export/tests/Makefile 2008-07-29 19:52:52.000000000 +0100 +++ libhugetlbfs-gitlatest-0020-shmget-override/tests/Makefile 2008-07-30 09:11:38.000000000 +0100 @@ -7,10 +7,10 @@ LIB_TESTS = gethugepagesize test_root fi truncate_reserve_wraparound truncate_sigbus_versus_oom \ map_high_truncate_2 truncate_above_4GB direct \ misaligned_offset brk_near_huge task-size-overrun stack_grow_into_huge \ - counters quota heap-overflow get_huge_pages + counters quota heap-overflow get_huge_pages shmoverride_linked LIB_TESTS_64 = straddle_4GB huge_at_4GB_normal_below \ huge_below_4GB_normal_above -NOLIB_TESTS = malloc malloc_manysmall dummy heapshrink +NOLIB_TESTS = malloc malloc_manysmall dummy heapshrink shmoverride_unlinked LDSCRIPT_TESTS = zero_filesize_segment HUGELINK_TESTS = linkhuge linkhuge_nofd linkshare HUGELINK_RW_TESTS = linkhuge_rw @@ -67,6 +67,9 @@ endif all: $(ALLTESTS) $(ALLHELPERS) $(ALLHELPERLIBS) +shmoverride_linked.c: shmoverride_unlinked.c + ln -s shmoverride_unlinked.c shmoverride_linked.c + obj32/%.o: %.c @$(VECHO) CC32 $@ @mkdir -p obj32 diff -rup -X /usr/src/patchset-0.6/bin//dontdiff libhugetlbfs-gitlatest-0010-private-export/tests/run_tests.sh libhugetlbfs-gitlatest-0020-shmget-override/tests/run_tests.sh --- libhugetlbfs-gitlatest-0010-private-export/tests/run_tests.sh 2008-07-29 19:52:52.000000000 +0100 +++ libhugetlbfs-gitlatest-0020-shmget-override/tests/run_tests.sh 2008-07-30 09:11:38.000000000 +0100 @@ -275,6 +275,10 @@ check_linkhuge_tests # Test direct allocation API run_test get_huge_pages +# Test overriding of shmget() + run_test shmoverride_linked + run_test LD_PRELOAD=libhugetlbfs.so shmoverride_unlinked + # Test hugetlbfs filesystem quota accounting run_test quota ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Libhugetlbfs-devel mailing list Libhugetlbfs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel