Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kunit: unify module and builtin suite definitions

Currently, KUnit runs built-in tests and tests loaded from modules
differently. For built-in tests, the kunit_test_suite{,s}() macro adds a
list of suites in the .kunit_test_suites linker section. However, for
kernel modules, a module_init() function is used to run the test suites.

This causes problems if tests are included in a module which already
defines module_init/exit_module functions, as they'll conflict with the
kunit-provided ones.

This change removes the kunit-defined module inits, and instead parses
the kunit tests from their own section in the module. After module init,
we call __kunit_test_suites_init() on the contents of that section,
which prepares and runs the suite.

This essentially unifies the module- and non-module kunit init formats.

Tested-by: Maíra Canal <maira.canal@usp.br>
Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
Signed-off-by: Daniel Latypov <dlatypov@google.com>
Signed-off-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>

authored by

Jeremy Kerr and committed by
Shuah Khan
3d6e4462 8370b400

+68 -44
+6 -43
include/kunit/test.h
··· 250 250 } 251 251 #endif /* IS_BUILTIN(CONFIG_KUNIT) */ 252 252 253 - #ifdef MODULE 254 - /** 255 - * kunit_test_suites_for_module() - used to register one or more 256 - * &struct kunit_suite with KUnit. 257 - * 258 - * @__suites: a statically allocated list of &struct kunit_suite. 259 - * 260 - * Registers @__suites with the test framework. See &struct kunit_suite for 261 - * more information. 262 - * 263 - * If a test suite is built-in, module_init() gets translated into 264 - * an initcall which we don't want as the idea is that for builtins 265 - * the executor will manage execution. So ensure we do not define 266 - * module_{init|exit} functions for the builtin case when registering 267 - * suites via kunit_test_suites() below. 268 - */ 269 - #define kunit_test_suites_for_module(__suites) \ 270 - static int __init kunit_test_suites_init(void) \ 271 - { \ 272 - return __kunit_test_suites_init(__suites); \ 273 - } \ 274 - module_init(kunit_test_suites_init); \ 275 - \ 276 - static void __exit kunit_test_suites_exit(void) \ 277 - { \ 278 - return __kunit_test_suites_exit(__suites); \ 279 - } \ 280 - module_exit(kunit_test_suites_exit) \ 281 - MODULE_INFO(test, "Y"); 282 - #else 283 - #define kunit_test_suites_for_module(__suites) 284 - #endif /* MODULE */ 285 - 286 253 #define __kunit_test_suites(unique_array, unique_suites, ...) \ 254 + MODULE_INFO(test, "Y"); \ 287 255 static struct kunit_suite *unique_array[] = { __VA_ARGS__, NULL }; \ 288 - kunit_test_suites_for_module(unique_array); \ 289 256 static struct kunit_suite **unique_suites \ 290 257 __used __section(".kunit_test_suites") = unique_array 291 258 ··· 262 295 * 263 296 * @__suites: a statically allocated list of &struct kunit_suite. 264 297 * 265 - * Registers @suites with the test framework. See &struct kunit_suite for 266 - * more information. 298 + * Registers @suites with the test framework. 299 + * This is done by placing the array of struct kunit_suite * in the 300 + * .kunit_test_suites ELF section. 267 301 * 268 - * When builtin, KUnit tests are all run via executor; this is done 269 - * by placing the array of struct kunit_suite * in the .kunit_test_suites 270 - * ELF section. 271 - * 272 - * An alternative is to build the tests as a module. Because modules do not 273 - * support multiple initcall()s, we need to initialize an array of suites for a 274 - * module. 302 + * When builtin, KUnit tests are all run via the executor at boot, and when 303 + * built as a module, they run on module load. 275 304 * 276 305 */ 277 306 #define kunit_test_suites(__suites...) \
+5
include/linux/module.h
··· 505 505 int num_static_call_sites; 506 506 struct static_call_site *static_call_sites; 507 507 #endif 508 + #if IS_ENABLED(CONFIG_KUNIT) 509 + int num_kunit_suites; 510 + struct kunit_suite ***kunit_suites; 511 + #endif 512 + 508 513 509 514 #ifdef CONFIG_LIVEPATCH 510 515 bool klp; /* Is this a livepatch module? */
+6
kernel/module/main.c
··· 2094 2094 sizeof(*mod->static_call_sites), 2095 2095 &mod->num_static_call_sites); 2096 2096 #endif 2097 + #ifdef CONFIG_KUNIT 2098 + mod->kunit_suites = section_objs(info, ".kunit_test_suites", 2099 + sizeof(*mod->kunit_suites), 2100 + &mod->num_kunit_suites); 2101 + #endif 2102 + 2097 2103 mod->extable = section_objs(info, "__ex_table", 2098 2104 sizeof(*mod->extable), &mod->num_exentries); 2099 2105
+51 -1
lib/kunit/test.c
··· 10 10 #include <kunit/test.h> 11 11 #include <kunit/test-bug.h> 12 12 #include <linux/kernel.h> 13 + #include <linux/module.h> 13 14 #include <linux/moduleparam.h> 14 15 #include <linux/panic.h> 15 16 #include <linux/sched/debug.h> ··· 614 613 } 615 614 EXPORT_SYMBOL_GPL(__kunit_test_suites_exit); 616 615 616 + #ifdef CONFIG_MODULES 617 + static void kunit_module_init(struct module *mod) 618 + { 619 + unsigned int i; 620 + 621 + for (i = 0; i < mod->num_kunit_suites; i++) 622 + __kunit_test_suites_init(mod->kunit_suites[i]); 623 + } 624 + 625 + static void kunit_module_exit(struct module *mod) 626 + { 627 + unsigned int i; 628 + 629 + for (i = 0; i < mod->num_kunit_suites; i++) 630 + __kunit_test_suites_exit(mod->kunit_suites[i]); 631 + } 632 + 633 + static int kunit_module_notify(struct notifier_block *nb, unsigned long val, 634 + void *data) 635 + { 636 + struct module *mod = data; 637 + 638 + switch (val) { 639 + case MODULE_STATE_LIVE: 640 + kunit_module_init(mod); 641 + break; 642 + case MODULE_STATE_GOING: 643 + kunit_module_exit(mod); 644 + break; 645 + case MODULE_STATE_COMING: 646 + case MODULE_STATE_UNFORMED: 647 + break; 648 + } 649 + 650 + return 0; 651 + } 652 + 653 + static struct notifier_block kunit_mod_nb = { 654 + .notifier_call = kunit_module_notify, 655 + .priority = 0, 656 + }; 657 + #endif 658 + 617 659 struct kunit_kmalloc_array_params { 618 660 size_t n; 619 661 size_t size; ··· 751 707 static int __init kunit_init(void) 752 708 { 753 709 kunit_debugfs_init(); 754 - 710 + #ifdef CONFIG_MODULES 711 + return register_module_notifier(&kunit_mod_nb); 712 + #else 755 713 return 0; 714 + #endif 756 715 } 757 716 late_initcall(kunit_init); 758 717 759 718 static void __exit kunit_exit(void) 760 719 { 720 + #ifdef CONFIG_MODULES 721 + unregister_module_notifier(&kunit_mod_nb); 722 + #endif 761 723 kunit_debugfs_cleanup(); 762 724 } 763 725 module_exit(kunit_exit);