[glibc] elf: Align large load segments to PMD huge page size for THP

Wilco Dijkstra via Glibc-cvs <[email protected]>
Newsgroups gmane.comp.lib.glibc.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=2f9fc3fba6562c888204159c09d654cb3499e38b

commit 2f9fc3fba6562c888204159c09d654cb3499e38b
Author: WANG Rui <[email protected]>
Date:   Tue Apr 14 15:24:39 2026 +0000

    elf: Align large load segments to PMD huge page size for THP
    
    Mapping segments that are at least the size of a PMD huge page to
    huge-page-aligned addresses helps make them eligible for Transparent
    Huge Pages (THP).
    
    This patch introduces a Linux-specific helper, `_dl_map_segment_align`,
    to determine an appropriate maximum alignment for ELF load segments based
    on the system THP policy. The optimization is enabled only when the glibc
    tunable `glibc.elf.thp=1` is set and THP is configured to be used
    unconditionally.
    
    The optimization depends on Linux kernel support for file-backed THP,
    specifically:
    
    * `CONFIG_READ_ONLY_THP_FOR_FS` (available since Linux kernel 5.4), and
    * `CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS`.
    
    When enabled, the helper queries the default THP page size and uses it
    to align sufficiently large load segments that are already properly
    aligned in both virtual address and file offset (e.g., zero).
    
    For eligible segments, the alignment is bumped to the THP page size,
    which improves THP eligibility, reduces TLB pressure, and improves
    performance for large objects. To avoid excessive address space padding
    on systems with very large THP sizes, the alignment is capped at 32MB.
    The optimization is applied only to non-writable segments, matching
    typical THP usage.
    
    Signed-off-by: WANG Rui <[email protected]>
    Reviewed-by: Wilco Dijkstra  <[email protected]>

Diff:
---
 sysdeps/unix/sysv/linux/Makefile               |  1 +
 sysdeps/unix/sysv/linux/dl-map-segment-align.c | 55 ++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/dl-map-segment-align.h | 27 +++++++++++++
 3 files changed, 83 insertions(+)

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 94608b436b..b06afbdeaa 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -673,6 +673,7 @@ endif
 
 ifeq ($(subdir),elf)
 dl-routines += \
+  dl-map-segment-align \
   dl-rseq-symbols \
   # dl-routines
 
diff --git a/sysdeps/unix/sysv/linux/dl-map-segment-align.c b/sysdeps/unix/sysv/linux/dl-map-segment-align.c
new file mode 100644
index 0000000000..a39e74d91b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/dl-map-segment-align.c
@@ -0,0 +1,55 @@
+/* _dl_map_segment_align.  Linux version.
+   Copyright (C) 2026 Free Software Foundation, Inc.
+   Copyright The GNU Toolchain Authors.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <dl-map-segment-align.h>
+#include <dl-tunables.h>
+#include <hugepages.h>
+
+ElfW (Addr)
+_dl_map_segment_align (const struct loadcmd *c, ElfW (Addr) p_align_max)
+{
+  static enum thp_mode_t thp_mode = thp_mode_not_supported;
+  static unsigned long int thp_pagesize;
+
+  if (TUNABLE_GET (glibc, elf, thp, int32_t, NULL) == 0)
+    return p_align_max;
+
+  if (__glibc_unlikely (thp_mode == thp_mode_not_supported
+                        || thp_pagesize == 0))
+    {
+      unsigned long int default_thp_pagesize = DL_MAP_DEFAULT_THP_PAGESIZE;
+      thp_mode = default_thp_pagesize ? thp_mode_always : __get_thp_mode ();
+      thp_pagesize = default_thp_pagesize ? : __get_thp_size ();
+    }
+
+  /* Aligning load segments that are large enough to the PMD size helps
+     improve THP eligibility and reduces TLB pressure.
+     We cap the huge page size at MAX_THP_PAGESIZE to avoid over-aligning
+     on systems with very large normal pages (like 64K pages with 512M
+     huge pages). */
+  if (thp_mode == thp_mode_always
+      && thp_pagesize <= MAX_THP_PAGESIZE
+      && ((c->mapstart | c->mapoff) & (thp_pagesize - 1)) == 0
+      && (c->mapend - c->mapstart) >= thp_pagesize
+      && p_align_max < thp_pagesize
+      && (c->prot & PROT_WRITE) == 0)
+    return thp_pagesize;
+
+  return p_align_max;
+}
diff --git a/sysdeps/unix/sysv/linux/dl-map-segment-align.h b/sysdeps/unix/sysv/linux/dl-map-segment-align.h
new file mode 100644
index 0000000000..d9b05181b7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/dl-map-segment-align.h
@@ -0,0 +1,27 @@
+/* _dl_map_segment_align.  Linux version.
+   Copyright (C) 2026 Free Software Foundation, Inc.
+   Copyright The GNU Toolchain Authors.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <dl-load.h>
+
+#ifndef DL_MAP_DEFAULT_THP_PAGESIZE
+# define DL_MAP_DEFAULT_THP_PAGESIZE	0
+#endif
+
+extern ElfW (Addr) _dl_map_segment_align
+  (const struct loadcmd *, ElfW (Addr)) attribute_hidden;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.