endif
ifneq "$(strip $(binaries-malloc-hugetlb1-tests))" ""
-$(addprefix $(objpfx),$(binaries-malloc-hugetlb1-tests)): %-malloc-hugetlb1: %.o \
+$(addprefix $(objpfx),$(binaries-malloc-hugetlb1-tests)): \
+%-malloc-hugetlb1: %-malloc-hugetlb1.o \
$(link-extra-libs-tests) \
$(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
$(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
endif
ifneq "$(strip $(binaries-malloc-hugetlb2-tests))" ""
-$(addprefix $(objpfx),$(binaries-malloc-hugetlb2-tests)): %-malloc-hugetlb2: %.o \
+$(addprefix $(objpfx),$(binaries-malloc-hugetlb2-tests)): \
+%-malloc-hugetlb2: %-malloc-hugetlb2.o \
$(link-extra-libs-tests) \
$(sort $(filter $(common-objpfx)lib%,$(link-libc))) \
$(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit)
$(objpfx)%-threaded-worker.o: %.c $(before-compile)
$(compile-command.c)
+# Compile the hugetlb={1,2} test variants from their base sources with
+# -DTEST_HUGETLB so support/test-driver.c gates them on kernel support.
+$(foreach t,$(tests-malloc-hugetlb1),\
+ $(eval libof-$(t)-malloc-hugetlb1 := testsuite))
+$(foreach t,$(tests-malloc-hugetlb2),\
+ $(eval libof-$(t)-malloc-hugetlb2 := testsuite))
+$(objpfx)%-malloc-hugetlb1.o: CPPFLAGS += -DTEST_HUGETLB
+$(objpfx)%-malloc-hugetlb1.o: %.c $(before-compile)
+ $(compile-command.c)
+$(objpfx)%-malloc-hugetlb2.o: CPPFLAGS += -DTEST_HUGETLB
+$(objpfx)%-malloc-hugetlb2.o: %.c $(before-compile)
+ $(compile-command.c)
+
# Include the cleanup handler.
aux := set-freeres thread-freeres
support_can_chroot \
support_capture_subprocess \
support_capture_subprocess_check \
+ support_check_hugetlb \
support_check_nss \
support_check_stat_fd \
support_check_stat_path \
--- /dev/null
+/* Runtime detection of huge-page support for malloc tests.
+ Copyright (C) 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; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <fcntl.h>
+#include <intprops.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <elf/dl-tunables.h>
+#include <support/support_check_hugetlb.h>
+#include <support/check.h>
+
+bool
+support_thp_is_madvise (void)
+{
+ int fd = open ("/sys/kernel/mm/transparent_hugepage/enabled", O_RDONLY);
+ if (fd == -1)
+ return false;
+
+#define MODE_MADVISE "always [madvise] never\n"
+
+ char str[sizeof(MODE_MADVISE)];
+ ssize_t s = read (fd, str, sizeof (str));
+ close (fd);
+ if (s != sizeof (str) - 1)
+ return false;
+ str[s] = '\0';
+ return strcmp (str, MODE_MADVISE) == 0;
+}
+
+bool
+support_hugepages_reserved (void)
+{
+ int fd = open ("/proc/sys/vm/nr_hugepages", O_RDONLY);
+ if (fd == -1)
+ return false;
+
+ char str[INT_BUFSIZE_BOUND(unsigned long int)];
+ ssize_t s = read (fd, str, sizeof (str));
+ close (fd);
+ if (s >= sizeof str || s < 0)
+ return false;
+ str[s] = '\0';
+ unsigned long int n = 0;
+ return sscanf (str, "%lu", &n) == 1 && n > 0;
+}
+
+void
+support_check_malloc_hugetlb (void)
+{
+ if (!TUNABLE_IS_INITIALIZED (glibc, malloc, hugetlb))
+ return;
+
+ size_t hugetlb = TUNABLE_GET_FULL (glibc, malloc, hugetlb, size_t, NULL);
+ if (hugetlb == 1 && !support_thp_is_madvise ())
+ FAIL_UNSUPPORTED ("glibc.malloc.hugetlb=1 requires"
+ " /sys/kernel/mm/transparent_hugepage/enabled"
+ " = madvise");
+ if (hugetlb == 2 && !support_hugepages_reserved ())
+ FAIL_UNSUPPORTED ("glibc.malloc.hugetlb=2 requires"
+ " /proc/sys/vm/nr_hugepages > 0");
+}
--- /dev/null
+/* Runtime detection of huge-page support for malloc tests.
+ Copyright (C) 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; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef SUPPORT_SUPPORT_CHECK_HUGETLB_H
+#define SUPPORT_SUPPORT_CHECK_HUGETLB_H
+
+#include <stdbool.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/* Returns true if /sys/kernel/mm/transparent_hugepage/enabled selects
+ `madvise' as the active mode (i.e. MADV_HUGEPAGE is honored, but
+ THP is not applied automatically). Returns false on any other
+ configuration, on read failure, or on non-Linux systems. */
+bool support_thp_is_madvise (void);
+
+/* Returns true if /proc/sys/vm/nr_hugepages reports a strictly
+ positive number of pre-allocated huge pages (the prerequisite for
+ MAP_HUGETLB allocations). Returns false on read failure or on
+ non-Linux systems. */
+bool support_hugepages_reserved (void);
+
+/* If the current process is running with GLIBC_TUNABLES requesting
+ glibc.malloc.hugetlb=1 or glibc.malloc.hugetlb=2, verifies that the
+ kernel can actually satisfy the requested mode. If not, terminates
+ the test with EXIT_UNSUPPORTED. No-op when no such tunable is set,
+ so it is safe to call unconditionally. */
+void support_check_malloc_hugetlb (void);
+
+__END_DECLS
+
+#endif /* SUPPORT_SUPPORT_CHECK_HUGETLB_H */
#include <string.h>
+#ifdef TEST_HUGETLB
+# include <support/support_check_hugetlb.h>
+#endif
+
int
main (int argc, char **argv)
{
+#ifdef TEST_HUGETLB
+ /* For malloc hugetlb=1/=2 test variants: skip the test (UNSUPPORTED)
+ when the kernel cannot honor the requested mode. */
+ support_check_malloc_hugetlb ();
+#endif
+
struct test_config test_config;
memset (&test_config, 0, sizeof (test_config));