Skip to content

Commit 3d6e446

Browse files
jk-ozlabsshuahkh
authored andcommitted
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 <[email protected]> Reviewed-by: Brendan Higgins <[email protected]> Signed-off-by: Jeremy Kerr <[email protected]> Signed-off-by: Daniel Latypov <[email protected]> Signed-off-by: David Gow <[email protected]> Signed-off-by: Shuah Khan <[email protected]>
1 parent 8370b40 commit 3d6e446

File tree

4 files changed

+68
-44
lines changed

4 files changed

+68
-44
lines changed

include/kunit/test.h

Lines changed: 6 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -250,42 +250,9 @@ static inline int kunit_run_all_tests(void)
250250
}
251251
#endif /* IS_BUILTIN(CONFIG_KUNIT) */
252252

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-
286253
#define __kunit_test_suites(unique_array, unique_suites, ...) \
254+
MODULE_INFO(test, "Y"); \
287255
static struct kunit_suite *unique_array[] = { __VA_ARGS__, NULL }; \
288-
kunit_test_suites_for_module(unique_array); \
289256
static struct kunit_suite **unique_suites \
290257
__used __section(".kunit_test_suites") = unique_array
291258

@@ -295,16 +262,12 @@ static inline int kunit_run_all_tests(void)
295262
*
296263
* @__suites: a statically allocated list of &struct kunit_suite.
297264
*
298-
* Registers @suites with the test framework. See &struct kunit_suite for
299-
* more information.
300-
*
301-
* When builtin, KUnit tests are all run via executor; this is done
302-
* by placing the array of struct kunit_suite * in the .kunit_test_suites
303-
* ELF section.
265+
* Registers @suites with the test framework.
266+
* This is done by placing the array of struct kunit_suite * in the
267+
* .kunit_test_suites ELF section.
304268
*
305-
* An alternative is to build the tests as a module. Because modules do not
306-
* support multiple initcall()s, we need to initialize an array of suites for a
307-
* module.
269+
* When builtin, KUnit tests are all run via the executor at boot, and when
270+
* built as a module, they run on module load.
308271
*
309272
*/
310273
#define kunit_test_suites(__suites...) \

include/linux/module.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,11 @@ struct module {
505505
int num_static_call_sites;
506506
struct static_call_site *static_call_sites;
507507
#endif
508+
#if IS_ENABLED(CONFIG_KUNIT)
509+
int num_kunit_suites;
510+
struct kunit_suite ***kunit_suites;
511+
#endif
512+
508513

509514
#ifdef CONFIG_LIVEPATCH
510515
bool klp; /* Is this a livepatch module? */

kernel/module/main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,6 +2094,12 @@ static int find_module_sections(struct module *mod, struct load_info *info)
20942094
sizeof(*mod->static_call_sites),
20952095
&mod->num_static_call_sites);
20962096
#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+
20972103
mod->extable = section_objs(info, "__ex_table",
20982104
sizeof(*mod->extable), &mod->num_exentries);
20992105

lib/kunit/test.c

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <kunit/test.h>
1111
#include <kunit/test-bug.h>
1212
#include <linux/kernel.h>
13+
#include <linux/module.h>
1314
#include <linux/moduleparam.h>
1415
#include <linux/panic.h>
1516
#include <linux/sched/debug.h>
@@ -613,6 +614,49 @@ void __kunit_test_suites_exit(struct kunit_suite **suites)
613614
}
614615
EXPORT_SYMBOL_GPL(__kunit_test_suites_exit);
615616

617+
#ifdef CONFIG_MODULES
618+
static void kunit_module_init(struct module *mod)
619+
{
620+
unsigned int i;
621+
622+
for (i = 0; i < mod->num_kunit_suites; i++)
623+
__kunit_test_suites_init(mod->kunit_suites[i]);
624+
}
625+
626+
static void kunit_module_exit(struct module *mod)
627+
{
628+
unsigned int i;
629+
630+
for (i = 0; i < mod->num_kunit_suites; i++)
631+
__kunit_test_suites_exit(mod->kunit_suites[i]);
632+
}
633+
634+
static int kunit_module_notify(struct notifier_block *nb, unsigned long val,
635+
void *data)
636+
{
637+
struct module *mod = data;
638+
639+
switch (val) {
640+
case MODULE_STATE_LIVE:
641+
kunit_module_init(mod);
642+
break;
643+
case MODULE_STATE_GOING:
644+
kunit_module_exit(mod);
645+
break;
646+
case MODULE_STATE_COMING:
647+
case MODULE_STATE_UNFORMED:
648+
break;
649+
}
650+
651+
return 0;
652+
}
653+
654+
static struct notifier_block kunit_mod_nb = {
655+
.notifier_call = kunit_module_notify,
656+
.priority = 0,
657+
};
658+
#endif
659+
616660
struct kunit_kmalloc_array_params {
617661
size_t n;
618662
size_t size;
@@ -707,13 +751,19 @@ EXPORT_SYMBOL_GPL(kunit_cleanup);
707751
static int __init kunit_init(void)
708752
{
709753
kunit_debugfs_init();
710-
754+
#ifdef CONFIG_MODULES
755+
return register_module_notifier(&kunit_mod_nb);
756+
#else
711757
return 0;
758+
#endif
712759
}
713760
late_initcall(kunit_init);
714761

715762
static void __exit kunit_exit(void)
716763
{
764+
#ifdef CONFIG_MODULES
765+
unregister_module_notifier(&kunit_mod_nb);
766+
#endif
717767
kunit_debugfs_cleanup();
718768
}
719769
module_exit(kunit_exit);

0 commit comments

Comments
 (0)