Transparent huge pages (THP) give another option for access to huge pages for
anonymous mappings.  This patch adds the ability to specify that the process
heap should be aligned and (if requested madvised) to be merged into huge pages
by khugepaged.  For more information on THP see
linux-2.6/Documentation/transhuge.txt.

Signed-off-by: Eric B Munson <emun...@mgebm.net>
---
 HOWTO                   |   11 ++++++++++-
 hugeutils.c             |    8 ++++++++
 libhugetlbfs_internal.h |    2 ++
 morecore.c              |   22 ++++++++++++++++++----
 4 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/HOWTO b/HOWTO
index 3c1f124..b018543 100644
--- a/HOWTO
+++ b/HOWTO
@@ -2,7 +2,7 @@ libhugetlbfs HOWTO
 ==================
 
 Author: David Gibson <d...@au1.ibm.com>, Adam Litke <a...@us.ibm.com>, and 
others
-Last updated: February 1st, 2011
+Last updated: May 25th, 2011
 
 Introduction
 ============
@@ -264,6 +264,11 @@ environment variables:
   To use a specific huge page size:
        HUGETLB_MORECORE=<pagesize>
 
+  To use Transparent Huge Pages (THP):
+       HUGETLB_MORECORE=thp
+
+Note: This option requires a kernel that supports Transparent Huge Pages
+
 Usually it's preferable to set these environment variables on the
 command line of the program you wish to run, rather than using
 "export", because you'll only want to enable the hugepage malloc() for
@@ -599,6 +604,10 @@ libhugetlbfs:
        HUGETLB_NO_PREFAULT
                Explained in "Using hugepages for malloc()
                (morecore)"
+       HUGETLB_THP_MADVISE
+               When using thp for HUGETLB_MORECORE, this signals that
+               allocations for the heap should use madvise(MADV_HUGEPAGE) to
+               mark them as appropriate for collapsing by khugepaged
 
        HUGETLB_VERBOSE
                Specify the verbosity level of debugging output from 1
diff --git a/hugeutils.c b/hugeutils.c
index b28bd0a..5e13e15 100644
--- a/hugeutils.c
+++ b/hugeutils.c
@@ -335,6 +335,14 @@ void hugetlbfs_setup_env()
        __hugetlb_opts.morecore = getenv("HUGETLB_MORECORE");
        __hugetlb_opts.heapbase = getenv("HUGETLB_MORECORE_HEAPBASE");
 
+       if (__hugetlb_opts.morecore)
+               __hugetlb_opts.thp_morecore =
+                       (strcasecmp(__hugetlb_opts.morecore, "thp") == 0);
+
+       env = getenv("HUGETLB_THP_MADVISE");
+       if (env && (strcasecmp(env, "yes") == 0))
+               __hugetlb_opts.thp_madvise = true;
+
        env = getenv("HUGETLB_FORCE_ELFMAP");
        if (env && (strcasecmp(env, "yes") == 0))
                __hugetlb_opts.force_elfmap = 1;
diff --git a/libhugetlbfs_internal.h b/libhugetlbfs_internal.h
index 97b19fa..b7d1bc0 100644
--- a/libhugetlbfs_internal.h
+++ b/libhugetlbfs_internal.h
@@ -63,6 +63,8 @@ struct libhugeopts_t {
        bool            shm_enabled;
        bool            no_reserve;
        bool            map_hugetlb;
+       bool            thp_morecore;
+       bool            thp_madvise;
        unsigned long   force_elfmap;
        char            *ld_preload;
        char            *elfmap;
diff --git a/morecore.c b/morecore.c
index 6b4364c..11a5493 100644
--- a/morecore.c
+++ b/morecore.c
@@ -100,7 +100,11 @@ static void *hugetlbfs_morecore(ptrdiff_t increment)
                INFO("Attempting to map %ld bytes\n", delta);
 
                /* map in (extend) more of the file at the end of our last map 
*/
-               if (__hugetlb_opts.map_hugetlb && using_default_pagesize)
+               if (__hugetlb_opts.thp_morecore)
+                       p = mmap(heapbase + mapsize, delta, 
PROT_READ|PROT_WRITE,
+                               MAP_ANONYMOUS|MAP_PRIVATE|mmap_reserve, heap_fd,
+                               mapsize);
+               else if (__hugetlb_opts.map_hugetlb && using_default_pagesize)
                        p = mmap(heapbase + mapsize, delta, 
PROT_READ|PROT_WRITE,
                                 
mmap_hugetlb|MAP_ANONYMOUS|MAP_PRIVATE|mmap_reserve,
                                 heap_fd, mapsize);
@@ -142,6 +146,11 @@ static void *hugetlbfs_morecore(ptrdiff_t increment)
 
                /* we now have mmap'd further */
                mapsize += delta;
+
+#ifdef MADV_HUGEPAGE
+               if (__hugetlb_opts.thp_madvise)
+                       madvise(p, delta, MADV_HUGEPAGE);
+#endif
        } else if (delta < 0) {
                /* shrinking the heap */
 
@@ -220,7 +229,8 @@ void hugetlbfs_setup_morecore(void)
         * This can be set explicitly by setting HUGETLB_MORECORE to a valid
         * page size string or by setting HUGETLB_DEFAULT_PAGE_SIZE.
         */
-       if (strncasecmp(__hugetlb_opts.morecore, "y", 1) == 0)
+       if ((strncasecmp(__hugetlb_opts.morecore, "y", 1) == 0) ||
+                       __hugetlb_opts.thp_morecore)
                hpage_size = gethugepagesize();
        else
                hpage_size = parse_page_size(__hugetlb_opts.morecore);
@@ -237,8 +247,12 @@ void hugetlbfs_setup_morecore(void)
                return;
        }
 
-       if(__hugetlb_opts.map_hugetlb &&
-                       hpage_size == kernel_default_hugepage_size()) {
+       /*
+        * We won't need an fd for the heap mmaps if we are using MAP_HUGETLB
+        * or we are depending on transparent huge pages
+        */
+       if(__hugetlb_opts.thp_morecore || (__hugetlb_opts.map_hugetlb &&
+                       hpage_size == kernel_default_hugepage_size())) {
                heap_fd = -1;
        } else {
                if (!hugetlbfs_find_path_for_size(hpage_size)) {
-- 
1.7.4.1


------------------------------------------------------------------------------
vRanger cuts backup time in half-while increasing security.
With the market-leading solution for virtual backup and recovery, 
you get blazing-fast, flexible, and affordable data protection.
Download your free trial now. 
http://p.sf.net/sfu/quest-d2dcopy1
_______________________________________________
Libhugetlbfs-devel mailing list
Libhugetlbfs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel

Reply via email to