Hi David, On Tue, 2023-04-18 at 14:53 +0800, David Gow wrote: > On Mon, 17 Apr 2023 at 18:43, Benjamin Berg <benjamin@xxxxxxxxxxxxxxxx> wrote: > > > > Hi, > > > > On Sat, 2023-04-15 at 17:14 +0800, David Gow wrote: > > > KUnit tests run in a kthread, with the current->kunit_test pointer set > > > to the test's context. This allows the kunit_get_current_test() and > > > kunit_fail_current_test() macros to work. Normally, this pointer is > > > still valid during test shutdown (i.e., the suite->exit function, and > > > any resource cleanup). However, if the test has exited early (e.g., due > > > to a failed assertion), the cleanup is done in the parent KUnit thread, > > > which does not have an active context. > > > > My only question here is whether assertions (not expectations) are OK > > within the exit/cleanup handler. That said, it wouldn't be clear > > whether we should try to continue cleaning up after every failure, so > > probably it is reasonable to not do that. > > Excellent point. > In general: > - It's okay to use expectations within exit and cleanup functions. > - It's not okay for assertions to fail within an exit / cleanup handler. > - It's not okay to access anything which was allocated on the stack > from within a test in exit / cleanup handlers. > - It's okay to access and free resources from within cleanup / exit > handlers, though it's not permitted to create new resources from > cleanup handlers (exit is okay). The list makes sense to me. > I do think we need to document this better, at the very least. > > What I think we'll end up doing is implementing a different system: > - The test (and, if successful, cleanup) runs in a kthread. > - If it aborts (e.g., due to an assertion), cleanup runs in another kthread. > - If this second kthread aborts early, no further cleanup is run. > > This would protect the KUnit executor thread from misbehaving cleanup > functions, and if an assertion happens in a cleanup function, we'll > leak things (which is bad), but not dereference a bunch of invalid > pointers (which is worse). Sounds good. > I've got this mostly working here, and will send it out as a > replacement to this patch (that second kthread will have > current->kunit_test set, rendering this change redundant). Cool! > > But, I did see that at least the clock tests currently use assertions > > inside the init function. And, in those tests, if the context > > allocation fails the exit handler will dereference the NULL pointer. > > Hmm... which clock test is that? Regardless, it sounds like a bug in the test. > > I think that ultimately, the right solution for dealing with the > context pointer issue is to use resources (or, when available, > kunit_add_action()), which nicely enforces the ordering as well. In > the meantime, though, I guess it just needs wrapping in a lot of "if > (ctx)" or similar... I am talking about drivers/clk/clk-gate_test.c. The _init functions (and clk_gate_test_alloc_ctx) use assertions heavily. The _exit handles does not deal with the ctx being NULL though. But, the fix is trivial though: diff --git a/drivers/clk/clk-gate_test.c b/drivers/clk/clk-gate_test.c index e136aaad48bf..f1adafe725e4 100644 --- a/drivers/clk/clk-gate_test.c +++ b/drivers/clk/clk-gate_test.c @@ -225,6 +225,9 @@ static void clk_gate_test_exit(struct kunit *test) { struct clk_gate_test_context *ctx = test->priv; + if (!ctx) + return; + clk_hw_unregister_gate(ctx->hw); clk_hw_unregister_fixed_rate(ctx->parent); } > > So, nothing for this patch, but maybe it would make sense to mark tests > > as failed (or print a warning) if they use assertions inside init, exit > > or cleanup handlers? > > > > I think we'll still want to support assertions in init functions > (albeit possibly with some documentation pointing out any pitfalls). > If actions or resources are used, it's not a problem. Yeah, a short sentence in the "struct kunit_suite" documentation should be enough. Something along the lines of: "This call to @exit will always happen, even if @init returned an error or aborted due to an assertion.". > Also, a lot of these issues also apply to kunit_skip(), which is used > _heavily_ in init functions. > > Warnings for assertions in exit or cleanup make sense. I _could_ see a > reason to allow assertions if we wanted to have, e.g., helpers which > asserted that their inputs were valid -- it'd be a bit rough to deny > their use if the inputs are known to be okay -- but I'm not aware of > any such case in practice yet, so I suspect it's still worth failing > tests (and seeing if anyone complains). I am not going to insist on disallowing or warning about assertions. It is OK from my point of view, as long as the damage is contained to a kunit kthread and "only" affects cleanup. Benjamin