]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
malloc: Remove unused tcache code from unsorted bin scan
authorWilco Dijkstra <wilco.dijkstra@arm.com>
Wed, 17 Dec 2025 16:16:23 +0000 (16:16 +0000)
committerWilco Dijkstra <wilco.dijkstra@arm.com>
Fri, 6 Feb 2026 18:20:17 +0000 (18:20 +0000)
Now that fastbins have been removed, there is no need to add chunks
to tcache during an unsorted scan.  Small blocks can only be added
to unsorted as a result of a remainder chunk split off a larger block,
so there is no point in checking for additional chunks to place in
tcache.  The last remainder is checked first, and will be used if it
is large enough or an exact fit.  The unsorted bin scan becomes simpler
as a result.  Remove the tcache_unsorted_limit tunable and manual entries.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
elf/dl-tunables.list
elf/tst-rtld-list-tunables.exp
malloc/arena.c
malloc/malloc.c
manual/probes.texi
manual/tunables.texi

index 5bc5f037920d6db99bff4df513ac2ea3ae416b2a..040a544c0e0fe57c2205966412ea8589bb178189 100644 (file)
@@ -71,9 +71,6 @@ glibc {
     tcache_count {
       type: SIZE_T
     }
-    tcache_unsorted_limit {
-      type: SIZE_T
-    }
     mxfast {
       type: SIZE_T
       minval: 0
index 8df6f5906e6ccc1cc4094947e7084fbb8605dae3..9590021f3ae305a6088eaf81b106d2355b8da57a 100644 (file)
@@ -8,7 +8,6 @@ glibc.malloc.mxfast: 0x0 (min: 0x0, max: 0x[f]+)
 glibc.malloc.perturb: 0 (min: 0, max: 255)
 glibc.malloc.tcache_count: 0x0 (min: 0x0, max: 0x[f]+)
 glibc.malloc.tcache_max: 0x0 (min: 0x0, max: 0x[f]+)
-glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0x[f]+)
 glibc.malloc.top_pad: 0x20000 (min: 0x0, max: 0x[f]+)
 glibc.malloc.trim_threshold: 0x0 (min: 0x0, max: 0x[f]+)
 glibc.rtld.dynamic_sort: 2 (min: 1, max: 2)
index 5bfcd7f9723a8a6396ec53ea49bef5472fa28672..cabeb0d8ce1783121af3327ccd3371ab516b8722 100644 (file)
@@ -238,7 +238,6 @@ TUNABLE_CALLBACK_FNDECL (set_arena_test, size_t)
 #if USE_TCACHE
 TUNABLE_CALLBACK_FNDECL (set_tcache_max, size_t)
 TUNABLE_CALLBACK_FNDECL (set_tcache_count, size_t)
-TUNABLE_CALLBACK_FNDECL (set_tcache_unsorted_limit, size_t)
 #endif
 TUNABLE_CALLBACK_FNDECL (set_hugetlb, size_t)
 
@@ -290,8 +289,6 @@ __ptmalloc_init (void)
 # if USE_TCACHE
   TUNABLE_GET (tcache_max, size_t, TUNABLE_CALLBACK (set_tcache_max));
   TUNABLE_GET (tcache_count, size_t, TUNABLE_CALLBACK (set_tcache_count));
-  TUNABLE_GET (tcache_unsorted_limit, size_t,
-              TUNABLE_CALLBACK (set_tcache_unsorted_limit));
 # endif
   TUNABLE_GET (hugetlb, size_t, TUNABLE_CALLBACK (set_hugetlb));
 
index a49e211925ae6303d064b7e590fd015e85affe38..0ff016e549694f457c3fe090f3265d35f1d60e28 100644 (file)
@@ -1797,9 +1797,6 @@ struct malloc_par
   size_t tcache_max_bytes;
   /* Maximum number of chunks in each bucket.  */
   size_t tcache_count;
-  /* Maximum number of chunks to remove from the unsorted list, which
-     aren't used to prefill the cache.  */
-  size_t tcache_unsorted_limit;
 #endif
 };
 
@@ -1832,7 +1829,6 @@ static struct malloc_par mp_ =
   .tcache_count = TCACHE_FILL_COUNT,
   .tcache_small_bins = TCACHE_SMALL_BINS,
   .tcache_max_bytes = MAX_TCACHE_SMALL_SIZE + 1,
-  .tcache_unsorted_limit = 0 /* No limit.  */
 #endif
 };
 
@@ -3824,10 +3820,6 @@ _int_malloc (mstate av, size_t bytes)
   mchunkptr fwd;                    /* misc temp for linking */
   mchunkptr bck;                    /* misc temp for linking */
 
-#if USE_TCACHE
-  size_t tcache_unsorted_count;            /* count of unsorted chunks processed */
-#endif
-
   /*
      Convert request size to internal form by adding SIZE_SZ bytes
      overhead plus possibly more to obtain necessary alignment and/or
@@ -3925,24 +3917,8 @@ _int_malloc (mstate av, size_t bytes)
      the most recent non-exact fit.  Place other traversed chunks in
      bins.  Note that this step is the only place in any routine where
      chunks are placed in bins.
-
-     The outer loop here is needed because we might not realize until
-     near the end of malloc that we should have consolidated, so must
-     do so and retry. This happens at most once, and only when we would
-     otherwise need to expand memory to service a "small" request.
    */
 
