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
[email protected]
https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel