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 <lu...@cray.com>. Signed-off-by: Andrew Hastings <a...@cray.com> on behalf of Cray Inc. --- -Andrew Hastings Cray Inc. HOWTO | 31 +++++++++++++++++++++++ hugeutils.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++ man/libhugetlbfs.7 | 31 +++++++++++++++++++++++ tests/malloc.c | 16 +++++++++--- tests/run_tests.py | 4 +++ 5 files changed, 146 insertions(+), 5 deletions(-) diff -ruNp libhugetlbfs-2.11/HOWTO libhugetlbfs-2.11-restrict/HOWTO --- libhugetlbfs-2.11/HOWTO 2010-12-16 11:38:22.000000000 -0600 +++ libhugetlbfs-2.11-restrict/HOWTO 2011-02-02 10:59:24.997143000 -0600 @@ -2,7 +2,7 @@ libhugetlbfs HOWTO ================== Author: David Gibson <d...@au1.ibm.com>, Adam Litke <a...@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 -ruNp libhugetlbfs-2.11/hugeutils.c libhugetlbfs-2.11-restrict/hugeutils.c --- libhugetlbfs-2.11/hugeutils.c 2010-12-16 11:38:22.000000000 -0600 +++ libhugetlbfs-2.11-restrict/hugeutils.c 2011-02-02 11:05:42.338572000 -0600 @@ -233,6 +233,52 @@ int file_write_ulong(char *file, unsigne 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 -ruNp libhugetlbfs-2.11/man/libhugetlbfs.7 libhugetlbfs-2.11-restrict/man/libhugetlbfs.7 --- libhugetlbfs-2.11/man/libhugetlbfs.7 2010-12-16 11:38:22.000000000 -0600 +++ libhugetlbfs-2.11-restrict/man/libhugetlbfs.7 2011-02-02 10:59:33.818272000 -0600 @@ -102,6 +102,37 @@ large enough to contain at least one hug 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 -ruNp libhugetlbfs-2.11/tests/malloc.c libhugetlbfs-2.11-restrict/tests/malloc.c --- libhugetlbfs-2.11/tests/malloc.c 2010-12-16 11:38:22.000000000 -0600 +++ libhugetlbfs-2.11-restrict/tests/malloc.c 2011-02-02 10:59:14.477875000 -0600 @@ -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 -ruNp libhugetlbfs-2.11/tests/run_tests.py libhugetlbfs-2.11-restrict/tests/run_tests.py --- libhugetlbfs-2.11/tests/run_tests.py 2010-12-16 11:38:22.000000000 -0600 +++ libhugetlbfs-2.11-restrict/tests/run_tests.py 2011-02-02 11:14:25.154383000 -0600 @@ -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") ------------------------------------------------------------------------------ Special Offer-- Download ArcSight Logger for FREE (a $49 USD value)! Finally, a world-class log management solution at an even better price-free! Download using promo code Free_Logger_4_Dev2Dev. Offer expires February 28th, so secure your free ArcSight Logger TODAY! http://p.sf.net/sfu/arcsight-sfd2d _______________________________________________ Libhugetlbfs-devel mailing list Libhugetlbfs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel