2020-08-05 04:47:42 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
|
2021-05-27 05:24:04 +08:00
|
|
|
#include <linux/reboot.h>
|
2020-08-05 04:47:42 +08:00
|
|
|
#include <kunit/test.h>
|
2023-07-26 05:25:12 +08:00
|
|
|
#include <kunit/attributes.h>
|
2021-02-06 08:08:52 +08:00
|
|
|
#include <linux/glob.h>
|
|
|
|
#include <linux/moduleparam.h>
|
2020-08-05 04:47:42 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* These symbols point to the .kunit_test_suites section and are defined in
|
|
|
|
* include/asm-generic/vmlinux.lds.h, and consequently must be extern.
|
|
|
|
*/
|
2022-07-09 11:19:58 +08:00
|
|
|
extern struct kunit_suite * const __kunit_suites_start[];
|
|
|
|
extern struct kunit_suite * const __kunit_suites_end[];
|
2023-12-14 03:44:17 +08:00
|
|
|
extern struct kunit_suite * const __kunit_init_suites_start[];
|
|
|
|
extern struct kunit_suite * const __kunit_init_suites_end[];
|
2020-08-05 04:47:42 +08:00
|
|
|
|
kunit: Make 'list' action available to kunit test modules
Results from kunit tests reported via dmesg may be interleaved with other
kernel messages. When parsing dmesg for modular kunit results in real
time, external tools, e.g., Intel GPU tools (IGT), may want to insert
their own test name markers into dmesg at the start of each test, before
any kernel message related to that test appears there, so existing upper
level test result parsers have no doubt which test to blame for a specific
kernel message. Unfortunately, kunit reports names of tests only at their
completion (with the exeption of a not standarized "# Subtest: <name>"
header above a test plan of each test suite or parametrized test).
External tools could be able to insert their own "start of the test"
markers with test names included if they new those names in advance.
Test names could be learned from a list if provided by a kunit test
module.
There exists a feature of listing kunit tests without actually executing
them, but it is now limited to configurations with the kunit module built
in and covers only built-in tests, already available at boot time.
Moreover, switching from list to normal mode requires reboot. If that
feature was also available when kunit is built as a module, userspace
could load the module with action=list parameter, load some kunit test
modules they are interested in and learn about the list of tests provided
by those modules, then unload them, reload the kunit module in normal mode
and execute the tests with their lists already known.
Extend kunit module notifier initialization callback with a processing
path for only listing the tests provided by a module if the kunit action
parameter is set to "list" or "list_attr". For user convenience, make the
kunit.action parameter visible in sysfs.
v2: Don't use a different format, use kunit_exec_list_tests() (Rae),
- refresh on top of new attributes patches, handle newly introduced
kunit.action=list_attr case (Rae).
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 18:23:55 +08:00
|
|
|
static char *action_param;
|
|
|
|
|
|
|
|
module_param_named(action, action_param, charp, 0400);
|
|
|
|
MODULE_PARM_DESC(action,
|
|
|
|
"Changes KUnit executor behavior, valid values are:\n"
|
|
|
|
"<none>: run the tests like normal\n"
|
|
|
|
"'list' to list test names instead of running them.\n"
|
|
|
|
"'list_attr' to list test names and attributes instead of running them.\n");
|
|
|
|
|
|
|
|
const char *kunit_action(void)
|
|
|
|
{
|
|
|
|
return action_param;
|
|
|
|
}
|
|
|
|
|
2021-04-21 10:04:27 +08:00
|
|
|
static char *filter_glob_param;
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
static char *filter_param;
|
|
|
|
static char *filter_action_param;
|
2021-10-01 06:20:45 +08:00
|
|
|
|
2024-01-23 01:14:08 +08:00
|
|
|
module_param_named(filter_glob, filter_glob_param, charp, 0600);
|
2021-02-06 08:08:52 +08:00
|
|
|
MODULE_PARM_DESC(filter_glob,
|
2021-09-15 05:03:48 +08:00
|
|
|
"Filter which KUnit test suites/tests run at boot-time, e.g. list* or list*.*del_test");
|
2024-01-23 01:14:08 +08:00
|
|
|
module_param_named(filter, filter_param, charp, 0600);
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
MODULE_PARM_DESC(filter,
|
|
|
|
"Filter which KUnit test suites/tests run at boot-time using attributes, e.g. speed>slow");
|
2024-01-23 01:14:08 +08:00
|
|
|
module_param_named(filter_action, filter_action_param, charp, 0600);
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
MODULE_PARM_DESC(filter_action,
|
|
|
|
"Changes behavior of filtered tests using attributes, valid values are:\n"
|
|
|
|
"<none>: do not run filtered tests as normal\n"
|
|
|
|
"'skip': skip all filtered tests instead so tests will appear in output\n");
|
2021-09-15 05:03:48 +08:00
|
|
|
|
2023-08-07 18:23:56 +08:00
|
|
|
const char *kunit_filter_glob(void)
|
|
|
|
{
|
|
|
|
return filter_glob_param;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *kunit_filter(void)
|
|
|
|
{
|
|
|
|
return filter_param;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *kunit_filter_action(void)
|
|
|
|
{
|
|
|
|
return filter_action_param;
|
|
|
|
}
|
|
|
|
|
2021-09-15 05:03:48 +08:00
|
|
|
/* glob_match() needs NULL terminated strings, so we need a copy of filter_glob_param. */
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
struct kunit_glob_filter {
|
2021-09-15 05:03:48 +08:00
|
|
|
char *suite_glob;
|
|
|
|
char *test_glob;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Split "suite_glob.test_glob" into two. Assumes filter_glob is not empty. */
|
kunit: Fix possible null-ptr-deref in kunit_parse_glob_filter()
Inject fault while probing kunit-example-test.ko, if kzalloc fails
in kunit_parse_glob_filter(), strcpy() or strncpy() to NULL will
cause below null-ptr-deref bug. So check NULL for kzalloc() and
return int instead of void for kunit_parse_glob_filter().
Unable to handle kernel paging request at virtual address dfff800000000000
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
Mem abort info:
ESR = 0x0000000096000005
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x05: level 1 translation fault
Data abort info:
ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[dfff800000000000] address between user and kernel address ranges
Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
Modules linked in: kunit_example_test cfg80211 rfkill 8021q garp mrp stp llc ipv6 [last unloaded: kunit_example_test]
CPU: 4 PID: 6047 Comm: modprobe Tainted: G W N 6.5.0-next-20230829+ #141
Hardware name: linux,dummy-virt (DT)
pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : strncpy+0x58/0xc0
lr : kunit_filter_suites+0x15c/0xa84
sp : ffff800082a17420
x29: ffff800082a17420 x28: 0000000000000000 x27: 0000000000000004
x26: 0000000000000000 x25: ffffa847e40a5320 x24: 0000000000000001
x23: 0000000000000000 x22: 0000000000000001 x21: dfff800000000000
x20: 000000000000002a x19: 0000000000000000 x18: 00000000750b3b54
x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
x14: 0000000000000000 x13: 34393178302f3039 x12: ffff7508fcea4ec1
x11: 1ffff508fcea4ec0 x10: ffff7508fcea4ec0 x9 : dfff800000000000
x8 : ffff6051b1a7f86a x7 : ffff800082a17270 x6 : 0000000000000002
x5 : 0000000000000098 x4 : ffff028d9817b250 x3 : 0000000000000000
x2 : 0000000000000000 x1 : ffffa847e40a5320 x0 : 0000000000000000
Call trace:
strncpy+0x58/0xc0
kunit_filter_suites+0x15c/0xa84
kunit_module_notify+0x1b0/0x3ac
blocking_notifier_call_chain+0xc4/0x128
do_init_module+0x250/0x594
load_module+0x37b0/0x44b4
init_module_from_file+0xd4/0x128
idempotent_init_module+0x2c8/0x524
__arm64_sys_finit_module+0xac/0x100
invoke_syscall+0x6c/0x258
el0_svc_common.constprop.0+0x160/0x22c
do_el0_svc+0x44/0x5c
el0_svc+0x38/0x78
el0t_64_sync_handler+0x13c/0x158
el0t_64_sync+0x190/0x194
Code: 5400028a d343fe63 12000a62 39400034 (38f56863)
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Oops: Fatal exception
SMP: stopping secondary CPUs
Kernel Offset: 0x284761400000 from 0xffff800080000000
PHYS_OFFSET: 0xfffffd7380000000
CPU features: 0x88000203,3c020000,1000421b
Memory Limit: none
Rebooting in 1 seconds..
Fixes: a127b154a8f2 ("kunit: tool: allow filtering test cases via glob")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-09-03 15:10:27 +08:00
|
|
|
static int kunit_parse_glob_filter(struct kunit_glob_filter *parsed,
|
2021-09-15 05:03:48 +08:00
|
|
|
const char *filter_glob)
|
|
|
|
{
|
|
|
|
const int len = strlen(filter_glob);
|
|
|
|
const char *period = strchr(filter_glob, '.');
|
|
|
|
|
|
|
|
if (!period) {
|
2021-10-02 09:36:35 +08:00
|
|
|
parsed->suite_glob = kzalloc(len + 1, GFP_KERNEL);
|
kunit: Fix possible null-ptr-deref in kunit_parse_glob_filter()
Inject fault while probing kunit-example-test.ko, if kzalloc fails
in kunit_parse_glob_filter(), strcpy() or strncpy() to NULL will
cause below null-ptr-deref bug. So check NULL for kzalloc() and
return int instead of void for kunit_parse_glob_filter().
Unable to handle kernel paging request at virtual address dfff800000000000
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
Mem abort info:
ESR = 0x0000000096000005
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x05: level 1 translation fault
Data abort info:
ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[dfff800000000000] address between user and kernel address ranges
Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
Modules linked in: kunit_example_test cfg80211 rfkill 8021q garp mrp stp llc ipv6 [last unloaded: kunit_example_test]
CPU: 4 PID: 6047 Comm: modprobe Tainted: G W N 6.5.0-next-20230829+ #141
Hardware name: linux,dummy-virt (DT)
pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : strncpy+0x58/0xc0
lr : kunit_filter_suites+0x15c/0xa84
sp : ffff800082a17420
x29: ffff800082a17420 x28: 0000000000000000 x27: 0000000000000004
x26: 0000000000000000 x25: ffffa847e40a5320 x24: 0000000000000001
x23: 0000000000000000 x22: 0000000000000001 x21: dfff800000000000
x20: 000000000000002a x19: 0000000000000000 x18: 00000000750b3b54
x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
x14: 0000000000000000 x13: 34393178302f3039 x12: ffff7508fcea4ec1
x11: 1ffff508fcea4ec0 x10: ffff7508fcea4ec0 x9 : dfff800000000000
x8 : ffff6051b1a7f86a x7 : ffff800082a17270 x6 : 0000000000000002
x5 : 0000000000000098 x4 : ffff028d9817b250 x3 : 0000000000000000
x2 : 0000000000000000 x1 : ffffa847e40a5320 x0 : 0000000000000000
Call trace:
strncpy+0x58/0xc0
kunit_filter_suites+0x15c/0xa84
kunit_module_notify+0x1b0/0x3ac
blocking_notifier_call_chain+0xc4/0x128
do_init_module+0x250/0x594
load_module+0x37b0/0x44b4
init_module_from_file+0xd4/0x128
idempotent_init_module+0x2c8/0x524
__arm64_sys_finit_module+0xac/0x100
invoke_syscall+0x6c/0x258
el0_svc_common.constprop.0+0x160/0x22c
do_el0_svc+0x44/0x5c
el0_svc+0x38/0x78
el0t_64_sync_handler+0x13c/0x158
el0t_64_sync+0x190/0x194
Code: 5400028a d343fe63 12000a62 39400034 (38f56863)
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Oops: Fatal exception
SMP: stopping secondary CPUs
Kernel Offset: 0x284761400000 from 0xffff800080000000
PHYS_OFFSET: 0xfffffd7380000000
CPU features: 0x88000203,3c020000,1000421b
Memory Limit: none
Rebooting in 1 seconds..
Fixes: a127b154a8f2 ("kunit: tool: allow filtering test cases via glob")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-09-03 15:10:27 +08:00
|
|
|
if (!parsed->suite_glob)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2021-09-15 05:03:48 +08:00
|
|
|
parsed->test_glob = NULL;
|
|
|
|
strcpy(parsed->suite_glob, filter_glob);
|
kunit: Fix possible null-ptr-deref in kunit_parse_glob_filter()
Inject fault while probing kunit-example-test.ko, if kzalloc fails
in kunit_parse_glob_filter(), strcpy() or strncpy() to NULL will
cause below null-ptr-deref bug. So check NULL for kzalloc() and
return int instead of void for kunit_parse_glob_filter().
Unable to handle kernel paging request at virtual address dfff800000000000
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
Mem abort info:
ESR = 0x0000000096000005
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x05: level 1 translation fault
Data abort info:
ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[dfff800000000000] address between user and kernel address ranges
Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
Modules linked in: kunit_example_test cfg80211 rfkill 8021q garp mrp stp llc ipv6 [last unloaded: kunit_example_test]
CPU: 4 PID: 6047 Comm: modprobe Tainted: G W N 6.5.0-next-20230829+ #141
Hardware name: linux,dummy-virt (DT)
pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : strncpy+0x58/0xc0
lr : kunit_filter_suites+0x15c/0xa84
sp : ffff800082a17420
x29: ffff800082a17420 x28: 0000000000000000 x27: 0000000000000004
x26: 0000000000000000 x25: ffffa847e40a5320 x24: 0000000000000001
x23: 0000000000000000 x22: 0000000000000001 x21: dfff800000000000
x20: 000000000000002a x19: 0000000000000000 x18: 00000000750b3b54
x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
x14: 0000000000000000 x13: 34393178302f3039 x12: ffff7508fcea4ec1
x11: 1ffff508fcea4ec0 x10: ffff7508fcea4ec0 x9 : dfff800000000000
x8 : ffff6051b1a7f86a x7 : ffff800082a17270 x6 : 0000000000000002
x5 : 0000000000000098 x4 : ffff028d9817b250 x3 : 0000000000000000
x2 : 0000000000000000 x1 : ffffa847e40a5320 x0 : 0000000000000000
Call trace:
strncpy+0x58/0xc0
kunit_filter_suites+0x15c/0xa84
kunit_module_notify+0x1b0/0x3ac
blocking_notifier_call_chain+0xc4/0x128
do_init_module+0x250/0x594
load_module+0x37b0/0x44b4
init_module_from_file+0xd4/0x128
idempotent_init_module+0x2c8/0x524
__arm64_sys_finit_module+0xac/0x100
invoke_syscall+0x6c/0x258
el0_svc_common.constprop.0+0x160/0x22c
do_el0_svc+0x44/0x5c
el0_svc+0x38/0x78
el0t_64_sync_handler+0x13c/0x158
el0t_64_sync+0x190/0x194
Code: 5400028a d343fe63 12000a62 39400034 (38f56863)
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Oops: Fatal exception
SMP: stopping secondary CPUs
Kernel Offset: 0x284761400000 from 0xffff800080000000
PHYS_OFFSET: 0xfffffd7380000000
CPU features: 0x88000203,3c020000,1000421b
Memory Limit: none
Rebooting in 1 seconds..
Fixes: a127b154a8f2 ("kunit: tool: allow filtering test cases via glob")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-09-03 15:10:27 +08:00
|
|
|
return 0;
|
2021-09-15 05:03:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
parsed->suite_glob = kzalloc(period - filter_glob + 1, GFP_KERNEL);
|
kunit: Fix possible null-ptr-deref in kunit_parse_glob_filter()
Inject fault while probing kunit-example-test.ko, if kzalloc fails
in kunit_parse_glob_filter(), strcpy() or strncpy() to NULL will
cause below null-ptr-deref bug. So check NULL for kzalloc() and
return int instead of void for kunit_parse_glob_filter().
Unable to handle kernel paging request at virtual address dfff800000000000
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
Mem abort info:
ESR = 0x0000000096000005
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x05: level 1 translation fault
Data abort info:
ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[dfff800000000000] address between user and kernel address ranges
Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
Modules linked in: kunit_example_test cfg80211 rfkill 8021q garp mrp stp llc ipv6 [last unloaded: kunit_example_test]
CPU: 4 PID: 6047 Comm: modprobe Tainted: G W N 6.5.0-next-20230829+ #141
Hardware name: linux,dummy-virt (DT)
pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : strncpy+0x58/0xc0
lr : kunit_filter_suites+0x15c/0xa84
sp : ffff800082a17420
x29: ffff800082a17420 x28: 0000000000000000 x27: 0000000000000004
x26: 0000000000000000 x25: ffffa847e40a5320 x24: 0000000000000001
x23: 0000000000000000 x22: 0000000000000001 x21: dfff800000000000
x20: 000000000000002a x19: 0000000000000000 x18: 00000000750b3b54
x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
x14: 0000000000000000 x13: 34393178302f3039 x12: ffff7508fcea4ec1
x11: 1ffff508fcea4ec0 x10: ffff7508fcea4ec0 x9 : dfff800000000000
x8 : ffff6051b1a7f86a x7 : ffff800082a17270 x6 : 0000000000000002
x5 : 0000000000000098 x4 : ffff028d9817b250 x3 : 0000000000000000
x2 : 0000000000000000 x1 : ffffa847e40a5320 x0 : 0000000000000000
Call trace:
strncpy+0x58/0xc0
kunit_filter_suites+0x15c/0xa84
kunit_module_notify+0x1b0/0x3ac
blocking_notifier_call_chain+0xc4/0x128
do_init_module+0x250/0x594
load_module+0x37b0/0x44b4
init_module_from_file+0xd4/0x128
idempotent_init_module+0x2c8/0x524
__arm64_sys_finit_module+0xac/0x100
invoke_syscall+0x6c/0x258
el0_svc_common.constprop.0+0x160/0x22c
do_el0_svc+0x44/0x5c
el0_svc+0x38/0x78
el0t_64_sync_handler+0x13c/0x158
el0t_64_sync+0x190/0x194
Code: 5400028a d343fe63 12000a62 39400034 (38f56863)
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Oops: Fatal exception
SMP: stopping secondary CPUs
Kernel Offset: 0x284761400000 from 0xffff800080000000
PHYS_OFFSET: 0xfffffd7380000000
CPU features: 0x88000203,3c020000,1000421b
Memory Limit: none
Rebooting in 1 seconds..
Fixes: a127b154a8f2 ("kunit: tool: allow filtering test cases via glob")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-09-03 15:10:27 +08:00
|
|
|
if (!parsed->suite_glob)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2021-09-15 05:03:48 +08:00
|
|
|
parsed->test_glob = kzalloc(len - (period - filter_glob) + 1, GFP_KERNEL);
|
kunit: Fix possible null-ptr-deref in kunit_parse_glob_filter()
Inject fault while probing kunit-example-test.ko, if kzalloc fails
in kunit_parse_glob_filter(), strcpy() or strncpy() to NULL will
cause below null-ptr-deref bug. So check NULL for kzalloc() and
return int instead of void for kunit_parse_glob_filter().
Unable to handle kernel paging request at virtual address dfff800000000000
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
Mem abort info:
ESR = 0x0000000096000005
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x05: level 1 translation fault
Data abort info:
ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[dfff800000000000] address between user and kernel address ranges
Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
Modules linked in: kunit_example_test cfg80211 rfkill 8021q garp mrp stp llc ipv6 [last unloaded: kunit_example_test]
CPU: 4 PID: 6047 Comm: modprobe Tainted: G W N 6.5.0-next-20230829+ #141
Hardware name: linux,dummy-virt (DT)
pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : strncpy+0x58/0xc0
lr : kunit_filter_suites+0x15c/0xa84
sp : ffff800082a17420
x29: ffff800082a17420 x28: 0000000000000000 x27: 0000000000000004
x26: 0000000000000000 x25: ffffa847e40a5320 x24: 0000000000000001
x23: 0000000000000000 x22: 0000000000000001 x21: dfff800000000000
x20: 000000000000002a x19: 0000000000000000 x18: 00000000750b3b54
x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
x14: 0000000000000000 x13: 34393178302f3039 x12: ffff7508fcea4ec1
x11: 1ffff508fcea4ec0 x10: ffff7508fcea4ec0 x9 : dfff800000000000
x8 : ffff6051b1a7f86a x7 : ffff800082a17270 x6 : 0000000000000002
x5 : 0000000000000098 x4 : ffff028d9817b250 x3 : 0000000000000000
x2 : 0000000000000000 x1 : ffffa847e40a5320 x0 : 0000000000000000
Call trace:
strncpy+0x58/0xc0
kunit_filter_suites+0x15c/0xa84
kunit_module_notify+0x1b0/0x3ac
blocking_notifier_call_chain+0xc4/0x128
do_init_module+0x250/0x594
load_module+0x37b0/0x44b4
init_module_from_file+0xd4/0x128
idempotent_init_module+0x2c8/0x524
__arm64_sys_finit_module+0xac/0x100
invoke_syscall+0x6c/0x258
el0_svc_common.constprop.0+0x160/0x22c
do_el0_svc+0x44/0x5c
el0_svc+0x38/0x78
el0t_64_sync_handler+0x13c/0x158
el0t_64_sync+0x190/0x194
Code: 5400028a d343fe63 12000a62 39400034 (38f56863)
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Oops: Fatal exception
SMP: stopping secondary CPUs
Kernel Offset: 0x284761400000 from 0xffff800080000000
PHYS_OFFSET: 0xfffffd7380000000
CPU features: 0x88000203,3c020000,1000421b
Memory Limit: none
Rebooting in 1 seconds..
Fixes: a127b154a8f2 ("kunit: tool: allow filtering test cases via glob")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-09-03 15:10:27 +08:00
|
|
|
if (!parsed->test_glob) {
|
|
|
|
kfree(parsed->suite_glob);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
2021-09-15 05:03:48 +08:00
|
|
|
|
|
|
|
strncpy(parsed->suite_glob, filter_glob, period - filter_glob);
|
|
|
|
strncpy(parsed->test_glob, period + 1, len - (period - filter_glob));
|
kunit: Fix possible null-ptr-deref in kunit_parse_glob_filter()
Inject fault while probing kunit-example-test.ko, if kzalloc fails
in kunit_parse_glob_filter(), strcpy() or strncpy() to NULL will
cause below null-ptr-deref bug. So check NULL for kzalloc() and
return int instead of void for kunit_parse_glob_filter().
Unable to handle kernel paging request at virtual address dfff800000000000
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
Mem abort info:
ESR = 0x0000000096000005
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x05: level 1 translation fault
Data abort info:
ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[dfff800000000000] address between user and kernel address ranges
Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
Modules linked in: kunit_example_test cfg80211 rfkill 8021q garp mrp stp llc ipv6 [last unloaded: kunit_example_test]
CPU: 4 PID: 6047 Comm: modprobe Tainted: G W N 6.5.0-next-20230829+ #141
Hardware name: linux,dummy-virt (DT)
pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : strncpy+0x58/0xc0
lr : kunit_filter_suites+0x15c/0xa84
sp : ffff800082a17420
x29: ffff800082a17420 x28: 0000000000000000 x27: 0000000000000004
x26: 0000000000000000 x25: ffffa847e40a5320 x24: 0000000000000001
x23: 0000000000000000 x22: 0000000000000001 x21: dfff800000000000
x20: 000000000000002a x19: 0000000000000000 x18: 00000000750b3b54
x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
x14: 0000000000000000 x13: 34393178302f3039 x12: ffff7508fcea4ec1
x11: 1ffff508fcea4ec0 x10: ffff7508fcea4ec0 x9 : dfff800000000000
x8 : ffff6051b1a7f86a x7 : ffff800082a17270 x6 : 0000000000000002
x5 : 0000000000000098 x4 : ffff028d9817b250 x3 : 0000000000000000
x2 : 0000000000000000 x1 : ffffa847e40a5320 x0 : 0000000000000000
Call trace:
strncpy+0x58/0xc0
kunit_filter_suites+0x15c/0xa84
kunit_module_notify+0x1b0/0x3ac
blocking_notifier_call_chain+0xc4/0x128
do_init_module+0x250/0x594
load_module+0x37b0/0x44b4
init_module_from_file+0xd4/0x128
idempotent_init_module+0x2c8/0x524
__arm64_sys_finit_module+0xac/0x100
invoke_syscall+0x6c/0x258
el0_svc_common.constprop.0+0x160/0x22c
do_el0_svc+0x44/0x5c
el0_svc+0x38/0x78
el0t_64_sync_handler+0x13c/0x158
el0t_64_sync+0x190/0x194
Code: 5400028a d343fe63 12000a62 39400034 (38f56863)
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Oops: Fatal exception
SMP: stopping secondary CPUs
Kernel Offset: 0x284761400000 from 0xffff800080000000
PHYS_OFFSET: 0xfffffd7380000000
CPU features: 0x88000203,3c020000,1000421b
Memory Limit: none
Rebooting in 1 seconds..
Fixes: a127b154a8f2 ("kunit: tool: allow filtering test cases via glob")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-09-03 15:10:27 +08:00
|
|
|
|
|
|
|
return 0;
|
2021-09-15 05:03:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Create a copy of suite with only tests that match test_glob. */
|
|
|
|
static struct kunit_suite *
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
kunit_filter_glob_tests(const struct kunit_suite *const suite, const char *test_glob)
|
2021-09-15 05:03:48 +08:00
|
|
|
{
|
|
|
|
int n = 0;
|
|
|
|
struct kunit_case *filtered, *test_case;
|
|
|
|
struct kunit_suite *copy;
|
|
|
|
|
|
|
|
kunit_suite_for_each_test_case(suite, test_case) {
|
|
|
|
if (!test_glob || glob_match(test_glob, test_case->name))
|
|
|
|
++n;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n == 0)
|
|
|
|
return NULL;
|
|
|
|
|
2022-05-17 00:54:46 +08:00
|
|
|
copy = kmemdup(suite, sizeof(*copy), GFP_KERNEL);
|
2022-05-12 05:16:26 +08:00
|
|
|
if (!copy)
|
|
|
|
return ERR_PTR(-ENOMEM);
|
2021-09-15 05:03:48 +08:00
|
|
|
|
|
|
|
filtered = kcalloc(n + 1, sizeof(*filtered), GFP_KERNEL);
|
2022-07-13 07:25:27 +08:00
|
|
|
if (!filtered) {
|
|
|
|
kfree(copy);
|
2022-05-12 05:16:26 +08:00
|
|
|
return ERR_PTR(-ENOMEM);
|
2022-07-13 07:25:27 +08:00
|
|
|
}
|
2021-09-15 05:03:48 +08:00
|
|
|
|
|
|
|
n = 0;
|
|
|
|
kunit_suite_for_each_test_case(suite, test_case) {
|
|
|
|
if (!test_glob || glob_match(test_glob, test_case->name))
|
|
|
|
filtered[n++] = *test_case;
|
|
|
|
}
|
|
|
|
|
|
|
|
copy->test_cases = filtered;
|
|
|
|
return copy;
|
|
|
|
}
|
2021-02-06 08:08:52 +08:00
|
|
|
|
2023-08-07 18:23:56 +08:00
|
|
|
void kunit_free_suite_set(struct kunit_suite_set suite_set)
|
2021-09-15 05:03:48 +08:00
|
|
|
{
|
2022-07-09 11:19:58 +08:00
|
|
|
struct kunit_suite * const *suites;
|
2021-09-15 05:03:48 +08:00
|
|
|
|
2023-09-27 17:03:47 +08:00
|
|
|
for (suites = suite_set.start; suites < suite_set.end; suites++) {
|
|
|
|
kfree((*suites)->test_cases);
|
2022-07-09 11:19:58 +08:00
|
|
|
kfree(*suites);
|
2023-09-27 17:03:47 +08:00
|
|
|
}
|
2021-09-15 05:03:48 +08:00
|
|
|
kfree(suite_set.start);
|
|
|
|
}
|
|
|
|
|
kunit: run test suites only after module initialization completes
Commit 2810c1e99867 ("kunit: Fix wild-memory-access bug in
kunit_free_suite_set()") fixed a wild-memory-access bug that could have
happened during the loading phase of test suites built and executed as
loadable modules. However, it also introduced a problematic side effect
that causes test suites modules to crash when they attempt to register
fake devices.
When a module is loaded, it traverses the MODULE_STATE_UNFORMED and
MODULE_STATE_COMING states before reaching the normal operating state
MODULE_STATE_LIVE. Finally, when the module is removed, it moves to
MODULE_STATE_GOING before being released. However, if the loading
function load_module() fails between complete_formation() and
do_init_module(), the module goes directly from MODULE_STATE_COMING to
MODULE_STATE_GOING without passing through MODULE_STATE_LIVE.
This behavior was causing kunit_module_exit() to be called without
having first executed kunit_module_init(). Since kunit_module_exit() is
responsible for freeing the memory allocated by kunit_module_init()
through kunit_filter_suites(), this behavior was resulting in a
wild-memory-access bug.
Commit 2810c1e99867 ("kunit: Fix wild-memory-access bug in
kunit_free_suite_set()") fixed this issue by running the tests when the
module is still in MODULE_STATE_COMING. However, modules in that state
are not fully initialized, lacking sysfs kobjects. Therefore, if a test
module attempts to register a fake device, it will inevitably crash.
This patch proposes a different approach to fix the original
wild-memory-access bug while restoring the normal module execution flow
by making kunit_module_exit() able to detect if kunit_module_init() has
previously initialized the tests suite set. In this way, test modules
can once again register fake devices without crashing.
This behavior is achieved by checking whether mod->kunit_suites is a
virtual or direct mapping address. If it is a virtual address, then
kunit_module_init() has allocated the suite_set in kunit_filter_suites()
using kmalloc_array(). On the contrary, if mod->kunit_suites is still
pointing to the original address that was set when looking up the
.kunit_test_suites section of the module, then the loading phase has
failed and there's no memory to be freed.
v4:
- rebased on 6.8
- noted that kunit_filter_suites() must return a virtual address
v3:
- add a comment to clarify why the start address is checked
v2:
- add include <linux/mm.h>
Fixes: 2810c1e99867 ("kunit: Fix wild-memory-access bug in kunit_free_suite_set()")
Reviewed-by: David Gow <davidgow@google.com>
Tested-by: Rae Moar <rmoar@google.com>
Tested-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Marco Pagani <marpagan@redhat.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2024-01-10 23:59:47 +08:00
|
|
|
/*
|
|
|
|
* Filter and reallocate test suites. Must return the filtered test suites set
|
|
|
|
* allocated at a valid virtual address or NULL in case of error.
|
|
|
|
*/
|
2023-08-07 18:23:56 +08:00
|
|
|
struct kunit_suite_set
|
kunit: Report the count of test suites in a module
According to KTAP specification[1], results should always start from a
header that provides a TAP protocol version, followed by a test plan with
a count of items to be executed. That pattern should be followed at each
nesting level. In the current implementation of the top-most, i.e., test
suite level, those rules apply only for test suites built into the kernel,
executed and reported on boot. Results submitted to dmesg from kunit test
modules loaded later are missing those top-level headers.
As a consequence, if a kunit test module provides more than one test suite
then, without the top level test plan, external tools that are parsing
dmesg for kunit test output are not able to tell how many test suites
should be expected and whether to continue parsing after complete output
from the first test suite is collected.
Submit the top-level headers also from the kunit test module notifier
initialization callback.
v3: Fix new name of a structure moved to kunit namespace not updated in
executor_test functions (lkp@intel.com).
v2: Use kunit_exec_run_tests() (Mauro, Rae), but prevent it from
emitting the headers when called on load of non-test modules.
[1] https://docs.kernel.org/dev-tools/ktap.html#
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 18:23:54 +08:00
|
|
|
kunit_filter_suites(const struct kunit_suite_set *suite_set,
|
|
|
|
const char *filter_glob,
|
|
|
|
char *filters,
|
|
|
|
char *filter_action,
|
|
|
|
int *err)
|
2021-02-06 08:08:52 +08:00
|
|
|
{
|
2023-07-29 09:00:03 +08:00
|
|
|
int i, j, k;
|
|
|
|
int filter_count = 0;
|
2023-08-04 03:36:35 +08:00
|
|
|
struct kunit_suite **copy, **copy_start, *filtered_suite, *new_filtered_suite;
|
kunit: Report the count of test suites in a module
According to KTAP specification[1], results should always start from a
header that provides a TAP protocol version, followed by a test plan with
a count of items to be executed. That pattern should be followed at each
nesting level. In the current implementation of the top-most, i.e., test
suite level, those rules apply only for test suites built into the kernel,
executed and reported on boot. Results submitted to dmesg from kunit test
modules loaded later are missing those top-level headers.
As a consequence, if a kunit test module provides more than one test suite
then, without the top level test plan, external tools that are parsing
dmesg for kunit test output are not able to tell how many test suites
should be expected and whether to continue parsing after complete output
from the first test suite is collected.
Submit the top-level headers also from the kunit test module notifier
initialization callback.
v3: Fix new name of a structure moved to kunit namespace not updated in
executor_test functions (lkp@intel.com).
v2: Use kunit_exec_run_tests() (Mauro, Rae), but prevent it from
emitting the headers when called on load of non-test modules.
[1] https://docs.kernel.org/dev-tools/ktap.html#
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 18:23:54 +08:00
|
|
|
struct kunit_suite_set filtered = {NULL, NULL};
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
struct kunit_glob_filter parsed_glob;
|
2023-08-04 03:36:35 +08:00
|
|
|
struct kunit_attr_filter *parsed_filters = NULL;
|
2023-09-27 17:03:49 +08:00
|
|
|
struct kunit_suite * const *suites;
|
2021-02-06 08:08:52 +08:00
|
|
|
|
2021-04-21 10:04:27 +08:00
|
|
|
const size_t max = suite_set->end - suite_set->start;
|
2021-02-06 08:08:52 +08:00
|
|
|
|
2023-09-27 17:03:49 +08:00
|
|
|
copy = kcalloc(max, sizeof(*filtered.start), GFP_KERNEL);
|
2021-02-06 08:08:52 +08:00
|
|
|
if (!copy) { /* won't be able to run anything, return an empty set */
|
|
|
|
return filtered;
|
|
|
|
}
|
2023-08-04 03:36:35 +08:00
|
|
|
copy_start = copy;
|
2021-02-06 08:08:52 +08:00
|
|
|
|
kunit: Fix possible null-ptr-deref in kunit_parse_glob_filter()
Inject fault while probing kunit-example-test.ko, if kzalloc fails
in kunit_parse_glob_filter(), strcpy() or strncpy() to NULL will
cause below null-ptr-deref bug. So check NULL for kzalloc() and
return int instead of void for kunit_parse_glob_filter().
Unable to handle kernel paging request at virtual address dfff800000000000
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
Mem abort info:
ESR = 0x0000000096000005
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x05: level 1 translation fault
Data abort info:
ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[dfff800000000000] address between user and kernel address ranges
Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
Modules linked in: kunit_example_test cfg80211 rfkill 8021q garp mrp stp llc ipv6 [last unloaded: kunit_example_test]
CPU: 4 PID: 6047 Comm: modprobe Tainted: G W N 6.5.0-next-20230829+ #141
Hardware name: linux,dummy-virt (DT)
pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : strncpy+0x58/0xc0
lr : kunit_filter_suites+0x15c/0xa84
sp : ffff800082a17420
x29: ffff800082a17420 x28: 0000000000000000 x27: 0000000000000004
x26: 0000000000000000 x25: ffffa847e40a5320 x24: 0000000000000001
x23: 0000000000000000 x22: 0000000000000001 x21: dfff800000000000
x20: 000000000000002a x19: 0000000000000000 x18: 00000000750b3b54
x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
x14: 0000000000000000 x13: 34393178302f3039 x12: ffff7508fcea4ec1
x11: 1ffff508fcea4ec0 x10: ffff7508fcea4ec0 x9 : dfff800000000000
x8 : ffff6051b1a7f86a x7 : ffff800082a17270 x6 : 0000000000000002
x5 : 0000000000000098 x4 : ffff028d9817b250 x3 : 0000000000000000
x2 : 0000000000000000 x1 : ffffa847e40a5320 x0 : 0000000000000000
Call trace:
strncpy+0x58/0xc0
kunit_filter_suites+0x15c/0xa84
kunit_module_notify+0x1b0/0x3ac
blocking_notifier_call_chain+0xc4/0x128
do_init_module+0x250/0x594
load_module+0x37b0/0x44b4
init_module_from_file+0xd4/0x128
idempotent_init_module+0x2c8/0x524
__arm64_sys_finit_module+0xac/0x100
invoke_syscall+0x6c/0x258
el0_svc_common.constprop.0+0x160/0x22c
do_el0_svc+0x44/0x5c
el0_svc+0x38/0x78
el0t_64_sync_handler+0x13c/0x158
el0t_64_sync+0x190/0x194
Code: 5400028a d343fe63 12000a62 39400034 (38f56863)
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Oops: Fatal exception
SMP: stopping secondary CPUs
Kernel Offset: 0x284761400000 from 0xffff800080000000
PHYS_OFFSET: 0xfffffd7380000000
CPU features: 0x88000203,3c020000,1000421b
Memory Limit: none
Rebooting in 1 seconds..
Fixes: a127b154a8f2 ("kunit: tool: allow filtering test cases via glob")
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-09-03 15:10:27 +08:00
|
|
|
if (filter_glob) {
|
|
|
|
*err = kunit_parse_glob_filter(&parsed_glob, filter_glob);
|
|
|
|
if (*err)
|
|
|
|
goto free_copy;
|
|
|
|
}
|
2021-09-15 05:03:48 +08:00
|
|
|
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
/* Parse attribute filters */
|
|
|
|
if (filters) {
|
|
|
|
filter_count = kunit_get_filter_count(filters);
|
2023-08-04 03:36:35 +08:00
|
|
|
parsed_filters = kcalloc(filter_count, sizeof(*parsed_filters), GFP_KERNEL);
|
|
|
|
if (!parsed_filters) {
|
2023-09-03 15:10:28 +08:00
|
|
|
*err = -ENOMEM;
|
|
|
|
goto free_parsed_glob;
|
2023-08-04 03:36:35 +08:00
|
|
|
}
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
for (j = 0; j < filter_count; j++)
|
|
|
|
parsed_filters[j] = kunit_next_attr_filter(&filters, err);
|
|
|
|
if (*err)
|
2023-09-03 15:10:26 +08:00
|
|
|
goto free_parsed_filters;
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; &suite_set->start[i] != suite_set->end; i++) {
|
|
|
|
filtered_suite = suite_set->start[i];
|
|
|
|
if (filter_glob) {
|
|
|
|
if (!glob_match(parsed_glob.suite_glob, filtered_suite->name))
|
|
|
|
continue;
|
|
|
|
filtered_suite = kunit_filter_glob_tests(filtered_suite,
|
|
|
|
parsed_glob.test_glob);
|
|
|
|
if (IS_ERR(filtered_suite)) {
|
|
|
|
*err = PTR_ERR(filtered_suite);
|
2023-09-27 17:03:49 +08:00
|
|
|
goto free_filtered_suite;
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
}
|
2022-05-12 05:16:26 +08:00
|
|
|
}
|
2023-08-04 03:36:35 +08:00
|
|
|
if (filter_count > 0 && parsed_filters != NULL) {
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
for (k = 0; k < filter_count; k++) {
|
|
|
|
new_filtered_suite = kunit_filter_attr_tests(filtered_suite,
|
|
|
|
parsed_filters[k], filter_action, err);
|
|
|
|
|
|
|
|
/* Free previous copy of suite */
|
kunit: fix possible memory leak in kunit_filter_suites()
Inject fault while probing drm_kunit_helpers.ko, if one of
kunit_next_attr_filter(), kunit_filter_glob_tests() and
kunit_filter_attr_tests() fails, parsed_filters,
parsed_glob.suite_glob/test_glob alloced in
kunit_parse_glob_filter() is leaked.
And the filtered_suite->test_cases alloced in kunit_filter_glob_tests()
or kunit_filter_attr_tests() may also be leaked.
unreferenced object 0xff110001067e4800 (size 1024):
comm "kunit_try_catch", pid 96, jiffies 4294671796 (age 763.547s)
hex dump (first 32 bytes):
73 75 69 74 65 32 00 00 00 00 00 00 00 00 00 00 suite2..........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<00000000116e8eba>] __kmalloc_node_track_caller+0x4e/0x140
[<00000000e2f9cce9>] kmemdup+0x2c/0x60
[<000000002a36710b>] kunit_filter_suites+0x3e4/0xa50
[<0000000045779fb9>] filter_suites_test+0x1b7/0x440
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000105d79b00 (size 192):
comm "kunit_try_catch", pid 96, jiffies 4294671796 (age 763.547s)
hex dump (first 32 bytes):
f0 e1 5a 88 ff ff ff ff 60 59 bb 8a ff ff ff ff ..Z.....`Y......
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<000000006afe50bd>] kunit_filter_suites+0x424/0xa50
[<0000000045779fb9>] filter_suites_test+0x1b7/0x440
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff110001067e6000 (size 1024):
comm "kunit_try_catch", pid 98, jiffies 4294671798 (age 763.545s)
hex dump (first 32 bytes):
73 75 69 74 65 32 00 00 00 00 00 00 00 00 00 00 suite2..........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<00000000116e8eba>] __kmalloc_node_track_caller+0x4e/0x140
[<00000000e2f9cce9>] kmemdup+0x2c/0x60
[<000000002a36710b>] kunit_filter_suites+0x3e4/0xa50
[<00000000f452f130>] filter_suites_test_glob_test+0x1b7/0x660
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000103f3a800 (size 96):
comm "kunit_try_catch", pid 98, jiffies 4294671798 (age 763.545s)
hex dump (first 32 bytes):
f0 e1 5a 88 ff ff ff ff 40 39 bb 8a ff ff ff ff ..Z.....@9......
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<000000006afe50bd>] kunit_filter_suites+0x424/0xa50
[<00000000f452f130>] filter_suites_test_glob_test+0x1b7/0x660
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000101a72ac0 (size 16):
comm "kunit_try_catch", pid 104, jiffies 4294671814 (age 763.529s)
hex dump (first 16 bytes):
00 00 00 00 00 00 00 00 e0 2a a7 01 01 00 11 ff .........*......
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c7b724e7>] kunit_filter_suites+0x108/0xa50
[<00000000bad5427d>] filter_attr_test+0x1e9/0x6a0
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000103caf880 (size 32):
comm "kunit_try_catch", pid 104, jiffies 4294671814 (age 763.547s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c47b0f75>] kunit_filter_suites+0x189/0xa50
[<00000000bad5427d>] filter_attr_test+0x1e9/0x6a0
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000101a72ae0 (size 16):
comm "kunit_try_catch", pid 106, jiffies 4294671823 (age 763.538s)
hex dump (first 16 bytes):
00 00 00 00 00 00 00 00 00 2b a7 01 01 00 11 ff .........+......
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c7b724e7>] kunit_filter_suites+0x108/0xa50
[<0000000096255c51>] filter_attr_empty_test+0x1b0/0x310
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000103caf9c0 (size 32):
comm "kunit_try_catch", pid 106, jiffies 4294671823 (age 763.538s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c47b0f75>] kunit_filter_suites+0x189/0xa50
[<0000000096255c51>] filter_attr_empty_test+0x1b0/0x310
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000101a72b00 (size 16):
comm "kunit_try_catch", pid 108, jiffies 4294671832 (age 763.529s)
hex dump (first 16 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c47b0f75>] kunit_filter_suites+0x189/0xa50
[<00000000881258cc>] filter_attr_skip_test+0x148/0x770
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
Fixes: 5d31f71efcb6 ("kunit: add kunit.filter_glob cmdline option to filter suites")
Fixes: 529534e8cba3 ("kunit: Add ability to filter attributes")
Signed-off-by: Ruan Jinjie <ruanjinjie@huawei.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-01 15:37:00 +08:00
|
|
|
if (k > 0 || filter_glob) {
|
|
|
|
kfree(filtered_suite->test_cases);
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
kfree(filtered_suite);
|
kunit: fix possible memory leak in kunit_filter_suites()
Inject fault while probing drm_kunit_helpers.ko, if one of
kunit_next_attr_filter(), kunit_filter_glob_tests() and
kunit_filter_attr_tests() fails, parsed_filters,
parsed_glob.suite_glob/test_glob alloced in
kunit_parse_glob_filter() is leaked.
And the filtered_suite->test_cases alloced in kunit_filter_glob_tests()
or kunit_filter_attr_tests() may also be leaked.
unreferenced object 0xff110001067e4800 (size 1024):
comm "kunit_try_catch", pid 96, jiffies 4294671796 (age 763.547s)
hex dump (first 32 bytes):
73 75 69 74 65 32 00 00 00 00 00 00 00 00 00 00 suite2..........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<00000000116e8eba>] __kmalloc_node_track_caller+0x4e/0x140
[<00000000e2f9cce9>] kmemdup+0x2c/0x60
[<000000002a36710b>] kunit_filter_suites+0x3e4/0xa50
[<0000000045779fb9>] filter_suites_test+0x1b7/0x440
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000105d79b00 (size 192):
comm "kunit_try_catch", pid 96, jiffies 4294671796 (age 763.547s)
hex dump (first 32 bytes):
f0 e1 5a 88 ff ff ff ff 60 59 bb 8a ff ff ff ff ..Z.....`Y......
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<000000006afe50bd>] kunit_filter_suites+0x424/0xa50
[<0000000045779fb9>] filter_suites_test+0x1b7/0x440
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff110001067e6000 (size 1024):
comm "kunit_try_catch", pid 98, jiffies 4294671798 (age 763.545s)
hex dump (first 32 bytes):
73 75 69 74 65 32 00 00 00 00 00 00 00 00 00 00 suite2..........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<00000000116e8eba>] __kmalloc_node_track_caller+0x4e/0x140
[<00000000e2f9cce9>] kmemdup+0x2c/0x60
[<000000002a36710b>] kunit_filter_suites+0x3e4/0xa50
[<00000000f452f130>] filter_suites_test_glob_test+0x1b7/0x660
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000103f3a800 (size 96):
comm "kunit_try_catch", pid 98, jiffies 4294671798 (age 763.545s)
hex dump (first 32 bytes):
f0 e1 5a 88 ff ff ff ff 40 39 bb 8a ff ff ff ff ..Z.....@9......
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<000000006afe50bd>] kunit_filter_suites+0x424/0xa50
[<00000000f452f130>] filter_suites_test_glob_test+0x1b7/0x660
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000101a72ac0 (size 16):
comm "kunit_try_catch", pid 104, jiffies 4294671814 (age 763.529s)
hex dump (first 16 bytes):
00 00 00 00 00 00 00 00 e0 2a a7 01 01 00 11 ff .........*......
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c7b724e7>] kunit_filter_suites+0x108/0xa50
[<00000000bad5427d>] filter_attr_test+0x1e9/0x6a0
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000103caf880 (size 32):
comm "kunit_try_catch", pid 104, jiffies 4294671814 (age 763.547s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c47b0f75>] kunit_filter_suites+0x189/0xa50
[<00000000bad5427d>] filter_attr_test+0x1e9/0x6a0
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000101a72ae0 (size 16):
comm "kunit_try_catch", pid 106, jiffies 4294671823 (age 763.538s)
hex dump (first 16 bytes):
00 00 00 00 00 00 00 00 00 2b a7 01 01 00 11 ff .........+......
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c7b724e7>] kunit_filter_suites+0x108/0xa50
[<0000000096255c51>] filter_attr_empty_test+0x1b0/0x310
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000103caf9c0 (size 32):
comm "kunit_try_catch", pid 106, jiffies 4294671823 (age 763.538s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c47b0f75>] kunit_filter_suites+0x189/0xa50
[<0000000096255c51>] filter_attr_empty_test+0x1b0/0x310
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000101a72b00 (size 16):
comm "kunit_try_catch", pid 108, jiffies 4294671832 (age 763.529s)
hex dump (first 16 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c47b0f75>] kunit_filter_suites+0x189/0xa50
[<00000000881258cc>] filter_attr_skip_test+0x148/0x770
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
Fixes: 5d31f71efcb6 ("kunit: add kunit.filter_glob cmdline option to filter suites")
Fixes: 529534e8cba3 ("kunit: Add ability to filter attributes")
Signed-off-by: Ruan Jinjie <ruanjinjie@huawei.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-01 15:37:00 +08:00
|
|
|
}
|
|
|
|
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
filtered_suite = new_filtered_suite;
|
|
|
|
|
|
|
|
if (*err)
|
2023-09-27 17:03:49 +08:00
|
|
|
goto free_filtered_suite;
|
2023-09-03 15:10:26 +08:00
|
|
|
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
if (IS_ERR(filtered_suite)) {
|
|
|
|
*err = PTR_ERR(filtered_suite);
|
2023-09-27 17:03:49 +08:00
|
|
|
goto free_filtered_suite;
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
}
|
|
|
|
if (!filtered_suite)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-09 11:19:58 +08:00
|
|
|
if (!filtered_suite)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
*copy++ = filtered_suite;
|
2021-02-06 08:08:52 +08:00
|
|
|
}
|
2023-08-04 03:36:35 +08:00
|
|
|
filtered.start = copy_start;
|
2021-02-06 08:08:52 +08:00
|
|
|
filtered.end = copy;
|
2021-09-15 05:03:48 +08:00
|
|
|
|
2023-09-27 17:03:49 +08:00
|
|
|
free_filtered_suite:
|
|
|
|
if (*err) {
|
|
|
|
for (suites = copy_start; suites < copy; suites++) {
|
|
|
|
kfree((*suites)->test_cases);
|
|
|
|
kfree(*suites);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-03 15:10:26 +08:00
|
|
|
free_parsed_filters:
|
|
|
|
if (filter_count)
|
|
|
|
kfree(parsed_filters);
|
kunit: fix possible memory leak in kunit_filter_suites()
Inject fault while probing drm_kunit_helpers.ko, if one of
kunit_next_attr_filter(), kunit_filter_glob_tests() and
kunit_filter_attr_tests() fails, parsed_filters,
parsed_glob.suite_glob/test_glob alloced in
kunit_parse_glob_filter() is leaked.
And the filtered_suite->test_cases alloced in kunit_filter_glob_tests()
or kunit_filter_attr_tests() may also be leaked.
unreferenced object 0xff110001067e4800 (size 1024):
comm "kunit_try_catch", pid 96, jiffies 4294671796 (age 763.547s)
hex dump (first 32 bytes):
73 75 69 74 65 32 00 00 00 00 00 00 00 00 00 00 suite2..........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<00000000116e8eba>] __kmalloc_node_track_caller+0x4e/0x140
[<00000000e2f9cce9>] kmemdup+0x2c/0x60
[<000000002a36710b>] kunit_filter_suites+0x3e4/0xa50
[<0000000045779fb9>] filter_suites_test+0x1b7/0x440
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000105d79b00 (size 192):
comm "kunit_try_catch", pid 96, jiffies 4294671796 (age 763.547s)
hex dump (first 32 bytes):
f0 e1 5a 88 ff ff ff ff 60 59 bb 8a ff ff ff ff ..Z.....`Y......
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<000000006afe50bd>] kunit_filter_suites+0x424/0xa50
[<0000000045779fb9>] filter_suites_test+0x1b7/0x440
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff110001067e6000 (size 1024):
comm "kunit_try_catch", pid 98, jiffies 4294671798 (age 763.545s)
hex dump (first 32 bytes):
73 75 69 74 65 32 00 00 00 00 00 00 00 00 00 00 suite2..........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<00000000116e8eba>] __kmalloc_node_track_caller+0x4e/0x140
[<00000000e2f9cce9>] kmemdup+0x2c/0x60
[<000000002a36710b>] kunit_filter_suites+0x3e4/0xa50
[<00000000f452f130>] filter_suites_test_glob_test+0x1b7/0x660
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000103f3a800 (size 96):
comm "kunit_try_catch", pid 98, jiffies 4294671798 (age 763.545s)
hex dump (first 32 bytes):
f0 e1 5a 88 ff ff ff ff 40 39 bb 8a ff ff ff ff ..Z.....@9......
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<000000006afe50bd>] kunit_filter_suites+0x424/0xa50
[<00000000f452f130>] filter_suites_test_glob_test+0x1b7/0x660
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000101a72ac0 (size 16):
comm "kunit_try_catch", pid 104, jiffies 4294671814 (age 763.529s)
hex dump (first 16 bytes):
00 00 00 00 00 00 00 00 e0 2a a7 01 01 00 11 ff .........*......
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c7b724e7>] kunit_filter_suites+0x108/0xa50
[<00000000bad5427d>] filter_attr_test+0x1e9/0x6a0
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000103caf880 (size 32):
comm "kunit_try_catch", pid 104, jiffies 4294671814 (age 763.547s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c47b0f75>] kunit_filter_suites+0x189/0xa50
[<00000000bad5427d>] filter_attr_test+0x1e9/0x6a0
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000101a72ae0 (size 16):
comm "kunit_try_catch", pid 106, jiffies 4294671823 (age 763.538s)
hex dump (first 16 bytes):
00 00 00 00 00 00 00 00 00 2b a7 01 01 00 11 ff .........+......
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c7b724e7>] kunit_filter_suites+0x108/0xa50
[<0000000096255c51>] filter_attr_empty_test+0x1b0/0x310
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000103caf9c0 (size 32):
comm "kunit_try_catch", pid 106, jiffies 4294671823 (age 763.538s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c47b0f75>] kunit_filter_suites+0x189/0xa50
[<0000000096255c51>] filter_attr_empty_test+0x1b0/0x310
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
unreferenced object 0xff11000101a72b00 (size 16):
comm "kunit_try_catch", pid 108, jiffies 4294671832 (age 763.529s)
hex dump (first 16 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<000000000d6e4891>] __kmalloc+0x4d/0x140
[<00000000c47b0f75>] kunit_filter_suites+0x189/0xa50
[<00000000881258cc>] filter_attr_skip_test+0x148/0x770
[<00000000cd1104a7>] kunit_try_run_case+0x119/0x270
[<00000000c654c917>] kunit_generic_run_threadfn_adapter+0x4e/0xa0
[<00000000d195ac13>] kthread+0x2c7/0x3c0
[<00000000b79c1ee9>] ret_from_fork+0x2c/0x70
[<000000001167f7e6>] ret_from_fork_asm+0x1b/0x30
Fixes: 5d31f71efcb6 ("kunit: add kunit.filter_glob cmdline option to filter suites")
Fixes: 529534e8cba3 ("kunit: Add ability to filter attributes")
Signed-off-by: Ruan Jinjie <ruanjinjie@huawei.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-01 15:37:00 +08:00
|
|
|
|
2023-09-03 15:10:26 +08:00
|
|
|
free_parsed_glob:
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
if (filter_glob) {
|
|
|
|
kfree(parsed_glob.suite_glob);
|
|
|
|
kfree(parsed_glob.test_glob);
|
|
|
|
}
|
|
|
|
|
2023-09-03 15:10:26 +08:00
|
|
|
free_copy:
|
|
|
|
if (*err)
|
2023-09-27 17:03:48 +08:00
|
|
|
kfree(copy_start);
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
|
2021-02-06 08:08:52 +08:00
|
|
|
return filtered;
|
|
|
|
}
|
|
|
|
|
kunit: Report the count of test suites in a module
According to KTAP specification[1], results should always start from a
header that provides a TAP protocol version, followed by a test plan with
a count of items to be executed. That pattern should be followed at each
nesting level. In the current implementation of the top-most, i.e., test
suite level, those rules apply only for test suites built into the kernel,
executed and reported on boot. Results submitted to dmesg from kunit test
modules loaded later are missing those top-level headers.
As a consequence, if a kunit test module provides more than one test suite
then, without the top level test plan, external tools that are parsing
dmesg for kunit test output are not able to tell how many test suites
should be expected and whether to continue parsing after complete output
from the first test suite is collected.
Submit the top-level headers also from the kunit test module notifier
initialization callback.
v3: Fix new name of a structure moved to kunit namespace not updated in
executor_test functions (lkp@intel.com).
v2: Use kunit_exec_run_tests() (Mauro, Rae), but prevent it from
emitting the headers when called on load of non-test modules.
[1] https://docs.kernel.org/dev-tools/ktap.html#
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 18:23:54 +08:00
|
|
|
void kunit_exec_run_tests(struct kunit_suite_set *suite_set, bool builtin)
|
2020-08-05 04:47:42 +08:00
|
|
|
{
|
2022-07-09 11:19:58 +08:00
|
|
|
size_t num_suites = suite_set->end - suite_set->start;
|
2021-10-01 06:20:45 +08:00
|
|
|
|
kunit: Report the count of test suites in a module
According to KTAP specification[1], results should always start from a
header that provides a TAP protocol version, followed by a test plan with
a count of items to be executed. That pattern should be followed at each
nesting level. In the current implementation of the top-most, i.e., test
suite level, those rules apply only for test suites built into the kernel,
executed and reported on boot. Results submitted to dmesg from kunit test
modules loaded later are missing those top-level headers.
As a consequence, if a kunit test module provides more than one test suite
then, without the top level test plan, external tools that are parsing
dmesg for kunit test output are not able to tell how many test suites
should be expected and whether to continue parsing after complete output
from the first test suite is collected.
Submit the top-level headers also from the kunit test module notifier
initialization callback.
v3: Fix new name of a structure moved to kunit namespace not updated in
executor_test functions (lkp@intel.com).
v2: Use kunit_exec_run_tests() (Mauro, Rae), but prevent it from
emitting the headers when called on load of non-test modules.
[1] https://docs.kernel.org/dev-tools/ktap.html#
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 18:23:54 +08:00
|
|
|
if (builtin || num_suites) {
|
|
|
|
pr_info("KTAP version 1\n");
|
|
|
|
pr_info("1..%zu\n", num_suites);
|
|
|
|
}
|
2021-10-01 06:20:45 +08:00
|
|
|
|
2022-07-09 11:19:58 +08:00
|
|
|
__kunit_test_suites_init(suite_set->start, num_suites);
|
2021-10-01 06:20:45 +08:00
|
|
|
}
|
|
|
|
|
kunit: Make 'list' action available to kunit test modules
Results from kunit tests reported via dmesg may be interleaved with other
kernel messages. When parsing dmesg for modular kunit results in real
time, external tools, e.g., Intel GPU tools (IGT), may want to insert
their own test name markers into dmesg at the start of each test, before
any kernel message related to that test appears there, so existing upper
level test result parsers have no doubt which test to blame for a specific
kernel message. Unfortunately, kunit reports names of tests only at their
completion (with the exeption of a not standarized "# Subtest: <name>"
header above a test plan of each test suite or parametrized test).
External tools could be able to insert their own "start of the test"
markers with test names included if they new those names in advance.
Test names could be learned from a list if provided by a kunit test
module.
There exists a feature of listing kunit tests without actually executing
them, but it is now limited to configurations with the kunit module built
in and covers only built-in tests, already available at boot time.
Moreover, switching from list to normal mode requires reboot. If that
feature was also available when kunit is built as a module, userspace
could load the module with action=list parameter, load some kunit test
modules they are interested in and learn about the list of tests provided
by those modules, then unload them, reload the kunit module in normal mode
and execute the tests with their lists already known.
Extend kunit module notifier initialization callback with a processing
path for only listing the tests provided by a module if the kunit action
parameter is set to "list" or "list_attr". For user convenience, make the
kunit.action parameter visible in sysfs.
v2: Don't use a different format, use kunit_exec_list_tests() (Rae),
- refresh on top of new attributes patches, handle newly introduced
kunit.action=list_attr case (Rae).
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 18:23:55 +08:00
|
|
|
void kunit_exec_list_tests(struct kunit_suite_set *suite_set, bool include_attr)
|
2021-10-01 06:20:45 +08:00
|
|
|
{
|
2022-07-09 11:19:58 +08:00
|
|
|
struct kunit_suite * const *suites;
|
2021-10-01 06:20:45 +08:00
|
|
|
struct kunit_case *test_case;
|
|
|
|
|
2022-11-24 02:25:58 +08:00
|
|
|
/* Hack: print a ktap header so kunit.py can find the start of KUnit output. */
|
|
|
|
pr_info("KTAP version 1\n");
|
2021-10-01 06:20:45 +08:00
|
|
|
|
2023-07-26 05:25:12 +08:00
|
|
|
for (suites = suite_set->start; suites < suite_set->end; suites++) {
|
|
|
|
/* Print suite name and suite attributes */
|
|
|
|
pr_info("%s\n", (*suites)->name);
|
|
|
|
if (include_attr)
|
|
|
|
kunit_print_attr((void *)(*suites), false, 0);
|
|
|
|
|
|
|
|
/* Print test case name and attributes in suite */
|
2022-07-09 11:19:58 +08:00
|
|
|
kunit_suite_for_each_test_case((*suites), test_case) {
|
|
|
|
pr_info("%s.%s\n", (*suites)->name, test_case->name);
|
2023-07-26 05:25:12 +08:00
|
|
|
if (include_attr)
|
|
|
|
kunit_print_attr((void *)test_case, true, 0);
|
2021-10-01 06:20:45 +08:00
|
|
|
}
|
2023-07-26 05:25:12 +08:00
|
|
|
}
|
2021-10-01 06:20:45 +08:00
|
|
|
}
|
|
|
|
|
2023-12-14 03:44:17 +08:00
|
|
|
struct kunit_suite_set kunit_merge_suite_sets(struct kunit_suite_set init_suite_set,
|
|
|
|
struct kunit_suite_set suite_set)
|
|
|
|
{
|
|
|
|
struct kunit_suite_set total_suite_set = {NULL, NULL};
|
|
|
|
struct kunit_suite **total_suite_start = NULL;
|
|
|
|
size_t init_num_suites, num_suites, suite_size;
|
2023-12-14 03:44:19 +08:00
|
|
|
int i = 0;
|
2023-12-14 03:44:17 +08:00
|
|
|
|
|
|
|
init_num_suites = init_suite_set.end - init_suite_set.start;
|
|
|
|
num_suites = suite_set.end - suite_set.start;
|
|
|
|
suite_size = sizeof(suite_set.start);
|
|
|
|
|
|
|
|
/* Allocate memory for array of all kunit suites */
|
|
|
|
total_suite_start = kmalloc_array(init_num_suites + num_suites, suite_size, GFP_KERNEL);
|
|
|
|
if (!total_suite_start)
|
|
|
|
return total_suite_set;
|
|
|
|
|
2023-12-14 03:44:19 +08:00
|
|
|
/* Append and mark init suites and then append all other kunit suites */
|
2023-12-14 03:44:17 +08:00
|
|
|
memcpy(total_suite_start, init_suite_set.start, init_num_suites * suite_size);
|
2023-12-14 03:44:19 +08:00
|
|
|
for (i = 0; i < init_num_suites; i++)
|
|
|
|
total_suite_start[i]->is_init = true;
|
|
|
|
|
2023-12-14 03:44:17 +08:00
|
|
|
memcpy(total_suite_start + init_num_suites, suite_set.start, num_suites * suite_size);
|
|
|
|
|
|
|
|
/* Set kunit suite set start and end */
|
|
|
|
total_suite_set.start = total_suite_start;
|
|
|
|
total_suite_set.end = total_suite_start + (init_num_suites + num_suites);
|
|
|
|
|
|
|
|
return total_suite_set;
|
|
|
|
}
|
|
|
|
|
kunit: Make 'list' action available to kunit test modules
Results from kunit tests reported via dmesg may be interleaved with other
kernel messages. When parsing dmesg for modular kunit results in real
time, external tools, e.g., Intel GPU tools (IGT), may want to insert
their own test name markers into dmesg at the start of each test, before
any kernel message related to that test appears there, so existing upper
level test result parsers have no doubt which test to blame for a specific
kernel message. Unfortunately, kunit reports names of tests only at their
completion (with the exeption of a not standarized "# Subtest: <name>"
header above a test plan of each test suite or parametrized test).
External tools could be able to insert their own "start of the test"
markers with test names included if they new those names in advance.
Test names could be learned from a list if provided by a kunit test
module.
There exists a feature of listing kunit tests without actually executing
them, but it is now limited to configurations with the kunit module built
in and covers only built-in tests, already available at boot time.
Moreover, switching from list to normal mode requires reboot. If that
feature was also available when kunit is built as a module, userspace
could load the module with action=list parameter, load some kunit test
modules they are interested in and learn about the list of tests provided
by those modules, then unload them, reload the kunit module in normal mode
and execute the tests with their lists already known.
Extend kunit module notifier initialization callback with a processing
path for only listing the tests provided by a module if the kunit action
parameter is set to "list" or "list_attr". For user convenience, make the
kunit.action parameter visible in sysfs.
v2: Don't use a different format, use kunit_exec_list_tests() (Rae),
- refresh on top of new attributes patches, handle newly introduced
kunit.action=list_attr case (Rae).
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 18:23:55 +08:00
|
|
|
#if IS_BUILTIN(CONFIG_KUNIT)
|
|
|
|
|
2023-08-07 18:23:56 +08:00
|
|
|
static char *kunit_shutdown;
|
|
|
|
core_param(kunit_shutdown, kunit_shutdown, charp, 0644);
|
|
|
|
|
|
|
|
static void kunit_handle_shutdown(void)
|
|
|
|
{
|
|
|
|
if (!kunit_shutdown)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!strcmp(kunit_shutdown, "poweroff"))
|
|
|
|
kernel_power_off();
|
|
|
|
else if (!strcmp(kunit_shutdown, "halt"))
|
|
|
|
kernel_halt();
|
|
|
|
else if (!strcmp(kunit_shutdown, "reboot"))
|
|
|
|
kernel_restart(NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-10-01 06:20:45 +08:00
|
|
|
int kunit_run_all_tests(void)
|
|
|
|
{
|
2023-12-14 03:44:17 +08:00
|
|
|
struct kunit_suite_set suite_set = {NULL, NULL};
|
|
|
|
struct kunit_suite_set filtered_suite_set = {NULL, NULL};
|
|
|
|
struct kunit_suite_set init_suite_set = {
|
|
|
|
__kunit_init_suites_start, __kunit_init_suites_end,
|
|
|
|
};
|
|
|
|
struct kunit_suite_set normal_suite_set = {
|
kunit: Report the count of test suites in a module
According to KTAP specification[1], results should always start from a
header that provides a TAP protocol version, followed by a test plan with
a count of items to be executed. That pattern should be followed at each
nesting level. In the current implementation of the top-most, i.e., test
suite level, those rules apply only for test suites built into the kernel,
executed and reported on boot. Results submitted to dmesg from kunit test
modules loaded later are missing those top-level headers.
As a consequence, if a kunit test module provides more than one test suite
then, without the top level test plan, external tools that are parsing
dmesg for kunit test output are not able to tell how many test suites
should be expected and whether to continue parsing after complete output
from the first test suite is collected.
Submit the top-level headers also from the kunit test module notifier
initialization callback.
v3: Fix new name of a structure moved to kunit namespace not updated in
executor_test functions (lkp@intel.com).
v2: Use kunit_exec_run_tests() (Mauro, Rae), but prevent it from
emitting the headers when called on load of non-test modules.
[1] https://docs.kernel.org/dev-tools/ktap.html#
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 18:23:54 +08:00
|
|
|
__kunit_suites_start, __kunit_suites_end,
|
|
|
|
};
|
2023-12-14 03:44:17 +08:00
|
|
|
size_t init_num_suites = init_suite_set.end - init_suite_set.start;
|
2022-05-14 02:37:07 +08:00
|
|
|
int err = 0;
|
2023-12-14 03:44:17 +08:00
|
|
|
|
|
|
|
if (init_num_suites > 0) {
|
|
|
|
suite_set = kunit_merge_suite_sets(init_suite_set, normal_suite_set);
|
|
|
|
if (!suite_set.start)
|
|
|
|
goto out;
|
|
|
|
} else
|
|
|
|
suite_set = normal_suite_set;
|
|
|
|
|
2022-08-23 22:24:54 +08:00
|
|
|
if (!kunit_enabled()) {
|
|
|
|
pr_info("kunit: disabled\n");
|
2023-12-14 03:44:17 +08:00
|
|
|
goto free_out;
|
2022-08-23 22:24:54 +08:00
|
|
|
}
|
2020-08-05 04:47:42 +08:00
|
|
|
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
if (filter_glob_param || filter_param) {
|
2023-12-14 03:44:17 +08:00
|
|
|
filtered_suite_set = kunit_filter_suites(&suite_set, filter_glob_param,
|
kunit: Add ability to filter attributes
Add filtering of test attributes. Users can filter tests using the
module_param called "filter".
Filters are imputed in the format: <attribute_name><operation><value>
Example: kunit.filter="speed>slow"
Operations include: >, <, >=, <=, !=, and =. These operations will act the
same for attributes of the same type but may not between types.
Note multiple filters can be inputted by separating them with a comma.
Example: kunit.filter="speed=slow, module!=example"
Since both suites and test cases can have attributes, there may be
conflicts. The process of filtering follows these rules:
- Filtering always operates at a per-test level.
- If a test has an attribute set, then the test's value is filtered on.
- Otherwise, the value falls back to the suite's value.
- If neither are set, the attribute has a global "default" value, which
is used.
Filtered tests will not be run or show in output. The tests can instead be
skipped using the configurable option "kunit.filter_action=skip".
Note the default settings for running tests remains unfiltered.
Finally, add "filter" methods for the speed and module attributes to parse
and compare attribute values.
Note this filtering functionality will be added to kunit.py in the next
patch.
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Rae Moar <rmoar@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-07-26 05:25:15 +08:00
|
|
|
filter_param, filter_action_param, &err);
|
2023-12-14 03:44:17 +08:00
|
|
|
|
|
|
|
/* Free original suite set before using filtered suite set */
|
|
|
|
if (init_num_suites > 0)
|
|
|
|
kfree(suite_set.start);
|
|
|
|
suite_set = filtered_suite_set;
|
|
|
|
|
2022-05-12 05:16:26 +08:00
|
|
|
if (err) {
|
|
|
|
pr_err("kunit executor: error filtering suites: %d\n", err);
|
2023-12-14 03:44:17 +08:00
|
|
|
goto free_out;
|
2022-05-12 05:16:26 +08:00
|
|
|
}
|
|
|
|
}
|
2021-02-06 08:08:52 +08:00
|
|
|
|
2021-10-01 06:20:45 +08:00
|
|
|
if (!action_param)
|
kunit: Report the count of test suites in a module
According to KTAP specification[1], results should always start from a
header that provides a TAP protocol version, followed by a test plan with
a count of items to be executed. That pattern should be followed at each
nesting level. In the current implementation of the top-most, i.e., test
suite level, those rules apply only for test suites built into the kernel,
executed and reported on boot. Results submitted to dmesg from kunit test
modules loaded later are missing those top-level headers.
As a consequence, if a kunit test module provides more than one test suite
then, without the top level test plan, external tools that are parsing
dmesg for kunit test output are not able to tell how many test suites
should be expected and whether to continue parsing after complete output
from the first test suite is collected.
Submit the top-level headers also from the kunit test module notifier
initialization callback.
v3: Fix new name of a structure moved to kunit namespace not updated in
executor_test functions (lkp@intel.com).
v2: Use kunit_exec_run_tests() (Mauro, Rae), but prevent it from
emitting the headers when called on load of non-test modules.
[1] https://docs.kernel.org/dev-tools/ktap.html#
Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Rae Moar <rmoar@google.com>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
2023-08-07 18:23:54 +08:00
|
|
|
kunit_exec_run_tests(&suite_set, true);
|
2021-10-01 06:20:45 +08:00
|
|
|
else if (strcmp(action_param, "list") == 0)
|
2023-07-26 05:25:12 +08:00
|
|
|
kunit_exec_list_tests(&suite_set, false);
|
|
|
|
else if (strcmp(action_param, "list_attr") == 0)
|
|
|
|
kunit_exec_list_tests(&suite_set, true);
|
2021-10-01 06:20:45 +08:00
|
|
|
else
|
|
|
|
pr_err("kunit executor: unknown action '%s'\n", action_param);
|
2020-08-05 04:47:44 +08:00
|
|
|
|
2023-12-14 03:44:17 +08:00
|
|
|
free_out:
|
|
|
|
if (filter_glob_param || filter_param)
|
2021-09-15 05:03:48 +08:00
|
|
|
kunit_free_suite_set(suite_set);
|
2023-12-14 03:44:17 +08:00
|
|
|
else if (init_num_suites > 0)
|
|
|
|
/* Don't use kunit_free_suite_set because suites aren't individually allocated */
|
|
|
|
kfree(suite_set.start);
|
2020-08-05 04:47:42 +08:00
|
|
|
|
2022-05-14 02:37:07 +08:00
|
|
|
out:
|
|
|
|
kunit_handle_shutdown();
|
|
|
|
return err;
|
2020-08-05 04:47:42 +08:00
|
|
|
}
|
|
|
|
|
2021-04-21 10:04:27 +08:00
|
|
|
#if IS_BUILTIN(CONFIG_KUNIT_TEST)
|
|
|
|
#include "executor_test.c"
|
|
|
|
#endif
|
|
|
|
|
2020-08-05 04:47:42 +08:00
|
|
|
#endif /* IS_BUILTIN(CONFIG_KUNIT) */
|