aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Hastings <abh@cray.com>2011-02-02 11:57:22 -0600
committerEric B Munson <emunson@mgebm.net>2011-02-23 14:29:07 -0500
commit8b55918e470927522a2e30e938c791bf4bbfa8df (patch)
tree26adf20582db4ea27021389544780a02b6d99538
parent319122ba1f31cf5804901ec078dab5491f9202be (diff)
downloadlibhugetlbfs-8b55918e470927522a2e30e938c791bf4bbfa8df.tar.gz
Allow actions to be restricted to certain programs
By default, libhugetlbfs will act on any program that it is loaded with, either via LD_PRELOAD or by explicitly linking with -lhugetlbfs. There are situations in which it is desirable to restrict libhugetlbfs' actions to specific programs. For example, some ISV applications are wrapped in a series of scripts that invoke bash, python, and/or perl. It is more convenient to set the environment variables related to libhugetlbfs outside of the wrapper scripts, yet this has the unintended and undesirable consequence of causing the script interpreters to use and consume hugepages. Often there is no obvious benefit to causing the script interpreters to use hugepages, and there is a clear disadvantage: fewer hugepages are available to the actual application. To address this scenario, add a HUGETLB_RESTRICT_EXE environment variable. If this variable is set, libhugetlbfs will restrict its actions to only those programs named in HUGETLB_RESTRICT_EXE. (If not set, libhugetlbfs will attempt to apply the requested actions to all programs.) For example, HUGETLB_RESTRICT_EXE="hpcc:long_hpcc" will restrict libhugetlbfs' actions to programs named /home/fred/hpcc and /bench/long_hpcc but will not affect /usr/bin/hpcc_no. Based on a patch originally authored by Dean Luick <luick@cray.com>. Signed-off-by: Andrew Hastings <abh@cray.com> on behalf of Cray Inc. Signed-off-by: Eric B Munson <emunson@mgebm.net>
-rw-r--r--HOWTO31
-rw-r--r--hugeutils.c69
-rw-r--r--man/libhugetlbfs.731
-rw-r--r--tests/malloc.c16
-rwxr-xr-xtests/run_tests.py4
5 files changed, 146 insertions, 5 deletions
diff --git a/HOWTO b/HOWTO
index 4930a2e..3c1f124 100644
--- a/HOWTO
+++ b/HOWTO
@@ -2,7 +2,7 @@ libhugetlbfs HOWTO
==================
Author: David Gibson <dwg@au1.ibm.com>, Adam Litke <agl@us.ibm.com>, and others
-Last updated: Tuesday, Oct 28th, 2008
+Last updated: February 1st, 2011
Introduction
============
@@ -554,6 +554,35 @@ libhugetlbfs:
Override the system default huge page size for all uses
except hugetlb-backed shared memory
+ HUGETLB_RESTRICT_EXE
+ By default, libhugetlbfs will act on any program that it
+ is loaded with, either via LD_PRELOAD or by explicitly
+ linking with -lhugetlbfs.
+
+ There are situations in which it is desirable to restrict
+ libhugetlbfs' actions to specific programs. For example,
+ some ISV applications are wrapped in a series of scripts
+ that invoke bash, python, and/or perl. It is more
+ convenient to set the environment variables related
+ to libhugetlbfs before invoking the wrapper scripts,
+ yet this has the unintended and undesirable consequence
+ of causing the script interpreters to use and consume
+ hugepages. There is no obvious benefit to causing the
+ script interpreters to use hugepages, and there is a
+ clear disadvantage: fewer hugepages are available to
+ the actual application.
+
+ To address this scenario, set HUGETLB_RESTRICT_EXE to a
+ colon-separated list of programs to which the other
+ libhugetlbfs environment variables should apply. (If
+ not set, libhugetlbfs will attempt to apply the requested
+ actions to all programs.) For example,
+
+ HUGETLB_RESTRICT_EXE="hpcc:long_hpcc"
+
+ will restrict libhugetlbfs' actions to programs named
+ /home/fred/hpcc and /bench/long_hpcc but not /usr/hpcc_no.
+
HUGETLB_ELFMAP
Control or disable segment remapping (see above)
diff --git a/hugeutils.c b/hugeutils.c
index 0a8d1b9..70e3d22 100644
--- a/hugeutils.c
+++ b/hugeutils.c
@@ -233,6 +233,52 @@ int file_write_ulong(char *file, unsigned long val)
return ret > 0 ? 0 : -1;
}
+
+/*
+ * Return the name of this executable, using buf as temporary space.
+ */
+#define MAX_EXE 4096
+static char *get_exe_name(char *buf, int size)
+{
+ char *p;
+ int fd;
+ ssize_t nread;
+
+ buf[0] = 0;
+ fd = open("/proc/self/cmdline", O_RDONLY);
+ if (fd < 0) {
+ WARNING("Unable to open cmdline, no exe name\n");
+ return buf;
+ }
+ nread = read(fd, buf, size-1);
+ close(fd);
+
+ if (nread < 0) {
+ WARNING("Error %d reading cmdline, no exe name\n", errno);
+ return buf;
+ }
+ if (nread == 0) {
+ WARNING("Read zero bytes from cmdline, no exe name\n");
+ return buf;
+ }
+
+ buf[nread] = 0; /* make sure we're null terminated */
+ /*
+ * Take advantage of cmdline being a series of null-terminated
+ * strings. The first string is the path to the executable in
+ * the form:
+ *
+ * /path/to/exe
+ *
+ * The exe name starts one character after the last '/'.
+ */
+ p = strrchr(buf, '/');
+ if (!p)
+ return buf;
+ return p + 1; /* skip over "/" */
+}
+
+
/*
* Reads the contents of hugetlb environment variables and save their
* values for later use.
@@ -253,6 +299,29 @@ void hugetlbfs_setup_env()
__hugetlbfs_verbose = VERBOSE_DEBUG;
}
+ env = getenv("HUGETLB_RESTRICT_EXE");
+ if (env) {
+ char *p, *tok, *exe, buf[MAX_EXE+1], restrict[MAX_EXE];
+ int found = 0;
+
+ exe = get_exe_name(buf, sizeof buf);
+ DEBUG("Found HUGETLB_RESTRICT_EXE, this exe is \"%s\"\n", exe);
+ strncpy(restrict, env, sizeof restrict);
+ restrict[sizeof(restrict)-1] = 0;
+ for (p = restrict; (tok = strtok(p, ":")) != NULL; p = NULL) {
+ DEBUG(" ...check exe match for \"%s\"\n", tok);
+ if (strcmp(tok, exe) == 0) {
+ found = 1;
+ DEBUG("exe match - libhugetlbfs is active for this exe\n");
+ break;
+ }
+ }
+ if (!found) {
+ DEBUG("No exe match - libhugetlbfs is inactive for this exe\n");
+ return;
+ }
+ }
+
env = getenv("HUGETLB_NO_PREFAULT");
if (env)
__hugetlbfs_prefault = false;
diff --git a/man/libhugetlbfs.7 b/man/libhugetlbfs.7
index 2161858..14bcf04 100644
--- a/man/libhugetlbfs.7
+++ b/man/libhugetlbfs.7
@@ -102,6 +102,37 @@ large enough to contain at least one hugepage for the remapping to occur.
The following options affect how libhugetlbfs behaves.
.TP
+.B HUGETLB_RESTRICT_EXE=e1:e2:...:eN
+By default, libhugetlbfs will act on any program that it
+is loaded with, either via LD_PRELOAD or by explicitly
+linking with -lhugetlbfs.
+
+There are situations in which it is desirable to restrict
+libhugetlbfs' actions to specific programs. For example,
+some ISV applications are wrapped in a series of scripts
+that invoke bash, python, and/or perl. It is more
+convenient to set the environment variables related
+to libhugetlbfs before invoking the wrapper scripts,
+yet this has the unintended and undesirable consequence
+of causing the script interpreters to use and consume
+hugepages. There is no obvious benefit to causing the
+script interpreters to use hugepages, and there is a
+clear disadvantage: fewer hugepages are available to
+the actual application.
+
+To address this scenario, set HUGETLB_RESTRICT_EXE to a
+colon-separated list of programs to which the other
+libhugetlbfs environment variables should apply. (If
+not set, libhugetlbfs will attempt to apply the requested
+actions to all programs.) For example,
+
+ HUGETLB_RESTRICT_EXE=hpcc:long_hpcc
+
+will restrict libhugetlbfs' actions to programs named
+/home/fred/hpcc and /bench/long_hpcc but not /bin/hpcc_no.
+
+
+.TP
.B HUGETLB_MORECORE_SHRINK=yes
By default, the hugepage heap does not shrink. Shrinking is enabled by
setting this environment variable. It is disabled by default as glibc
diff --git a/tests/malloc.c b/tests/malloc.c
index a50c99b..a1af5e1 100644
--- a/tests/malloc.c
+++ b/tests/malloc.c
@@ -42,16 +42,24 @@ static int block_sizes[] = {
int main(int argc, char *argv[])
{
int i;
- char *env;
+ char *env1, *env2, *exe;
int expect_hugepage = 0;
char *p;
test_init(argc, argv);
+ exe = strrchr(test_name, '/');
+ if (exe)
+ exe++; /* skip over "/" */
+ else
+ exe = test_name;
- env = getenv("HUGETLB_MORECORE");
- verbose_printf("HUGETLB_MORECORE=%s\n", env);
- if (env)
+ env1 = getenv("HUGETLB_MORECORE");
+ verbose_printf("HUGETLB_MORECORE=%s\n", env1);
+ env2 = getenv("HUGETLB_RESTRICT_EXE");
+ verbose_printf("HUGETLB_RESTRICT_EXE=%s\n", env2);
+ if (env1 && (!env2 || strstr(env2, exe)))
expect_hugepage = 1;
+ verbose_printf("expect_hugepage=%d\n", expect_hugepage);
for (i = 0; i < NUM_SIZES; i++) {
int size = block_sizes[i];
diff --git a/tests/run_tests.py b/tests/run_tests.py
index 27a94cb..8055940 100755
--- a/tests/run_tests.py
+++ b/tests/run_tests.py
@@ -554,6 +554,10 @@ def functional_tests():
do_test("direct")
do_test("malloc")
do_test("malloc", LD_PRELOAD="libhugetlbfs.so", HUGETLB_MORECORE="yes")
+ do_test("malloc", LD_PRELOAD="libhugetlbfs.so", HUGETLB_MORECORE="yes",
+ HUGETLB_RESTRICT_EXE="unknown:none")
+ do_test("malloc", LD_PRELOAD="libhugetlbfs.so", HUGETLB_MORECORE="yes",
+ HUGETLB_RESTRICT_EXE="unknown:malloc")
do_test("malloc_manysmall")
do_test("malloc_manysmall", LD_PRELOAD="libhugetlbfs.so",
HUGETLB_MORECORE="yes")