[PATCH] thp: Disable THP if THP isn't supported by kernel
H.J. Lu
hjl.tools@gmail.com
Wed Jul 15 11:22:54 GMT 2026
On Wed, Jul 15, 2026 at 4:10 AM Adhemerval Zanella Netto
<adhemerval.zanella@linaro.org> wrote:
>
>
>
> On 04/07/26 00:05, H.J. Lu wrote:
> > Since DL_MAP_DEFAULT_THP_PAGESIZE is defined for x86-64, THP control
> > is to set to madvise by default. If THP is disabled in x86-64 kernel,
> > madvise (..., MADV_HUGEPAGE) returns -EINVAL to indicate that THP isn't
> > supported. Add _dl_thp_madvise to disable THP in this case. This
> > fixes BZ #34348.
> >
> > Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
>
> LGTM, two suggestion below.
>
> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
>
> > ---
> > sysdeps/unix/sysv/linux/dl-exec-post.h | 6 ++--
> > sysdeps/unix/sysv/linux/dl-load-post.h | 6 ++--
> > sysdeps/unix/sysv/linux/dl-thp-madvise.h | 35 ++++++++++++++++++++++++
> > 3 files changed, 43 insertions(+), 4 deletions(-)
> > create mode 100644 sysdeps/unix/sysv/linux/dl-thp-madvise.h
> >
> > diff --git a/sysdeps/unix/sysv/linux/dl-exec-post.h b/sysdeps/unix/sysv/linux/dl-exec-post.h
> > index 9a49486db2..4bc8a50dd1 100644
> > --- a/sysdeps/unix/sysv/linux/dl-exec-post.h
> > +++ b/sysdeps/unix/sysv/linux/dl-exec-post.h
> > @@ -17,6 +17,8 @@
> > License along with the GNU C Library; if not, see
> > <https://www.gnu.org/licenses/>. */
> >
> > +#include "dl-thp-madvise.h"
> > +
> > static inline void
> > _dl_get_thp_config (void)
> > {
> > @@ -116,8 +118,8 @@ _dl_executable_postprocess (struct link_map *main_map,
> > && ((ph->p_vaddr | ph->p_offset) & (thp_pagesize - 1)) == 0
> > && (ph->p_flags & (PF_W | PF_R)) == PF_R)
> > {
> > - int ret = __madvise ((void *) (main_map->l_addr + ph->p_vaddr),
> > - ph->p_memsz, MADV_HUGEPAGE);
> > + void *addr = (void *) (main_map->l_addr + ph->p_vaddr);
> > + int ret = _dl_thp_madvise (addr, ph->p_memsz);
> > if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
> > _dl_debug_printf ("\
> > madvise (0x%0*lx, 0x%0*lx, MADV_HUGEPAGE) returns %d\n",
> > diff --git a/sysdeps/unix/sysv/linux/dl-load-post.h b/sysdeps/unix/sysv/linux/dl-load-post.h
> > index 741c4ddcb1..935298bda5 100644
> > --- a/sysdeps/unix/sysv/linux/dl-load-post.h
> > +++ b/sysdeps/unix/sysv/linux/dl-load-post.h
> > @@ -17,6 +17,8 @@
> > License along with the GNU C Library; if not, see
> > <https://www.gnu.org/licenses/>. */
> >
> > +#include "dl-thp-madvise.h"
> > +
> > static bool _dl_segment_thp_eligible (const struct loadcmd *, size_t);
> >
> > /* After L has been mapped in, call madvise with MADV_HUGEPAGE for THP
> > @@ -28,8 +30,8 @@ _dl_postprocess_loadcmd_extra (struct link_map *l, const struct loadcmd *c)
> > if (GL(dl_thp_mode) == thp_mode_madvise
> > && _dl_segment_thp_eligible (c, GL(dl_elf_thp_pagesize)))
> > {
> > - int ret = __madvise ((void *) (l->l_addr + c->mapstart),
> > - c->mapend - c->mapstart, MADV_HUGEPAGE);
> > + int ret = _dl_thp_madvise ((void *) (l->l_addr + c->mapstart),
> > + c->mapend - c->mapstart);
> > if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
> > _dl_debug_printf ("\
> > madvise (0x%0*lx, 0x%0*lx, MADV_HUGEPAGE) returns %d\n",
> > diff --git a/sysdeps/unix/sysv/linux/dl-thp-madvise.h b/sysdeps/unix/sysv/linux/dl-thp-madvise.h
> > new file mode 100644
> > index 0000000000..1d54d19987
> > --- /dev/null
> > +++ b/sysdeps/unix/sysv/linux/dl-thp-madvise.h
> > @@ -0,0 +1,35 @@
> > +/* _dl_thp_madvise. 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/>. */
>
> Maybe a guard include here.
Fixed in v2.
> > +
> > +/* Similar to madvise, but disable THP if the madvise syscall returns
> > + -EINVAL which indicates that THP isn't supported by kernel. */
> > +
> > +static inline int
> > +_dl_thp_madvise (void *addr, size_t size)
> > +{
> > + int res = INTERNAL_SYSCALL_CALL (madvise, addr, size, MADV_HUGEPAGE);
> > + if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res))
> > + && INTERNAL_SYSCALL_ERRNO (res) == EINVAL)
> > + {
> > + /* NB: Disable THP if THP isn't supported by kernel. */
> > + GL(dl_thp_mode) = thp_mode_not_supported;
> > + GL(dl_elf_thp_control) = dl_elf_thp_control_disabled;
> > + }
> > + return res;
>
> This changes the DL_DEBUG_FILES to print the -errno value insteaf of the
> -1 previously, which is an improvement but a bit confusing. Maybe return
> INTERNAL_SYSCALL_ERRNO.
Fixed in v2.
> > +}
>
Thanks.
--
H.J.
More information about the Libc-alpha
mailing list