[glibc] malloc: Remove dynamic mmap/trim threshold [BZ #30769]

Adhemerval Zanella via Glibc-cvs <[email protected]> Mon, 18 May 2026 16:34:16 +0000 (GMT)
Newsgroups gmane.comp.lib.glibc.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=17a79a51208c5648fe70983085833bf15d83d0f1

commit 17a79a51208c5648fe70983085833bf15d83d0f1
Author: Wilco Dijkstra <[email protected]>
Date:   Thu Apr 2 13:56:10 2026 +0000

    malloc: Remove dynamic mmap/trim threshold [BZ #30769]
    
    v2: Update documentation
    
    Whenever a large mmap is released the mmap and trim thresholds are updated.
    As a result these thresholds grow ever larger which means huge allocations
    are always served by arenas rather than mmap.  The thresholds can end up as
    large as an arena, which completely stops all trimming of the top block.
    Remove the code completely - the default thresholds seem way too low for
    modern 64-bit targets, but they can be increased seperately.
    
    Reviewed-by: Adhemerval Zanella  <[email protected]>

Diff:
---
 malloc/malloc.c    | 32 ++++----------------------------
 manual/memory.texi | 10 ++--------
 manual/probes.texi | 26 ++++++++------------------
 3 files changed, 14 insertions(+), 54 deletions(-)

diff --git a/malloc/malloc.c b/malloc/malloc.c
index 57b58382b1..63198fcde1 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1770,10 +1770,6 @@ struct malloc_par
   int n_mmaps;
   int n_mmaps_max;
   int max_n_mmaps;
-  /* the mmap_threshold is dynamic, until the user sets
-     it manually, at which point we need to disable any
-     dynamic behavior. */
-  int no_dyn_threshold;
 
   /* Statistics */
   INTERNAL_SIZE_T mmapped_mem;
@@ -4291,18 +4287,6 @@ _int_free_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size, int have_lock)
     /* Preserve errno in case munmap sets it.  */
     int err = errno;
 
-    /* See if the dynamic brk/mmap threshold needs adjusting.
-       Dumped fake mmapped chunks do not affect the threshold.  */
-    if (!mp_.no_dyn_threshold
-        && chunksize_nomask (p) > mp_.mmap_threshold
-        && chunksize_nomask (p) <= DEFAULT_MMAP_THRESHOLD_MAX)
-      {
-        mp_.mmap_threshold = chunksize (p);
-        mp_.trim_threshold = 2 * mp_.mmap_threshold;
-        LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2,
-		    mp_.mmap_threshold, mp_.trim_threshold);
-      }
-
     munmap_chunk (p);
 
     __set_errno (err);
@@ -4901,40 +4885,32 @@ __malloc_stats (void)
 static __always_inline int
 do_set_trim_threshold (size_t value)
 {
-  LIBC_PROBE (memory_mallopt_trim_threshold, 3, value, mp_.trim_threshold,
-	      mp_.no_dyn_threshold);
+  LIBC_PROBE (memory_mallopt_trim_threshold, 2, value, mp_.trim_threshold);
   mp_.trim_threshold = value;
-  mp_.no_dyn_threshold = 1;
   return 1;
 }
 
 static __always_inline int
 do_set_top_pad (size_t value)
 {
-  LIBC_PROBE (memory_mallopt_top_pad, 3, value, mp_.top_pad,
-	      mp_.no_dyn_threshold);
+  LIBC_PROBE (memory_mallopt_top_pad, 2, value, mp_.top_pad);
   mp_.top_pad = value;
-  mp_.no_dyn_threshold = 1;
   return 1;
 }
 
 static __always_inline int
 do_set_mmap_threshold (size_t value)
 {
-  LIBC_PROBE (memory_mallopt_mmap_threshold, 3, value, mp_.mmap_threshold,
-	      mp_.no_dyn_threshold);
+  LIBC_PROBE (memory_mallopt_mmap_threshold, 2, value, mp_.mmap_threshold);
   mp_.mmap_threshold = value;
-  mp_.no_dyn_threshold = 1;
   return 1;
 }
 
 static __always_inline int
 do_set_mmaps_max (int32_t value)
 {
-  LIBC_PROBE (memory_mallopt_mmap_max, 3, value, mp_.n_mmaps_max,
-	      mp_.no_dyn_threshold);
+  LIBC_PROBE (memory_mallopt_mmap_max, 2, value, mp_.n_mmaps_max);
   mp_.n_mmaps_max = value;
-  mp_.no_dyn_threshold = 1;
   return 1;
 }
 
diff --git a/manual/memory.texi b/manual/memory.texi
index 4f0ef51514..f8b6be6ee7 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -1333,10 +1333,7 @@ that the memory for these chunks can be returned to the system on
 @code{free}.  Note that requests smaller than this threshold might still
 be allocated via @code{mmap}.
 
