]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Created tunable to force small pages on stack allocation.
authorCupertino Miranda <cupertino.miranda@oracle.com>
Fri, 14 Apr 2023 15:12:20 +0000 (16:12 +0100)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Thu, 20 Apr 2023 16:54:24 +0000 (13:54 -0300)
Created tunable glibc.pthread.stack_hugetlb to control when hugepages
can be used for stack allocation.
In case THP are enabled and glibc.pthread.stack_hugetlb is set to
0, glibc will madvise the kernel not to use allow hugepages for stack
allocations.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
NEWS
manual/tunables.texi
nptl/allocatestack.c
nptl/nptl-stack.c
nptl/nptl-stack.h
nptl/pthread_mutex_conf.c
sysdeps/nptl/dl-tunables.list

diff --git a/NEWS b/NEWS
index 83d082afad753628e0949ae61767cffe3e7a2260..40964d2ee0e0735f61539fe5d5d667a90a040fb5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,9 @@ Major new features:
 
 * PRIb* and PRIB* macros from C2X have been added to <inttypes.h>.
 
+* A new tunable, glibc.pthread.stack_hugetlb, can be used to disable
+  Transparent Huge Pages (THP) in stack allocation at pthread_create.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * In the Linux kernel for the hppa/parisc architecture some of the
index 70dd2264c53b105c7f3441f0d20adb5bc970c1c0..130f94b2bce22605702279640436d4a0741ee9fc 100644 (file)
@@ -459,6 +459,21 @@ registration on behalf of the application.
 Restartable sequences are a Linux-specific extension.
 @end deftp
 
+@deftp Tunable glibc.pthread.stack_hugetlb
+This tunable controls whether to use Huge Pages in the stacks created by
+@code{pthread_create}.  This tunable only affects the stacks created by
+@theglibc{}, it has no effect on stack assigned with
+@code{pthread_attr_setstack}.
+
+The default is @samp{1} where the system default value is used.  Setting
+its value to @code{0} enables the use of @code{madvise} with
+@code{MADV_NOHUGEPAGE} after stack creation with @code{mmap}.
+
+This is a memory utilization optimization, since internal glibc setup of either
+the thread descriptor and the guard page might force the kernel to move the
+thread stack originally backup by Huge Pages to default pages.
+@end deftp
+
 @node Hardware Capability Tunables
 @section Hardware Capability Tunables
 @cindex hardware capability tunables
index c7adbccd6fc9ae99e6777034443c53a0224c6b1c..f9d8cdfd0824b10231c5a9427ec1f4afa5591844 100644 (file)
@@ -369,6 +369,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
          if (__glibc_unlikely (mem == MAP_FAILED))
            return errno;
 
+         /* Do madvise in case the tunable glibc.pthread.stack_hugetlb is
+            set to 0, disabling hugetlb.  */
+         if (__glibc_unlikely (__nptl_stack_hugetlb == 0)
+             && __madvise (mem, size, MADV_NOHUGEPAGE) != 0)
+           return errno;
+
          /* SIZE is guaranteed to be greater than zero.
             So we can never get a null pointer back from mmap.  */
          assert (mem != NULL);
index 5eb77735752cc7b517ec077ba52b05ad5abcbc32..e829711cb53e2e6907ac9cfb82f5e4fb7e368b2c 100644 (file)
@@ -21,6 +21,7 @@
 #include <pthreadP.h>
 
 size_t __nptl_stack_cache_maxsize = 40 * 1024 * 1024;
+int32_t __nptl_stack_hugetlb = 1;
 
 void
 __nptl_stack_list_del (list_t *elem)
index 34f8bbb15e9b0ddf430d12e46d2d54acde43c609..cf90b27c2bc39a430ee7ff88a7a2d013dc4c8482 100644 (file)
@@ -27,6 +27,9 @@
 /* Maximum size of the cache, in bytes.  40 MiB by default.  */
 extern size_t __nptl_stack_cache_maxsize attribute_hidden;
 
+/* Should allow stacks to use hugetlb. (1) is default.  */
+extern int32_t __nptl_stack_hugetlb;
+
 /* Check whether the stack is still used or not.  */
 static inline bool
 __nptl_stack_in_use (struct pthread *pd)
index 9133384d47a2e8609341e6698bcab6bc19c4db94..6517899718ec9a344cdb526ba0177f657b7d31e7 100644 (file)
@@ -44,6 +44,12 @@ TUNABLE_CALLBACK (set_stack_cache_size) (tunable_val_t *valp)
   __nptl_stack_cache_maxsize = valp->numval;
 }
 
+static void
+TUNABLE_CALLBACK (set_stack_hugetlb) (tunable_val_t *valp)
+{
+  __nptl_stack_hugetlb = (int32_t) valp->numval;
+}
+
 void
 __pthread_tunables_init (void)
 {
@@ -51,4 +57,6 @@ __pthread_tunables_init (void)
                TUNABLE_CALLBACK (set_mutex_spin_count));
   TUNABLE_GET (stack_cache_size, size_t,
                TUNABLE_CALLBACK (set_stack_cache_size));
+  TUNABLE_GET (stack_hugetlb, int32_t,
+              TUNABLE_CALLBACK (set_stack_hugetlb));
 }
index bd1ddb121d04a51001918e4391deee8eed475887..4cde9500b6484ee45fccceed2872a044a2b9bcbc 100644 (file)
@@ -33,5 +33,11 @@ glibc {
       maxval: 1
       default: 1
     }
+    stack_hugetlb {
+      type: INT_32
+      minval: 0
+      maxval: 1
+      default: 1
+    }
   }
 }