[PATCH v5] elf: Support THP segment load with madvise enabled THP

H.J. Lu hjl.tools@gmail.com
Tue Apr 21 01:31:30 GMT 2026


Changes from v4:

1. Rebase against e3e8f814e5 visories: Fix spelling mistake in
GLIBC-SA-2026-0009.
2. Drop the -z separate-code linker option check and use it unconditionally.
3. Set the maximum page alignment on tst-thp-size-mod.so to THP page size.

Changes from v3:

1. Fold the -z separate-code linker option check.
2. Move DL_MAP_DEFAULT_THP_PAGESIZE to <hugepages.h>
and default it to 0.
3. Don't run strace tests for cross-compiling.
4. Remove return after FAIL_UNSUPPORTED in THP test.

Changes from v2:

1.  Keep _dl_map_segment_align name.
2.  Pass size_t to _dl_map_segment_align.
3.  Enable THP if THP is always enabled in the kernel.
4.  Disable THP if THP page size > MAX_THP_PAGESIZE

Changes from v1:

1. Rebased against the v10 THP test patch from WANG Rui <wangrui@loongson.cn>.
2. Keep DL_MAP_DEFAULT_THP_PAGESIZE.

-- 
H.J.
---
The current THP segment load approach works only when THP is enabled
with always in the kernel.  If THP is enabled with madvise in the
kernel, to enable THP segment load in an application, madvise should
be called with MADV_HUGEPAGE on all THP eligible PT_LOAD segments:

1. Define DL_MAP_DEFAULT_THP_PAGESIZE in hugepages.h and default it to 0.
2. Change _dl_map_segment_align to update alignments of PT_LOAD segments,
which marks and aligns only THP eligible PT_LOAD segments to THP page size
when loading an object. This fixes BZ #34079.
3. Call _dl_executable_postprocess in rtld_setup_main_map for dynamic
executables and in LIBC_START_MAIN for static executables, which calls
madvise with MADV_HUGEPAGE on all THP eligible PT_LOAD segments in
executable.  This fixes BZ #34080 for both dynamic and static executables.
4. Call _dl_postprocess_loadcmd_extra in _dl_postprocess_loadcmd, which
calls madvise with MADV_HUGEPAGE on all THP eligible PT_LOAD segments
when loading an object after they have been mapped in.  This fixes
BZ #34080 for shared objects.
5. Set the maximum page alignment on THP tests to THP page size as the
default maximum page alignment may be smaller than THP page size.
6. Add tests to verify that large executable PT_LOAD segments in
executables are mapped at addresses aligned to THP page size when the
kernel is configured to use THP in "always" mode or "madvise" mode by
inspecting /proc/self/maps to check that the mapping address is aligned
to THP page size reported by the kernel.  Also verify that madvise is
called with MADV_HUGEPAGE when the glibc tunable glibc.elf.thp=1 is used
and madvise isn't called with MADV_HUGEPAGE when the glibc tunable
glibc.elf.thp=0 is used.

Skip these tests if THP page size cannot be determined or if THP is not
enabled in "always" mode nor "madvise" mode.

Quote WANG Rui <wangrui@loongson.cn>:

>From benchmarking a clang build of the Linux kernel on x86_64 with
your patch in THP madvise mode, I observed that iTLB misses were
reduced, similar to what we see in THP always mode.

The added THP tests pass on x86 and aarch64.  Some of them failed on
arm:

https://patchwork.sourceware.org/project/glibc/patch/CAMe9rOqKfFXMDY07GRuppudP3V9fsCDXoyxDesPMNQLDrRhzvg@mail.gmail.com/

Produces 4 regressions:
   |
   | regressions.sum:
   | Running glibc:elf ...
   | FAIL: elf/tst-thp-1-no-s-code-pde
   | FAIL: elf/tst-thp-1-no-s-code-static
   | FAIL: elf/tst-thp-1-pde
   | FAIL: elf/tst-thp-1-static

It looks like PIE works, but PDE and static PIE don't work on arm.  The
Linaro report doesn't have useful information for these failures.  My
arm glibc test binaries look like

$ readelf -lW elf/tst-thp-1-pde

Elf file type is EXEC (Executable file)
Entry point 0x2003dc
There are 11 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  ARM_EXIDX      0x2400e24 0x02400e24 0x02400e24 0x000c8 0x000c8 R   0x4
  PHDR           0x000034 0x00000034 0x00000034 0x00160 0x00160 R   0x4
  INTERP         0x010194 0x00010194 0x00010194 0x00019 0x00019 R   0x1
      [Requesting program interpreter: /lib/ld-linux-armhf.so.3]
  LOAD           0x000000 0x00000000 0x00000000 0x11374 0x11374 R   0x200000
  LOAD           0x200000 0x00200000 0x00200000 0x20032d0 0x20032d0 R E 0x200000
  LOAD           0x2400000 0x02400000 0x02400000 0x00f10 0x00f10 R   0x200000
  LOAD           0x25ffebc 0x027ffebc 0x027ffebc 0x002a4 0x002c4 RW  0x200000
  DYNAMIC        0x25fff08 0x027fff08 0x027fff08 0x000f8 0x000f8 RW  0x4
  NOTE           0x2400ef0 0x02400ef0 0x02400ef0 0x00020 0x00020 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  GNU_RELRO      0x25ffebc 0x027ffebc 0x027ffebc 0x00144 0x00144 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     .ARM.exidx
   01
   02     .interp
   03     .interp .hash .gnu.hash .dynsym .dynstr .gnu.version
.gnu.version_r .rel.dyn .rel.plt
   04     .init .plt .text .fini
   05     .rodata .ARM.extab .ARM.exidx .eh_frame .note.ABI-tag
   06     .init_array .fini_array .data.rel.ro .dynamic .got .data .bss
   07     .dynamic
   08     .note.ABI-tag
   09
   10     .init_array .fini_array .data.rel.ro .dynamic
$

I can work with someone who has access to arm machine to get the bottom
of these failures.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: v5-0001-elf-Support-THP-segment-load-with-madvise-enabled.patch
Type: text/x-patch
Size: 52105 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20260421/36668279/attachment-0001.bin>


More information about the Libc-alpha mailing list