-If this parameter is not set, the default value is set as 128 KiB and the
-threshold is adjusted dynamically to suit the allocation patterns of the
-program. If the parameter is set, the dynamic adjustment is disabled and the
-value is set statically to the input value.
+If this parameter is not set, the default value is set as 128 KiB.
 
 This parameter can also be set for the process at startup by setting the
 environment variable @env{MALLOC_MMAP_THRESHOLD_} to the desired value.
@@ -1371,10 +1368,7 @@ environment variable @env{MALLOC_TOP_PAD_} to the desired value.
 This is the minimum size (in bytes) of the top-most, releasable chunk
 that will trigger a system call in order to return memory to the system.
 
-If this parameter is not set, the default value is set as 128 KiB and the
-threshold is adjusted dynamically to suit the allocation patterns of the
-program. If the parameter is set, the dynamic adjustment is disabled and the
-value is set statically to the provided input.
+If this parameter is not set, the default value is set as 128 KiB.
 
 This parameter can also be set for the process at startup by setting the
 environment variable @env{MALLOC_TRIM_THRESHOLD_} to the desired value.
diff --git a/manual/probes.texi b/manual/probes.texi
index 23340e8e07..82d234f4b8 100644
--- a/manual/probes.texi
+++ b/manual/probes.texi
@@ -161,37 +161,33 @@ value, and @var{$arg2} is the previous value of this @code{malloc}
 parameter.
 @end deftp
 
-@deftp Probe memory_mallopt_trim_threshold (int @var{$arg1}, int @var{$arg2}, int @var{$arg3})
+@deftp Probe memory_mallopt_trim_threshold (int @var{$arg1}, int @var{$arg2})
 This probe is triggered shortly after the @code{memory_mallopt} probe,
 when the parameter to be changed is @code{M_TRIM_THRESHOLD}.  Argument
 @var{$arg1} is the requested value, @var{$arg2} is the previous value of
-this @code{malloc} parameter, and @var{$arg3} is nonzero if dynamic
-threshold adjustment was already disabled.
+this @code{malloc} parameter.
 @end deftp
 
-@deftp Probe memory_mallopt_top_pad (int @var{$arg1}, int @var{$arg2}, int @var{$arg3})
+@deftp Probe memory_mallopt_top_pad (int @var{$arg1}, int @var{$arg2})
 This probe is triggered shortly after the @code{memory_mallopt} probe,
 when the parameter to be changed is @code{M_TOP_PAD}.  Argument
 @var{$arg1} is the requested value, @var{$arg2} is the previous value of
-this @code{malloc} parameter, and @var{$arg3} is nonzero if dynamic
-threshold adjustment was already disabled.
+this @code{malloc} parameter.
 @end deftp
 
-@deftp Probe memory_mallopt_mmap_threshold (int @var{$arg1}, int @var{$arg2}, int @var{$arg3})
+@deftp Probe memory_mallopt_mmap_threshold (int @var{$arg1}, int @var{$arg2})
 This probe is triggered shortly after the @code{memory_mallopt} probe,
 when the parameter to be changed is @code{M_MMAP_THRESHOLD}, and the
 requested value is in an acceptable range.  Argument @var{$arg1} is the
 requested value, @var{$arg2} is the previous value of this @code{malloc}
-parameter, and @var{$arg3} is nonzero if dynamic threshold adjustment
-was already disabled.
+parameter.
 @end deftp
 
-@deftp Probe memory_mallopt_mmap_max (int @var{$arg1}, int @var{$arg2}, int @var{$arg3})
+@deftp Probe memory_mallopt_mmap_max (int @var{$arg1}, int @var{$arg2})
 This probe is triggered shortly after the @code{memory_mallopt} probe,
 when the parameter to be changed is @code{M_MMAP_MAX}.  Argument
 @var{$arg1} is the requested value, @var{$arg2} is the previous value of
-this @code{malloc} parameter, and @var{$arg3} is nonzero if dynamic
-threshold adjustment was already disabled.
+this @code{malloc} parameter.
 @end deftp
 
 @deftp Probe memory_mallopt_perturb (int @var{$arg1}, int @var{$arg2})
@@ -217,12 +213,6 @@ requested value, and @var{$arg2} is the previous value of this
 @code{malloc} parameter.
 @end deftp
 
-@deftp Probe memory_mallopt_free_dyn_thresholds (int @var{$arg1}, int @var{$arg2})
-This probe is triggered when function @code{free} decides to adjust the
-dynamic brk/mmap thresholds.  Argument @var{$arg1} and @var{$arg2} are
-the adjusted mmap and trim thresholds, respectively.
-@end deftp
-
 @deftp Probe memory_tunable_tcache_max_bytes (int @var{$arg1}, int @var{$arg2})
 This probe is triggered when the @code{glibc.malloc.tcache_max}
 tunable is set.  Argument @var{$arg1} is the requested value, and