kunit: split out part of kunit_assert into a static const
authorDaniel Latypov <dlatypov@google.com>
Thu, 13 Jan 2022 16:59:30 +0000 (08:59 -0800)
committerShuah Khan <skhan@linuxfoundation.org>
Tue, 25 Jan 2022 19:49:59 +0000 (12:49 -0700)
commit21957f90b28f6bc118c055e3e564d45f6e4df45d
tree0e952d2553288471e36211108252893bc92d4e35
parentdd640d70874bd27fb081d444252677766321c32f
kunit: split out part of kunit_assert into a static const

This is per Linus's suggestion in [1].

The issue there is that every KUNIT_EXPECT/KUNIT_ASSERT puts a
kunit_assert object onto the stack. Normally we rely on compilers to
elide this, but when that doesn't work out, this blows up the stack
usage of kunit test functions.

We can move some data off the stack by making it static.
This change introduces a new `struct kunit_loc` to hold the file and
line number and then just passing assert_type (EXPECT or ASSERT) as an
argument.

In [1], it was suggested to also move out the format string as well, but
users could theoretically craft a format string at runtime, so we can't.

This change leaves a copy of `assert_type` in kunit_assert for now
because cleaning up all the macros to not pass it around is a bit more
involved.

Here's an example of the expanded code for KUNIT_FAIL():
if (__builtin_expect(!!(!(false)), 0)) {
  static const struct kunit_loc loc = { .file = ... };
  struct kunit_fail_assert __assertion = { .assert = { .type ...  };
  kunit_do_failed_assertion(test, &loc, KUNIT_EXPECTATION, &__assertion.assert, ...);
};

[1] https://groups.google.com/g/kunit-dev/c/i3fZXgvBrfA/m/VULQg1z6BAAJ

Signed-off-by: Daniel Latypov <dlatypov@google.com>
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Reviewed-by: David Gow <davidgow@google.com>
Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
include/kunit/assert.h
include/kunit/test.h
lib/kunit/assert.c
lib/kunit/test.c