-#if USE_TCACHE
-  INTERNAL_SIZE_T tcache_nb = 0;
-  size_t tc_idx = csize2tidx (nb);
-  if (tc_idx < mp_.tcache_small_bins)
-    tcache_nb = nb;
-  int return_cached = 0;
-
-  tcache_unsorted_count = 0;
-#endif
-
-  for (;; )
     {
       int iters = 0;
       while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av))
@@ -4012,28 +3988,10 @@ _int_malloc (mstate av, size_t bytes)
               set_inuse_bit_at_offset (victim, size);
               if (av != &main_arena)
                set_non_main_arena (victim);
-#if USE_TCACHE
-             if (__glibc_unlikely (tcache_inactive ()))
-               tcache_init (av);
-             /* Fill cache first, return to user only if cache fills.
-                We may return one of these chunks later.  */
-             if (tcache_nb > 0
-                 && tcache->num_slots[tc_idx] != 0)
-               {
-                 tcache_put (victim, tc_idx);
-                 return_cached = 1;
-                 continue;
-               }
-             else
-               {
-#endif
               check_malloced_chunk (av, victim, nb);
               void *p = chunk2mem (victim);
               alloc_perturb (p, bytes);
               return p;
-#if USE_TCACHE
-               }
-#endif
             }
 
           /* Place chunk in bin.  Only splitting can put
@@ -4107,31 +4065,11 @@ _int_malloc (mstate av, size_t bytes)
           fwd->bk = victim;
           bck->fd = victim;
 
-#if USE_TCACHE
-      /* If we've processed as many chunks as we're allowed while
-        filling the cache, return one of the cached ones.  */
-      ++tcache_unsorted_count;
-      if (return_cached
-         && mp_.tcache_unsorted_limit > 0
-         && tcache_unsorted_count > mp_.tcache_unsorted_limit)
-       {
-         return tcache_get (tc_idx);
-       }
-#endif
-
 #define MAX_ITERS       10000
           if (++iters >= MAX_ITERS)
             break;
         }
 
-#if USE_TCACHE
-      /* If all the small chunks we found ended up cached, return one now.  */
-      if (return_cached)
-       {
-         return tcache_get (tc_idx);
-       }
-#endif
-
       /*
          If a large request, scan through the chunks of current bin in
          sorted order to find smallest that fits.  Use the skip list for this.
@@ -5114,13 +5052,6 @@ do_set_tcache_count (size_t value)
   return 0;
 }
 
-static __always_inline int
-do_set_tcache_unsorted_limit (size_t value)
-{
-  LIBC_PROBE (memory_tunable_tcache_unsorted_limit, 2, value, mp_.tcache_unsorted_limit);
-  mp_.tcache_unsorted_limit = value;
-  return 1;
-}
 #endif
 
 static __always_inline int
index ee019e651706f49253279b332edb7fc343a04183..23340e8e0774ae080bc6cecf0a916902c490f629 100644 (file)
@@ -235,13 +235,6 @@ tunable is set.  Argument @var{$arg1} is the requested value, and
 @var{$arg2} is the previous value of this tunable.
 @end deftp
 
-@deftp Probe memory_tunable_tcache_unsorted_limit (int @var{$arg1}, int @var{$arg2})
-This probe is triggered when the
-@code{glibc.malloc.tcache_unsorted_limit} tunable is set.  Argument
-@var{$arg1} is the requested value, and @var{$arg2} is the previous
-value of this tunable.
-@end deftp
-
 @deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2})
 This probe is triggered when @code{free} determines that the memory
 being freed has probably already been freed, and resides in the
index 7956df919beeb0b05b93d942e8dd8938ecc4d018..cacc0ea65262f06eb8c7f8a40520d5d85444a171 100644 (file)
@@ -53,7 +53,6 @@ glibc.cpu.x86_shstk:
 glibc.pthread.stack_cache_size: 0x2800000 (min: 0x0, max: 0xffffffffffffffff)
 glibc.malloc.mmap_max: 0 (min: 0, max: 2147483647)
 glibc.cpu.plt_rewrite: 0 (min: 0, max: 2)
-glibc.malloc.tcache_unsorted_limit: 0x0 (min: 0x0, max: 0xffffffffffffffff)
 glibc.cpu.x86_ibt:
 glibc.cpu.hwcaps:
 glibc.malloc.arena_max: 0x0 (min: 0x1, max: 0xffffffffffffffff)
@@ -243,21 +242,6 @@ per-thread cache is approximately 236 KB on 64-bit systems and 118 KB
 on 32-bit systems.
 @end deftp
 
-@deftp Tunable glibc.malloc.tcache_unsorted_limit
-When the user requests memory and the request cannot be met via the
-per-thread cache, the arenas are used to meet the request.  At this
-time, additional chunks will be moved from existing arena lists to
-pre-fill the corresponding cache.  While copies from the fastbins,
-smallbins, and regular bins are bounded and predictable due to the bin
-sizes, copies from the unsorted bin are not bounded, and incur
-additional time penalties as they need to be sorted as they're
-scanned.  To make scanning the unsorted list more predictable and
-bounded, the user may set this tunable to limit the number of chunks
-that are scanned from the unsorted list while searching for chunks to
-pre-fill the per-thread cache with.  The default, or when set to zero,
-is no limit.
-@end deftp
-
 @deftp Tunable glibc.malloc.mxfast
 One of the optimizations @code{malloc} uses is to maintain a series of ``fast
 bins'' that hold chunks up to a specific size.  The default and