[PATCH v3 1/6] hugepages: Move THP helpers to generic hugepages abstraction
WANG Rui
wangrui@loongson.cn
Fri Feb 27 13:23:29 GMT 2026
The helpers for determining the default transparent huge page size
and THP mode are currently implemented in malloc-hugepages. However,
these interfaces are not malloc-specific and are also needed by other
subsystems (e.g. the dynamic loader for segment alignment).
Introduce a new generic hugepages abstraction and move the THP mode
detection and default page size probing there. The malloc code now
calls into the generic helpers instead of duplicating the sysfs
parsing.
There is no functional change. This is a pure refactoring to make
the THP detection reusable outside of malloc.
* malloc/malloc.c (malloc_par): Use hugepages_thp_mode_t.
(thp_init): Call __hugepages_thp_mode.
(madvise_thp): Adjust enum usage.
(do_set_hugetlb): Use __hugepages_thp_mode and updated enum.
* sysdeps/generic/hugepages.h: New file.
Define hugepages_thp_mode_t and declare helpers.
* sysdeps/generic/hugepages.c: New file.
Provide generic stubs.
* sysdeps/unix/sysv/linux/hugepages.c: New file.
Provide Linux implementation reading THP sysfs files.
* sysdeps/generic/malloc-hugepages.c
(__malloc_default_thp_pagesize): Delegate to
__hugepages_default_thp_pagesize.
* sysdeps/generic/malloc-hugepages.h:
Include <hugepages.h>.
Rename DEFAULT_THP_PAGESIZE to MALLOC_DEFAULT_THP_PAGESIZE.
Remove malloc_thp_mode_t and __malloc_thp_mode.
* sysdeps/unix/sysv/linux/malloc-hugepages.c
(__malloc_default_thp_pagesize): Use
MALLOC_DEFAULT_THP_PAGESIZE and
__hugepages_default_thp_pagesize.
* sysdeps/unix/sysv/linux/aarch64/malloc-hugepages.h:
Rename DEFAULT_THP_PAGESIZE to
MALLOC_DEFAULT_THP_PAGESIZE.
* sysdeps/generic/Makefile: Add hugepages to sysdep routines.
Signed-off-by: WANG Rui <wangrui@loongson.cn>
---
malloc/malloc.c | 23 +++---
sysdeps/generic/Makefile | 8 +-
sysdeps/generic/hugepages.c | 31 ++++++++
sysdeps/generic/hugepages.h | 35 +++++++++
sysdeps/generic/malloc-hugepages.c | 8 +-
sysdeps/generic/malloc-hugepages.h | 15 +---
.../sysv/linux/aarch64/malloc-hugepages.h | 2 +-
sysdeps/unix/sysv/linux/hugepages.c | 77 +++++++++++++++++++
sysdeps/unix/sysv/linux/malloc-hugepages.c | 59 +-------------
9 files changed, 170 insertions(+), 88 deletions(-)
create mode 100644 sysdeps/generic/hugepages.c
create mode 100644 sysdeps/generic/hugepages.h
create mode 100644 sysdeps/unix/sysv/linux/hugepages.c
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 0ff016e549..04c0240983 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1768,7 +1768,7 @@ struct malloc_par
INTERNAL_SIZE_T arena_max;
/* Transparent Large Page support. */
- enum malloc_thp_mode_t thp_mode;
+ enum hugepages_thp_mode_t thp_mode;
INTERNAL_SIZE_T thp_pagesize;
/* A value different than 0 means to align mmap allocation to hp_pagesize
add hp_flags on flags. */
@@ -1823,7 +1823,7 @@ static struct malloc_par mp_ =
.trim_threshold = DEFAULT_TRIM_THRESHOLD,
#define NARENAS_FROM_NCORES(n) ((n) * (sizeof (long) == 4 ? 2 : 8))
.arena_test = NARENAS_FROM_NCORES (1),
- .thp_mode = malloc_thp_mode_not_supported
+ .thp_mode = hugepages_thp_mode_not_supported
#if USE_TCACHE
,
.tcache_count = TCACHE_FILL_COUNT,
@@ -1901,14 +1901,15 @@ free_perturb (char *p, size_t n)
static __always_inline void
thp_init (void)
{
- /* Initialize only once if DEFAULT_THP_PAGESIZE is defined. */
- if (DEFAULT_THP_PAGESIZE == 0 || mp_.thp_mode != malloc_thp_mode_not_supported)
+ /* Initialize only once if MALLOC_DEFAULT_THP_PAGESIZE is defined. */
+ if (MALLOC_DEFAULT_THP_PAGESIZE == 0
+ || mp_.thp_mode != hugepages_thp_mode_not_supported)
return;
/* Set thp_pagesize even if thp_mode is never. This reduces frequency
of MORECORE () invocation. */
- mp_.thp_mode = __malloc_thp_mode ();
- mp_.thp_pagesize = DEFAULT_THP_PAGESIZE;
+ mp_.thp_mode = __hugepages_thp_mode ();
+ mp_.thp_pagesize = MALLOC_DEFAULT_THP_PAGESIZE;
}
static inline void
@@ -1920,7 +1921,7 @@ madvise_thp (void *p, INTERNAL_SIZE_T size)
/* Only use __madvise if the system is using 'madvise' mode and the size
is at least a huge page, otherwise the call is wasteful. */
- if (mp_.thp_mode != malloc_thp_mode_madvise || size < mp_.thp_pagesize)
+ if (mp_.thp_mode != hugepages_thp_mode_madvise || size < mp_.thp_pagesize)
return;
/* Linux requires the input address to be page-aligned, and unaligned
@@ -5064,12 +5065,12 @@ static __always_inline int
do_set_hugetlb (size_t value)
{
if (value == 0)
- mp_.thp_mode = malloc_thp_mode_never;
+ mp_.thp_mode = hugepages_thp_mode_never;
else if (value == 1)
{
- mp_.thp_mode = __malloc_thp_mode ();
- if (mp_.thp_mode == malloc_thp_mode_madvise
- || mp_.thp_mode == malloc_thp_mode_always)
+ mp_.thp_mode = __hugepages_thp_mode ();
+ if (mp_.thp_mode == hugepages_thp_mode_madvise
+ || mp_.thp_mode == hugepages_thp_mode_always)
mp_.thp_pagesize = __malloc_default_thp_pagesize ();
}
else if (value >= 2)
diff --git a/sysdeps/generic/Makefile b/sysdeps/generic/Makefile
index 0c25592f35..9704e3f21f 100644
--- a/sysdeps/generic/Makefile
+++ b/sysdeps/generic/Makefile
@@ -32,9 +32,13 @@ endif
endif
ifeq ($(subdir),malloc)
-sysdep_malloc_debug_routines += malloc-hugepages
+sysdep_malloc_debug_routines += \
+ hugepages \
+ malloc-hugepages
endif
ifeq ($(subdir),misc)
-sysdep_routines += malloc-hugepages
+sysdep_routines += \
+ hugepages \
+ malloc-hugepages
endif
diff --git a/sysdeps/generic/hugepages.c b/sysdeps/generic/hugepages.c
new file mode 100644
index 0000000000..961a256c15
--- /dev/null
+++ b/sysdeps/generic/hugepages.c
@@ -0,0 +1,31 @@
+/* Huge Page support. Generic implementation.
+ Copyright (C) 2021-2026 Free Software Foundation, Inc.
+ 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; see the file COPYING.LIB. If
+ not, see <https://www.gnu.org/licenses/>. */
+
+#include <hugepages.h>
+
+unsigned long int
+__hugepages_default_thp_pagesize (void)
+{
+ return 0;
+}
+
+enum hugepages_thp_mode_t
+__hugepages_thp_mode (void)
+{
+ return hugepages_thp_mode_not_supported;
+}
diff --git a/sysdeps/generic/hugepages.h b/sysdeps/generic/hugepages.h
new file mode 100644
index 0000000000..f9e2569e9b
--- /dev/null
+++ b/sysdeps/generic/hugepages.h
@@ -0,0 +1,35 @@
+/* Huge page support. Generic implementation.
+ Copyright (C) 2021-2026 Free Software Foundation, Inc.
+ 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; see the file COPYING.LIB. If
+ not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _HUGEPAGES_H
+#define _HUGEPAGES_H
+
+/* Return the default transparent huge page size. */
+unsigned long int __hugepages_default_thp_pagesize (void) attribute_hidden;
+
+enum hugepages_thp_mode_t
+{
+ hugepages_thp_mode_always,
+ hugepages_thp_mode_madvise,
+ hugepages_thp_mode_never,
+ hugepages_thp_mode_not_supported
+};
+
+enum hugepages_thp_mode_t __hugepages_thp_mode (void) attribute_hidden;
+
+#endif /* _HUGEPAGES_H */
diff --git a/sysdeps/generic/malloc-hugepages.c b/sysdeps/generic/malloc-hugepages.c
index 57b82a2438..2a64a6596c 100644
--- a/sysdeps/generic/malloc-hugepages.c
+++ b/sysdeps/generic/malloc-hugepages.c
@@ -1,4 +1,4 @@
-/* Huge Page support. Generic implementation.
+/* Malloc huge Page support. Generic implementation.
Copyright (C) 2021-2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -24,12 +24,6 @@ __malloc_default_thp_pagesize (void)
return 0;
}
-enum malloc_thp_mode_t
-__malloc_thp_mode (void)
-{
- return malloc_thp_mode_not_supported;
-}
-
/* Return the default transparent huge page size. */
void
__malloc_hugepage_config (size_t requested, size_t *pagesize, int *flags)
diff --git a/sysdeps/generic/malloc-hugepages.h b/sysdeps/generic/malloc-hugepages.h
index ab2690f7b8..7dcab39047 100644
--- a/sysdeps/generic/malloc-hugepages.h
+++ b/sysdeps/generic/malloc-hugepages.h
@@ -20,20 +20,11 @@
#define _MALLOC_HUGEPAGES_H
#include <stddef.h>
+#include <hugepages.h>
/* Return the default transparent huge page size. */
unsigned long int __malloc_default_thp_pagesize (void) attribute_hidden;
-enum malloc_thp_mode_t
-{
- malloc_thp_mode_always,
- malloc_thp_mode_madvise,
- malloc_thp_mode_never,
- malloc_thp_mode_not_supported
-};
-
-enum malloc_thp_mode_t __malloc_thp_mode (void) attribute_hidden;
-
/* Return the supported huge page size from the REQUESTED sizes on PAGESIZE
along with the required extra mmap flags on FLAGS, Requesting the value
of 0 returns the default huge page size, otherwise the value will be
@@ -41,8 +32,8 @@ enum malloc_thp_mode_t __malloc_thp_mode (void) attribute_hidden;
void __malloc_hugepage_config (size_t requested, size_t *pagesize, int *flags)
attribute_hidden;
-#ifndef DEFAULT_THP_PAGESIZE
-# define DEFAULT_THP_PAGESIZE 0
+#ifndef MALLOC_DEFAULT_THP_PAGESIZE
+# define MALLOC_DEFAULT_THP_PAGESIZE 0
#endif
#endif /* _MALLOC_HUGEPAGES_H */
diff --git a/sysdeps/unix/sysv/linux/aarch64/malloc-hugepages.h b/sysdeps/unix/sysv/linux/aarch64/malloc-hugepages.h
index 2204112e4e..55f913b5d3 100644
--- a/sysdeps/unix/sysv/linux/aarch64/malloc-hugepages.h
+++ b/sysdeps/unix/sysv/linux/aarch64/malloc-hugepages.h
@@ -16,6 +16,6 @@
License along with the GNU C Library; see the file COPYING.LIB. If
not, see <https://www.gnu.org/licenses/>. */
-#define DEFAULT_THP_PAGESIZE (1UL << 21)
+#define MALLOC_DEFAULT_THP_PAGESIZE (1UL << 21)
#include_next <malloc-hugepages.h>
diff --git a/sysdeps/unix/sysv/linux/hugepages.c b/sysdeps/unix/sysv/linux/hugepages.c
new file mode 100644
index 0000000000..20ddca343f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hugepages.c
@@ -0,0 +1,77 @@
+/* Huge Page support. Linux implementation.
+ Copyright (C) 2021-2026 Free Software Foundation, Inc.
+ 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; see the file COPYING.LIB. If
+ not, see <https://www.gnu.org/licenses/>. */
+
+#include <hugepages.h>
+#include <intprops.h>
+#include <not-cancel.h>
+
+unsigned long int
+__hugepages_default_thp_pagesize (void)
+{
+ int fd = __open64_nocancel (
+ "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", O_RDONLY);
+ if (fd == -1)
+ return 0;
+
+ char str[INT_BUFSIZE_BOUND (unsigned long int)];
+ ssize_t s = __read_nocancel (fd, str, sizeof (str));
+ __close_nocancel (fd);
+ if (s < 0)
+ return 0;
+
+ unsigned long int r = 0;
+ for (ssize_t i = 0; i < s; i++)
+ {
+ if (str[i] == '\n')
+ break;
+ r *= 10;
+ r += str[i] - '0';
+ }
+ return r;
+}
+
+enum hugepages_thp_mode_t
+__hugepages_thp_mode (void)
+{
+ int fd = __open64_nocancel ("/sys/kernel/mm/transparent_hugepage/enabled",
+ O_RDONLY);
+ if (fd == -1)
+ return hugepages_thp_mode_not_supported;
+
+ static const char mode_always[] = "[always] madvise never\n";
+ static const char mode_madvise[] = "always [madvise] never\n";
+ static const char mode_never[] = "always madvise [never]\n";
+
+ char str[sizeof(mode_always)];
+ ssize_t s = __read_nocancel (fd, str, sizeof (str));
+ if (s >= sizeof str || s < 0)
+ return hugepages_thp_mode_not_supported;
+ str[s] = '\0';
+ __close_nocancel (fd);
+
+ if (s == sizeof (mode_always) - 1)
+ {
+ if (strcmp (str, mode_always) == 0)
+ return hugepages_thp_mode_always;
+ else if (strcmp (str, mode_madvise) == 0)
+ return hugepages_thp_mode_madvise;
+ else if (strcmp (str, mode_never) == 0)
+ return hugepages_thp_mode_never;
+ }
+ return hugepages_thp_mode_not_supported;
+}
diff --git a/sysdeps/unix/sysv/linux/malloc-hugepages.c b/sysdeps/unix/sysv/linux/malloc-hugepages.c
index 77b49374e6..d0b2c53740 100644
--- a/sysdeps/unix/sysv/linux/malloc-hugepages.c
+++ b/sysdeps/unix/sysv/linux/malloc-hugepages.c
@@ -1,4 +1,4 @@
-/* Huge Page support. Linux implementation.
+/* Malloc huge Page support. Linux implementation.
Copyright (C) 2021-2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,7 +16,6 @@
License along with the GNU C Library; see the file COPYING.LIB. If
not, see <https://www.gnu.org/licenses/>. */
-#include <intprops.h>
#include <dirent.h>
#include <malloc-hugepages.h>
#include <not-cancel.h>
@@ -25,60 +24,10 @@
unsigned long int
__malloc_default_thp_pagesize (void)
{
- if (DEFAULT_THP_PAGESIZE != 0)
- return DEFAULT_THP_PAGESIZE;
+ if (MALLOC_DEFAULT_THP_PAGESIZE != 0)
+ return MALLOC_DEFAULT_THP_PAGESIZE;
- int fd = __open64_nocancel (
- "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", O_RDONLY);
- if (fd == -1)
- return 0;
-
- char str[INT_BUFSIZE_BOUND (unsigned long int)];
- ssize_t s = __read_nocancel (fd, str, sizeof (str));
- __close_nocancel (fd);
- if (s < 0)
- return 0;
-
- unsigned long int r = 0;
- for (ssize_t i = 0; i < s; i++)
- {
- if (str[i] == '\n')
- break;
- r *= 10;
- r += str[i] - '0';
- }
- return r;
-}
-
-enum malloc_thp_mode_t
-__malloc_thp_mode (void)
-{
- int fd = __open64_nocancel ("/sys/kernel/mm/transparent_hugepage/enabled",
- O_RDONLY);
- if (fd == -1)
- return malloc_thp_mode_not_supported;
-
- static const char mode_always[] = "[always] madvise never\n";
- static const char mode_madvise[] = "always [madvise] never\n";
- static const char mode_never[] = "always madvise [never]\n";
-
- char str[sizeof(mode_always)];
- ssize_t s = __read_nocancel (fd, str, sizeof (str));
- if (s >= sizeof str || s < 0)
- return malloc_thp_mode_not_supported;
- str[s] = '\0';
- __close_nocancel (fd);
-
- if (s == sizeof (mode_always) - 1)
- {
- if (strcmp (str, mode_always) == 0)
- return malloc_thp_mode_always;
- else if (strcmp (str, mode_madvise) == 0)
- return malloc_thp_mode_madvise;
- else if (strcmp (str, mode_never) == 0)
- return malloc_thp_mode_never;
- }
- return malloc_thp_mode_not_supported;
+ return __hugepages_default_thp_pagesize ();
}
static size_t
--
2.53.0
More information about the Libc-alpha
mailing list