From patchwork Thu May 21 18:00:05 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 135419 X-Patchwork-Delegate: dj@redhat.com Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 03D8848F8E35 for ; Thu, 21 May 2026 18:00:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 03D8848F8E35 Authentication-Results: sourceware.org; dkim=fail reason="signature verification failed" (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=IxOU0iuM X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-vk1-xa36.google.com (mail-vk1-xa36.google.com [IPv6:2607:f8b0:4864:20::a36]) by sourceware.org (Postfix) with ESMTPS id 813B34BAD170 for ; Thu, 21 May 2026 18:00:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 813B34BAD170 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 813B34BAD170 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::a36 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1779386420; cv=none; b=oKlCMpXujZIiZ34AaJ9akZPlnkWDzqsQ7GpO/BDf1R4Uq1pxU/TOeg0MET3OFZwEoI1lxx/dy4yAtBPozAeIMTe/f/udK1fyxgS1GoNC5DVfB+Q/TpBEvDPtC/NStotZS2ufHGUPk0g6XhScxbTOQOURbVK/1IGr78zZ+bW1C3U= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1779386420; c=relaxed/simple; bh=abrjvuLfW9B0h5+QlnWy4iXwD1SZ2LRpWBQx1KgKSLo=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=DcJMLFYAtlRVqWXHqYiBuPheJ/IcgFEMkmvImy5UJZmllKKjXlH1CAqfhachAieBILfov+msqPPn+KZpzml1EdFaGKFC62ZR58p6BckfjWfFzRdjfNIZur6dsApLOHKPvaDD6SHJ+IFHCQXE9EXDgN465gO8oHbLzeZhtEFfDWE= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=IxOU0iuM DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 813B34BAD170 Received: by mail-vk1-xa36.google.com with SMTP id 71dfb90a1353d-5774680983dso2213139e0c.0 for ; Thu, 21 May 2026 11:00:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1779386420; x=1779991220; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=5mAq704khYuWGT2vwGIpJmkkSh4jZA5i607pkA7OWzc=; b=IxOU0iuMa/l8kcrBkgIvZ76MtjwXKnJdsT0CrUU+5OPgECjJij5UhDfAoSNRlRM/2Q N6vBwZMBxPjvUbm1k1HyCl4/YutCzkh6iD2WZmC5T52E5uMOOnJtVnjyvCVfsWsjDien P/wuhjQypZLZYb2vTeHveSlrwJEqRU9otj8L0c1+mcrPmx11h/+FhFUSUNIPQU6L2sq6 LmdC2BRxVyMFEZy2pxFX0wpt5jgncWO+gfd+2D29miF/fNIVy5LflQsrhl7lHbS6yEK3 ZWNvbjbD40hHvJh5Kts/MuZThHoqDUVdWmPqFRQnXxyzcBKwcIHNum/2n+7uHDfyhbhl 4MHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779386420; x=1779991220; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=5mAq704khYuWGT2vwGIpJmkkSh4jZA5i607pkA7OWzc=; b=iFu4U7h6YJZF25eHOnSXPJLkXBMcCVOZljuzs+Hf/uIpXTLZy8cqiamTeCIUSEJyCr sD2hg1ZOO9GEV46rvwzmU2tsOYfzjs8pFmfWtvT8YHfKq0vMSP3xwvvg1y6trWM91Wtx ZIF7dEL4w37rID0t8tQmKFq6BQVi/kc/TwMaF11tjejZam7Vq1BdeRrl+y7Wvivi2wN7 H0StzBBu73iyHkfohDToC+irctSjU5Ocbd9RtHiA/bAWgUVVy1iY9MMWlbIgPDAaHAap NPTfPdSWwRqw2LgTs1Jq8Xu6e7le7XgQ9TT/3HrQiUEEZtN6iw+iVSiSrTWYL1FGYR7i vV7w== X-Gm-Message-State: AOJu0YwOjU+LcPIXVLZJOfAbuCMiq7EEWQUR0x12xFd+HiWw1ZueU4uK ISEy47L8euKjphx15arGhbSjJKya/b0G64if9ihz4ajkF/Ollkg1QKp1tW1ho/eo7NZqFAVTQBX 5QnW7 X-Gm-Gg: Acq92OFdSWlvJ3A0+YYRXmxvIM5E4GoT0uCHWqTeUTtT+9O6IwyIt5xsxr9vicKOW35 vhhYNUIgnZyk3qhQZVArbT57b6DQbnJ1MXI9G9EWHPis7c0b+QDn4lpzurqeV7cc7xppsTWk7hO XYO8gR6HUpfyYK5AjGADZ8M4uGeLRutka9gubSy62XPr5XkDijwTYIy53W5VSydw+h+YjJLeQFW 9pDyguSaERCqFa2nU6P4+t2XmlUW9M/YPDGJfj4HFbiVFfkJIeO7rm4NzNn2Gh5ybz3Yq6Tj4e1 8jTxbQtp1opksbLkYTIKt5jMu325D7v+tnCfpM4NbobL+EPLvOMzNIs/w9iJyYSPOqxbHr7FfCP YpqVSyVTb+rzNUNrbk4wwvCJZIidxXgCcJXWwba29g8kJhV/znLHJFFH5yemPrsE3BYNDxBmFB5 ZOPb7JrX/S+N+IJd8i6T5VrGMraEE8VKY1HJYxtO2aUwtCeQ== X-Received: by 2002:a05:6122:f84:b0:56b:8023:b89e with SMTP id 71dfb90a1353d-5865fcf7d81mr209013e0c.6.1779386416068; Thu, 21 May 2026 11:00:16 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c2:8e05:db98:a853:cbb9:9367]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-5856d716ecdsm1658834e0c.2.2026.05.21.11.00.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 May 2026 11:00:15 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH] support: Skip malloc hugetlb={1, 2} variants when kernel cannot honor them Date: Thu, 21 May 2026 15:00:05 -0300 Message-ID: <20260521180012.578058-1-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org The malloc test variants run with GLIBC_TUNABLES=glibc.malloc.hugetlb=1 exercise transparent huge pages via MADV_HUGEPAGE, which is only meaningful when /sys/kernel/mm/transparent_hugepage/enabled is set to 'madvise' ('always' makes the madvise redundant and 'never' makes it ineffective). The hugetlb=2 variants rely on MAP_HUGETLB, which requires a positive /proc/sys/vm/nr_hugepages. On systems that do not satisfy these prerequisites - including any non-Linux target - those runs only consume CPU time in this case. Add support/support_check_hugetlb.{c,h} exposing: - support_thp_is_madvise: true iff THP is in 'madvise' mode; - support_hugepages_reserved: true iff nr_hugepages > 0; - support_check_malloc_hugetlb: inspects GLIBC_TUNABLES and calls FAIL_UNSUPPORTED when the requested hugetlb mode cannot be honored. Gate the check at compile time so only the variant binaries pay for it. --- Rules | 6 +- malloc/Makefile | 13 +++++ support/Makefile | 1 + support/support_check_hugetlb.c | 99 +++++++++++++++++++++++++++++++++ support/support_check_hugetlb.h | 48 ++++++++++++++++ support/test-driver.c | 10 ++++ 6 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 support/support_check_hugetlb.c create mode 100644 support/support_check_hugetlb.h diff --git a/Rules b/Rules index 64a337b2656..385246f07df 100644 --- a/Rules +++ b/Rules @@ -288,7 +288,8 @@ $(addprefix $(objpfx),$(binaries-malloc-check-tests)): %-malloc-check: %.o \ 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) @@ -296,7 +297,8 @@ $(addprefix $(objpfx),$(binaries-malloc-hugetlb1-tests)): %-malloc-hugetlb1: %.o 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) diff --git a/malloc/Makefile b/malloc/Makefile index f95bca7f8fa..72aa77af206 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -351,6 +351,19 @@ $(objpfx)%-threaded-worker.o: CPPFLAGS += -DTEST_IN_THREAD=TEST_THREAD_WORKER $(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 diff --git a/support/Makefile b/support/Makefile index 3f19a98bdc4..87eeb8199f6 100644 --- a/support/Makefile +++ b/support/Makefile @@ -55,6 +55,7 @@ libsupport-routines = \ support_can_chroot \ support_capture_subprocess \ support_capture_subprocess_check \ + support_check_hugetlb \ support_check_nss \ support_check_stat_fd \ support_check_stat_path \ diff --git a/support/support_check_hugetlb.c b/support/support_check_hugetlb.c new file mode 100644 index 00000000000..ef466a3124d --- /dev/null +++ b/support/support_check_hugetlb.c @@ -0,0 +1,99 @@ +/* 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 + . */ + +#include + +#include +#include +#include +#include + +bool +support_thp_is_madvise (void) +{ +#ifdef __linux__ + FILE *fp = fopen ("/sys/kernel/mm/transparent_hugepage/enabled", "r"); + if (fp == NULL) + return false; + char line[256]; + bool madvise = false; + if (fgets (line, sizeof (line), fp) != NULL) + madvise = strstr (line, "[madvise]") != NULL; + fclose (fp); + return madvise; +#else + return false; +#endif +} + +bool +support_hugepages_reserved (void) +{ +#ifdef __linux__ + FILE *fp = fopen ("/proc/sys/vm/nr_hugepages", "r"); + if (fp == NULL) + return false; + unsigned long n = 0; + bool any = fscanf (fp, "%lu", &n) == 1 && n > 0; + fclose (fp); + return any; +#else + return false; +#endif +} + +/* Returns true if TUNABLES (a GLIBC_TUNABLES-style colon-separated list) + contains an entry of the form NAME=VALUE. */ +static bool +tunable_equals (const char *tunables, const char *name, const char *value) +{ + size_t name_len = strlen (name); + size_t value_len = strlen (value); + const char *p = tunables; + while (*p != '\0') + { + if (strncmp (p, name, name_len) == 0 + && p[name_len] == '=' + && strncmp (p + name_len + 1, value, value_len) == 0 + && (p[name_len + 1 + value_len] == '\0' + || p[name_len + 1 + value_len] == ':')) + return true; + const char *colon = strchr (p, ':'); + if (colon == NULL) + break; + p = colon + 1; + } + return false; +} + +void +support_check_malloc_hugetlb (void) +{ + const char *tunables = getenv ("GLIBC_TUNABLES"); + if (tunables == NULL) + return; + if (tunable_equals (tunables, "glibc.malloc.hugetlb", "1") + && !support_thp_is_madvise ()) + FAIL_UNSUPPORTED ("glibc.malloc.hugetlb=1 requires" + " /sys/kernel/mm/transparent_hugepage/enabled" + " = madvise"); + if (tunable_equals (tunables, "glibc.malloc.hugetlb", "2") + && !support_hugepages_reserved ()) + FAIL_UNSUPPORTED ("glibc.malloc.hugetlb=2 requires" + " /proc/sys/vm/nr_hugepages > 0"); +} diff --git a/support/support_check_hugetlb.h b/support/support_check_hugetlb.h new file mode 100644 index 00000000000..2c5f5cb80cc --- /dev/null +++ b/support/support_check_hugetlb.h @@ -0,0 +1,48 @@ +/* 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 + . */ + +#ifndef SUPPORT_SUPPORT_CHECK_HUGETLB_H +#define SUPPORT_SUPPORT_CHECK_HUGETLB_H + +#include +#include + +__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 */ diff --git a/support/test-driver.c b/support/test-driver.c index 14555846671..a72c41e64c7 100644 --- a/support/test-driver.c +++ b/support/test-driver.c @@ -103,9 +103,19 @@ #include +#ifdef TEST_HUGETLB +# include +#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));