[PATCH] selftests/mm: make libnuma-dependent tests optional

From: Jiangshan Yi

Date: Thu Jul 30 2026 - 10:53:38 EST


The mm selftests Makefile unconditionally builds three test binaries
that depend on libnuma (migration, ksm_tests, rmap). When libnuma-dev
is not installed, the build fails with a hard error, inconsistent with
how the optional liburing dependency is already handled via
check_config.sh.

These three tests hard-depend on libnuma at both compile time
(#include <numa.h>) and link time (-lnuma), confirmed by grepping all
.c files under tools/testing/selftests/mm/ for numa.h/numaif.h, which
matches exactly ksm_tests.c, migration.c, and rmap.c.

Extend check_config.sh to probe for libnuma via a compile-plus-link
check (the link check needs a main() symbol), gate the three tests in
TEST_GEN_FILES behind NUMA_EXTRA_LIBS, and print a warning when
libnuma is missing. The liburing section is switched from ">" to ">>"
writes and both output files are truncated once at the top, so the new
libnuma section can append without overwriting the liburing section.

Signed-off-by: Jiangshan Yi <yijiangshan@xxxxxxxxxx>
---
tools/testing/selftests/mm/Makefile | 21 +++++++++--
tools/testing/selftests/mm/check_config.sh | 44 +++++++++++++++++++---
2 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
index e6df968f0971..235c8ec788a7 100644
--- a/tools/testing/selftests/mm/Makefile
+++ b/tools/testing/selftests/mm/Makefile
@@ -75,7 +75,9 @@ ifneq (,$(filter $(ARCH),arm64 riscv riscv64 x86 x86_64 loongarch32 loongarch64)
TEST_GEN_FILES += memfd_secret
endif
TEST_GEN_FILES += memory-failure
+ifneq ($(NUMA_EXTRA_LIBS),)
TEST_GEN_FILES += migration
+endif
TEST_GEN_FILES += mkdirty
TEST_GEN_FILES += mlock-random-test
TEST_GEN_FILES += mlock2-tests
@@ -94,7 +96,9 @@ TEST_GEN_FILES += uffd-stress
TEST_GEN_FILES += uffd-unit-tests
TEST_GEN_FILES += uffd-wp-mremap
TEST_GEN_FILES += split_huge_page_test
+ifneq ($(NUMA_EXTRA_LIBS),)
TEST_GEN_FILES += ksm_tests
+endif
TEST_GEN_FILES += ksm_functional_tests
TEST_GEN_FILES += mdwe_test
TEST_GEN_FILES += hugetlb_fault_after_madv
@@ -103,7 +107,9 @@ TEST_GEN_FILES += hugetlb_dio
TEST_GEN_FILES += droppable
TEST_GEN_FILES += guard-regions
TEST_GEN_FILES += merge
+ifneq ($(NUMA_EXTRA_LIBS),)
TEST_GEN_FILES += rmap
+endif
TEST_GEN_FILES += folio_split_race_test

ifneq ($(ARCH),arm64)
@@ -256,11 +262,11 @@ $(OUTPUT)/gup_longterm: LDLIBS += $(IOURING_EXTRA_LIBS)

$(OUTPUT)/mlock-random-test $(OUTPUT)/memfd_secret: LDLIBS += -lcap

-$(OUTPUT)/ksm_tests: LDLIBS += -lnuma
+$(OUTPUT)/ksm_tests: LDLIBS += $(NUMA_EXTRA_LIBS)

-$(OUTPUT)/migration: LDLIBS += -lnuma
+$(OUTPUT)/migration: LDLIBS += $(NUMA_EXTRA_LIBS)

-$(OUTPUT)/rmap: LDLIBS += -lnuma
+$(OUTPUT)/rmap: LDLIBS += $(NUMA_EXTRA_LIBS)

local_config.mk local_config.h: check_config.sh
$(call msg,CHK,config,$@)
@@ -277,6 +283,15 @@ warn_missing_liburing:
echo
endif

+ifeq ($(NUMA_EXTRA_LIBS),)
+all: warn_missing_libnuma
+
+warn_missing_libnuma:
+ @echo ; \
+ echo "Warning: missing libnuma support. Some tests (migration, ksm_tests, rmap) will be skipped." ; \
+ echo
+endif
+
ifneq ($(PAGE_FRAG_WARNING),)
all: warn_missing_page_frag

diff --git a/tools/testing/selftests/mm/check_config.sh b/tools/testing/selftests/mm/check_config.sh
index 32beaefe279e..8e6d1616561b 100755
--- a/tools/testing/selftests/mm/check_config.sh
+++ b/tools/testing/selftests/mm/check_config.sh
@@ -7,10 +7,17 @@
OUTPUT_H_FILE=local_config.h
OUTPUT_MKFILE=local_config.mk

+# Truncate output files so that re-running this script does not
+# accumulate duplicate content (all writes below use append ">>").
+: > $OUTPUT_H_FILE
+: > $OUTPUT_MKFILE
+
tmpname=$(mktemp)
tmpfile_c=${tmpname}.c
tmpfile_o=${tmpname}.o

+trap 'rm -f ${tmpname} ${tmpname}.*' EXIT
+
# liburing
echo "#include <sys/types.h>" > $tmpfile_c
echo "#include <liburing.h>" >> $tmpfile_c
@@ -19,12 +26,39 @@ echo "int func(void) { return 0; }" >> $tmpfile_c
$CC $CFLAGS -c $tmpfile_c -o $tmpfile_o >/dev/null 2>&1

if [ -f $tmpfile_o ]; then
- echo "#define LOCAL_CONFIG_HAVE_LIBURING 1" > $OUTPUT_H_FILE
- echo "IOURING_EXTRA_LIBS = -luring" > $OUTPUT_MKFILE
+ echo "#define LOCAL_CONFIG_HAVE_LIBURING 1" >> $OUTPUT_H_FILE
+ echo "IOURING_EXTRA_LIBS = -luring" >> $OUTPUT_MKFILE
else
- echo "// No liburing support found" > $OUTPUT_H_FILE
- echo "# No liburing support found, so:" > $OUTPUT_MKFILE
+ echo "// No liburing support found" >> $OUTPUT_H_FILE
+ echo "# No liburing support found, so:" >> $OUTPUT_MKFILE
echo "IOURING_EXTRA_LIBS = " >> $OUTPUT_MKFILE
fi

-rm ${tmpname}.*
+rm -f $tmpfile_o
+
+# libnuma
+echo "#include <numa.h>" > $tmpfile_c
+echo "#include <numaif.h>" >> $tmpfile_c
+echo "int func(void) { return 0; }" >> $tmpfile_c
+echo "int main(void) { return 0; }" >> $tmpfile_c
+
+$CC $CFLAGS -c $tmpfile_c -o $tmpfile_o >/dev/null 2>&1
+
+if [ -f $tmpfile_o ]; then
+ tmplink=${tmpname}.bin
+ # Also check linking, not just compilation, because <numa.h> may be
+ # available without the shared library (libnuma-dev vs libnuma)
+ if $CC $CFLAGS $tmpfile_c -o $tmplink -lnuma >/dev/null 2>&1; then
+ echo "#define LOCAL_CONFIG_HAVE_LIBNUMA 1" >> $OUTPUT_H_FILE
+ echo "NUMA_EXTRA_LIBS = -lnuma" >> $OUTPUT_MKFILE
+ else
+ echo "// No libnuma support found" >> $OUTPUT_H_FILE
+ echo "# No libnuma support found, so:" >> $OUTPUT_MKFILE
+ echo "NUMA_EXTRA_LIBS = " >> $OUTPUT_MKFILE
+ fi
+else
+ echo "// No libnuma support found" >> $OUTPUT_H_FILE
+ echo "# No libnuma support found, so:" >> $OUTPUT_MKFILE
+ echo "NUMA_EXTRA_LIBS = " >> $OUTPUT_MKFILE
+fi
+
--
2.25.1