summaryrefslogtreecommitdiffstats
path: root/lib/tests
diff options
context:
space:
mode:
authorLuis Chamberlain <mcgrof@kernel.org>2024-10-21 21:11:44 +0200
committerLuis Chamberlain <mcgrof@kernel.org>2024-10-24 19:14:12 +0200
commit84b4a51fce4ccc6605113ed8af41a3d91609a756 (patch)
treef8ce06db6350102984017f598c2c489d51c84604 /lib/tests
parentmodule: Reformat struct for code style (diff)
downloadlinux-84b4a51fce4ccc6605113ed8af41a3d91609a756.tar.xz
linux-84b4a51fce4ccc6605113ed8af41a3d91609a756.zip
selftests: add new kallsyms selftests
We lack find_symbol() selftests, so add one. This let's us stress test improvements easily on find_symbol() or optimizations. It also inherently allows us to test the limits of kallsyms on Linux today. We test a pathalogical use case for kallsyms by introducing modules which are automatically written for us with a larger number of symbols. We have 4 kallsyms test modules: A: has KALLSYSMS_NUMSYMS exported symbols B: uses one of A's symbols C: adds KALLSYMS_SCALE_FACTOR * KALLSYSMS_NUMSYMS exported D: adds 2 * the symbols than C By using anything much larger than KALLSYSMS_NUMSYMS as 10,000 and KALLSYMS_SCALE_FACTOR of 8 we segfault today. So we're capped at around 160000 symbols somehow today. We can inpsect that issue at our leasure later, but for now the real value to this test is that this will easily allow us to test improvements on find_symbol(). We want to enable this test on allyesmodconfig builds so we can't use this combination, so instead just use a safe value for now and be informative on the Kconfig symbol documentation about where our thresholds are for testers. We default then to KALLSYSMS_NUMSYMS of just 100 and KALLSYMS_SCALE_FACTOR of 8. On x86_64 we can use perf, for other architectures we just use 'time' and allow for customizations. For example a future enhancements could be done for parisc to check for unaligned accesses which triggers a special special exception handler assembler code inside the kernel. The negative impact on performance is so large on parisc that it keeps track of its accesses on /proc/cpuinfo as UAH: IRQ: CPU0 CPU1 3: 1332 0 SuperIO ttyS0 7: 1270013 0 SuperIO pata_ns87415 64: 320023012 320021431 CPU timer 65: 17080507 20624423 CPU IPI UAH: 10948640 58104 Unaligned access handler traps While at it, this tidies up lib/ test modules to allow us to have a new directory for them. The amount of test modules under lib/ is insane. This should also hopefully showcase how to start doing basic self module writing code, which may be more useful for more complex cases later in the future. Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
Diffstat (limited to 'lib/tests')
-rw-r--r--lib/tests/Makefile1
-rw-r--r--lib/tests/module/.gitignore4
-rw-r--r--lib/tests/module/Makefile15
-rwxr-xr-xlib/tests/module/gen_test_kallsyms.sh128
4 files changed, 148 insertions, 0 deletions
diff --git a/lib/tests/Makefile b/lib/tests/Makefile
new file mode 100644
index 000000000000..8e4f42cb9c54
--- /dev/null
+++ b/lib/tests/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TEST_RUNTIME_MODULE) += module/
diff --git a/lib/tests/module/.gitignore b/lib/tests/module/.gitignore
new file mode 100644
index 000000000000..8be7891b250f
--- /dev/null
+++ b/lib/tests/module/.gitignore
@@ -0,0 +1,4 @@
+test_kallsyms_a.c
+test_kallsyms_b.c
+test_kallsyms_c.c
+test_kallsyms_d.c
diff --git a/lib/tests/module/Makefile b/lib/tests/module/Makefile
new file mode 100644
index 000000000000..af5c27b996cb
--- /dev/null
+++ b/lib/tests/module/Makefile
@@ -0,0 +1,15 @@
+obj-$(CONFIG_TEST_KALLSYMS_A) += test_kallsyms_a.o
+obj-$(CONFIG_TEST_KALLSYMS_B) += test_kallsyms_b.o
+obj-$(CONFIG_TEST_KALLSYMS_C) += test_kallsyms_c.o
+obj-$(CONFIG_TEST_KALLSYMS_D) += test_kallsyms_d.o
+
+$(obj)/%.c: FORCE
+ @$(kecho) " GEN $@"
+ $(Q)$(srctree)/lib/tests/module/gen_test_kallsyms.sh $@\
+ $(CONFIG_TEST_KALLSYMS_NUMSYMS) \
+ $(CONFIG_TEST_KALLSYMS_SCALE_FACTOR)
+
+clean-files += test_kallsyms_a.c
+clean-files += test_kallsyms_b.c
+clean-files += test_kallsyms_c.c
+clean-files += test_kallsyms_d.c
diff --git a/lib/tests/module/gen_test_kallsyms.sh b/lib/tests/module/gen_test_kallsyms.sh
new file mode 100755
index 000000000000..e85f10dc11bd
--- /dev/null
+++ b/lib/tests/module/gen_test_kallsyms.sh
@@ -0,0 +1,128 @@
+#!/bin/bash
+
+TARGET=$(basename $1)
+DIR=lib/tests/module
+TARGET="$DIR/$TARGET"
+NUM_SYMS=$2
+SCALE_FACTOR=$3
+TEST_TYPE=$(echo $TARGET | sed -e 's|lib/tests/module/test_kallsyms_||g')
+TEST_TYPE=$(echo $TEST_TYPE | sed -e 's|.c||g')
+
+gen_template_module_header()
+{
+ cat <<____END_MODULE
+// SPDX-License-Identifier: GPL-2.0-or-later OR copyleft-next-0.3.1
+/*
+ * Copyright (C) 2023 Luis Chamberlain <mcgrof@kernel.org>
+ *
+ * Automatically generated code for testing, do not edit manually.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+
+____END_MODULE
+}
+
+gen_num_syms()
+{
+ PREFIX=$1
+ NUM=$2
+ for i in $(seq 1 $NUM); do
+ printf "int auto_test_%s_%010d = 0xff;\n" $PREFIX $i
+ printf "EXPORT_SYMBOL_GPL(auto_test_%s_%010d);\n" $PREFIX $i
+ done
+ echo
+}
+
+gen_template_module_data_a()
+{
+ gen_num_syms a $1
+ cat <<____END_MODULE
+static int auto_runtime_test(void)
+{
+ return 0;
+}
+
+____END_MODULE
+}
+
+gen_template_module_data_b()
+{
+ printf "\nextern int auto_test_a_%010d;\n\n" 28
+ echo "static int auto_runtime_test(void)"
+ echo "{"
+ printf "\nreturn auto_test_a_%010d;\n" 28
+ echo "}"
+}
+
+gen_template_module_data_c()
+{
+ gen_num_syms c $1
+ cat <<____END_MODULE
+static int auto_runtime_test(void)
+{
+ return 0;
+}
+
+____END_MODULE
+}
+
+gen_template_module_data_d()
+{
+ gen_num_syms d $1
+ cat <<____END_MODULE
+static int auto_runtime_test(void)
+{
+ return 0;
+}
+
+____END_MODULE
+}
+
+gen_template_module_exit()
+{
+ cat <<____END_MODULE
+static int __init auto_test_module_init(void)
+{
+ return auto_runtime_test();
+}
+module_init(auto_test_module_init);
+
+static void __exit auto_test_module_exit(void)
+{
+}
+module_exit(auto_test_module_exit);
+
+MODULE_AUTHOR("Luis Chamberlain <mcgrof@kernel.org>");
+MODULE_LICENSE("GPL");
+____END_MODULE
+}
+
+case $TEST_TYPE in
+ a)
+ gen_template_module_header > $TARGET
+ gen_template_module_data_a $NUM_SYMS >> $TARGET
+ gen_template_module_exit >> $TARGET
+ ;;
+ b)
+ gen_template_module_header > $TARGET
+ gen_template_module_data_b >> $TARGET
+ gen_template_module_exit >> $TARGET
+ ;;
+ c)
+ gen_template_module_header > $TARGET
+ gen_template_module_data_c $((NUM_SYMS * SCALE_FACTOR)) >> $TARGET
+ gen_template_module_exit >> $TARGET
+ ;;
+ d)
+ gen_template_module_header > $TARGET
+ gen_template_module_data_d $((NUM_SYMS * SCALE_FACTOR * 2)) >> $TARGET
+ gen_template_module_exit >> $TARGET
+ ;;
+ *)
+ ;;
+esac