On Tue 2025-07-08 16:48:47, Arnd Bergmann wrote: > On Tue, Jul 8, 2025, at 16:24, Petr Mladek wrote: > > On Wed 2025-07-02 13:28:35, Nathan Chancellor wrote: > >> On Wed, Jul 02, 2025 at 11:51:56AM +0200, Petr Mladek wrote: > > > > Thanks a lot for the nice report. > > > > The problem is how cpumask_var_t is defined in > > include/linux/cpumask_types.h: > > > > #ifdef CONFIG_CPUMASK_OFFSTACK > > typedef struct cpumask *cpumask_var_t; > > #else > > typedef struct cpumask cpumask_var_t[1]; > > #endif /* CONFIG_CPUMASK_OFFSTACK */ > > > > And KUNIT_DEFINE_ACTION_WRAPPER() expect that the 3rd parameter > > is a pointer. > > > > I am going to solve this by adding a wrapper over free_cpumask_var() > > which would work with a pointer to cpumask_var_t. > > I'm not familiar enough with the cleanup mechanism of kunit, > but can't you just move the mask allocation outside of > test_readerwriter()?
The only solution would be global variable. test_readerwriter() is the top-level function passed to KUnit framework via: KUNIT_CASE_SLOW(test_readerwriter), And it seems that the clean is even done in a separate process. I see the following: KUNIT_CASE_SLOW() sets .run_case() The callback is called via via: + kunit_try_run_case() + kunit_run_case_internal() + test_case->run_case() And kunit_try_run_case() is called via: + kunit_run_case_catch_errors() + kunit_try_catch_run() + kthread_create() -> kunit_try_run_case() in the new thread The clean up is called from the same kunit_run_case_catch_errors() in another thread + kunit_try_catch_run() + kthread_create() -> kunit_try_run_case_cleanup() in another new thread > > + */ > > +static void prbtest_free_cpumask_var(cpumask_var_t *mask) > > +{ > > + free_cpumask_var(*mask); > > +} > > Or you could pass this as a cpumask_t pointer instead, > which should do the right thing without the indirection. Nice trick. I am going to try it. > > KUNIT_ASSERT_TRUE(test, alloc_cpumask_var(&test_cpus, GFP_KERNEL)); > > - err = kunit_add_action_or_reset(test, prbtest_cpumask_cleanup, > > test_cpus); > > + err = kunit_add_action_or_reset(test, prbtest_cpumask_cleanup, > > &test_cpus); > > In my original version, I did not have the > KUNIT_ASSERT_TRUE() here, which seems sufficient since this > is not what you are testing at all, and in normal systems > this would just be a stack variable. I think that KUNIT_ASSERT is standard handling of any problem in the test. At least, I see KUNIT_ASSERT*() after any *malloc*() in the code samples in Documentation/dev-tools/kunit/usage.rst Best Regards, Petr