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

Merge tag 'linux-kselftest-kunit-fixes-5.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull Kunit fixes from Shuah Khan:

- Fixes to address the structleak plugin causing the stack frame size
to grow immensely when used with KUnit. Fixes include adding a new
makefile to disable structleak and using it from KUnit iio, device
property, thunderbolt, and bitfield tests to disable it.

- KUnit framework reference count leak in kfree_at_end

- KUnit tool fix to resolve conflict between --json and --raw_output
and generate correct test output in either case.

- kernel-doc warnings due to mismatched arg names

* tag 'linux-kselftest-kunit-fixes-5.15-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
kunit: fix kernel-doc warnings due to mismatched arg names
bitfield: build kunit tests without structleak plugin
thunderbolt: build kunit tests without structleak plugin
device property: build kunit tests without structleak plugin
iio/test-format: build kunit tests without structleak plugin
gcc-plugins/structleak: add makefile var for disabling structleak
kunit: fix reference count leak in kfree_at_end
kunit: tool: better handling of quasi-bool args (--json, --raw_output)

+43 -9
+1 -1
drivers/base/test/Makefile
··· 2 2 obj-$(CONFIG_TEST_ASYNC_DRIVER_PROBE) += test_async_driver_probe.o 3 3 4 4 obj-$(CONFIG_DRIVER_PE_KUNIT_TEST) += property-entry-test.o 5 - CFLAGS_REMOVE_property-entry-test.o += -fplugin-arg-structleak_plugin-byref -fplugin-arg-structleak_plugin-byref-all 5 + CFLAGS_property-entry-test.o += $(DISABLE_STRUCTLEAK_PLUGIN)
+1
drivers/iio/test/Makefile
··· 5 5 6 6 # Keep in alphabetical order 7 7 obj-$(CONFIG_IIO_TEST_FORMAT) += iio-test-format.o 8 + CFLAGS_iio-test-format.o += $(DISABLE_STRUCTLEAK_PLUGIN)
+1
drivers/thunderbolt/Makefile
··· 7 7 thunderbolt-${CONFIG_ACPI} += acpi.o 8 8 thunderbolt-$(CONFIG_DEBUG_FS) += debugfs.o 9 9 thunderbolt-${CONFIG_USB4_KUNIT_TEST} += test.o 10 + CFLAGS_test.o += $(DISABLE_STRUCTLEAK_PLUGIN) 10 11 11 12 thunderbolt_dma_test-${CONFIG_USB4_DMA_TEST} += dma_test.o 12 13 obj-$(CONFIG_USB4_DMA_TEST) += thunderbolt_dma_test.o
+3 -3
include/kunit/test.h
··· 613 613 * and is automatically cleaned up after the test case concludes. See &struct 614 614 * kunit_resource for more information. 615 615 */ 616 - void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t flags); 616 + void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp); 617 617 618 618 /** 619 619 * kunit_kmalloc() - Like kmalloc() except the allocation is *test managed*. ··· 657 657 * 658 658 * See kcalloc() and kunit_kmalloc_array() for more information. 659 659 */ 660 - static inline void *kunit_kcalloc(struct kunit *test, size_t n, size_t size, gfp_t flags) 660 + static inline void *kunit_kcalloc(struct kunit *test, size_t n, size_t size, gfp_t gfp) 661 661 { 662 - return kunit_kmalloc_array(test, n, size, flags | __GFP_ZERO); 662 + return kunit_kmalloc_array(test, n, size, gfp | __GFP_ZERO); 663 663 } 664 664 665 665 void kunit_cleanup(struct kunit *test);
+1 -1
lib/Makefile
··· 351 351 obj-$(CONFIG_PLDMFW) += pldmfw/ 352 352 353 353 # KUnit tests 354 - CFLAGS_bitfield_kunit.o := $(call cc-option,-Wframe-larger-than=10240) 354 + CFLAGS_bitfield_kunit.o := $(DISABLE_STRUCTLEAK_PLUGIN) 355 355 obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o 356 356 obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o 357 357 obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o
+2 -2
lib/kunit/executor_test.c
··· 116 116 /* kfree() handles NULL already, but avoid allocating a no-op cleanup. */ 117 117 if (IS_ERR_OR_NULL(to_free)) 118 118 return; 119 - kunit_alloc_and_get_resource(test, NULL, kfree_res_free, GFP_KERNEL, 120 - (void *)to_free); 119 + kunit_alloc_resource(test, NULL, kfree_res_free, GFP_KERNEL, 120 + (void *)to_free); 121 121 } 122 122 123 123 static struct kunit_suite *alloc_fake_suite(struct kunit *test,
+4
scripts/Makefile.gcc-plugins
··· 19 19 += -fplugin-arg-structleak_plugin-byref 20 20 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) \ 21 21 += -fplugin-arg-structleak_plugin-byref-all 22 + ifdef CONFIG_GCC_PLUGIN_STRUCTLEAK 23 + DISABLE_STRUCTLEAK_PLUGIN += -fplugin-arg-structleak_plugin-disable 24 + endif 25 + export DISABLE_STRUCTLEAK_PLUGIN 22 26 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \ 23 27 += -DSTRUCTLEAK_PLUGIN 24 28
+22 -2
tools/testing/kunit/kunit.py
··· 16 16 17 17 from collections import namedtuple 18 18 from enum import Enum, auto 19 - from typing import Iterable 19 + from typing import Iterable, Sequence 20 20 21 21 import kunit_config 22 22 import kunit_json ··· 186 186 exec_result.elapsed_time)) 187 187 return parse_result 188 188 189 + # Problem: 190 + # $ kunit.py run --json 191 + # works as one would expect and prints the parsed test results as JSON. 192 + # $ kunit.py run --json suite_name 193 + # would *not* pass suite_name as the filter_glob and print as json. 194 + # argparse will consider it to be another way of writing 195 + # $ kunit.py run --json=suite_name 196 + # i.e. it would run all tests, and dump the json to a `suite_name` file. 197 + # So we hackily automatically rewrite --json => --json=stdout 198 + pseudo_bool_flag_defaults = { 199 + '--json': 'stdout', 200 + '--raw_output': 'kunit', 201 + } 202 + def massage_argv(argv: Sequence[str]) -> Sequence[str]: 203 + def massage_arg(arg: str) -> str: 204 + if arg not in pseudo_bool_flag_defaults: 205 + return arg 206 + return f'{arg}={pseudo_bool_flag_defaults[arg]}' 207 + return list(map(massage_arg, argv)) 208 + 189 209 def add_common_opts(parser) -> None: 190 210 parser.add_argument('--build_dir', 191 211 help='As in the make command, it specifies the build ' ··· 323 303 help='Specifies the file to read results from.', 324 304 type=str, nargs='?', metavar='input_file') 325 305 326 - cli_args = parser.parse_args(argv) 306 + cli_args = parser.parse_args(massage_argv(argv)) 327 307 328 308 if get_kernel_root_path(): 329 309 os.chdir(get_kernel_root_path())
+8
tools/testing/kunit/kunit_tool_test.py
··· 408 408 self.assertNotEqual(call, mock.call(StrContains('Testing complete.'))) 409 409 self.assertNotEqual(call, mock.call(StrContains(' 0 tests run'))) 410 410 411 + def test_run_raw_output_does_not_take_positional_args(self): 412 + # --raw_output is a string flag, but we don't want it to consume 413 + # any positional arguments, only ones after an '=' 414 + self.linux_source_mock.run_kernel = mock.Mock(return_value=[]) 415 + kunit.main(['run', '--raw_output', 'filter_glob'], self.linux_source_mock) 416 + self.linux_source_mock.run_kernel.assert_called_once_with( 417 + args=None, build_dir='.kunit', filter_glob='filter_glob', timeout=300) 418 + 411 419 def test_exec_timeout(self): 412 420 timeout = 3453 413 421 kunit.main(['exec', '--timeout', str(timeout)], self.linux_source_mock)