lkml.org 
[lkml]   [2020]   [Jan]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] [RFC] kunit: move binary assertion out of line
Date
In combination with the structleak gcc plugin, kunit can lead to excessive
stack usage when each assertion adds another structure to the stack from
of the calling function:

base/test/property-entry-test.c:99:1: error: the frame size of 3032 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]

As most assertions are binary, change those over to a direct function
call that does not have this problem. This can probably be improved
further, I just went for a straightforward conversion, but a function
call with 12 fixed arguments plus varargs it not great either.

Cc: Kees Cook <keescook@chromium.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brendan Higgins <brendanhiggins@google.com>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: linux-kselftest@vger.kernel.org
Cc: kunit-dev@googlegroups.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
I think improving the compiler or the plugin to not force the
allocation of these structs would be better, as it avoids the
whack-a-mole game of fixing up each time it hits us, but this
may not be possible using the current plugin infrastructure.
---
include/kunit/test.h | 155 ++++++++++++-------------------------------
lib/kunit/assert.c | 8 +--
lib/kunit/test.c | 42 ++++++++++++
3 files changed, 90 insertions(+), 115 deletions(-)

diff --git a/include/kunit/test.h b/include/kunit/test.h
index dba48304b3bd..76eadd4a8b77 100644
--- a/include/kunit/test.h
+++ b/include/kunit/test.h
@@ -391,6 +391,16 @@ void kunit_do_assertion(struct kunit *test,
bool pass,
const char *fmt, ...);

+void kunit_do_binary_assertion(struct kunit *test, bool pass,
+ enum kunit_assert_type type,
+ int line, const char *file,
+ const char *operation,
+ const char *left_text, long long left_value,
+ const char *right_text, long long right_value,
+ void (*format)(const struct kunit_assert *assert,
+ struct string_stream *stream),
+ const char *fmt, ...);
+
#define KUNIT_ASSERTION(test, pass, assert_class, INITIALIZER, fmt, ...) do { \
struct assert_class __assertion = INITIALIZER; \
kunit_do_assertion(test, \
@@ -491,19 +501,32 @@ do { \
typeof(left) __left = (left); \
typeof(right) __right = (right); \
((void)__typecheck(__left, __right)); \
- \
- KUNIT_ASSERTION(test, \
- __left op __right, \
- assert_class, \
- ASSERT_CLASS_INIT(test, \
- assert_type, \
- #op, \
- #left, \
- __left, \
- #right, \
- __right), \
- fmt, \
- ##__VA_ARGS__); \
+ kunit_do_binary_assertion(test, left op right, assert_type, \
+ __LINE__, __FILE__, #op, #left, __left, \
+ #right, __right, \
+ kunit_binary_assert_format, \
+ fmt, ##__VA_ARGS__); \
+} while (0)
+
+#define KUNIT_BASE_POINTER_ASSERTION(test, \
+ assert_class, \
+ ASSERT_CLASS_INIT, \
+ assert_type, \
+ left, \
+ op, \
+ right, \
+ fmt, \
+ ...) \
+do { \
+ typeof(left) __left = (left); \
+ typeof(right) __right = (right); \
+ ((void)__typecheck(__left, __right)); \
+ kunit_do_binary_assertion(test, left op right, assert_type, \
+ __LINE__, __FILE__, #op, \
+ #left, (uintptr_t)__left, \
+ #right, (uintptr_t)__right, \
+ kunit_binary_ptr_assert_format, \
+ fmt, ##__VA_ARGS__); \
} while (0)

#define KUNIT_BASE_EQ_MSG_ASSERTION(test, \
@@ -625,12 +648,11 @@ do { \
right, \
fmt, \
...) \
- KUNIT_BASE_EQ_MSG_ASSERTION(test, \
- kunit_binary_ptr_assert, \
- KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \
+ KUNIT_BASE_POINTER_ASSERTION(test, \
+ assert_class, \
+ ASSERT_CLASS_INIT, \
assert_type, \
- left, \
- right, \
+ left, ==, right, \
fmt, \
##__VA_ARGS__)

@@ -664,12 +686,11 @@ do { \
right, \
fmt, \
...) \
- KUNIT_BASE_NE_MSG_ASSERTION(test, \
- kunit_binary_ptr_assert, \
- KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \
+ KUNIT_BASE_POINTER_ASSERTION(test, \
+ assert_class, \
+ ASSERT_CLASS_INIT, \
assert_type, \
- left, \
- right, \
+ left, !=, right, \
fmt, \
##__VA_ARGS__)

@@ -697,28 +718,6 @@ do { \
right, \
NULL)

-#define KUNIT_BINARY_PTR_LT_MSG_ASSERTION(test, \
- assert_type, \
- left, \
- right, \
- fmt, \
- ...) \
- KUNIT_BASE_LT_MSG_ASSERTION(test, \
- kunit_binary_ptr_assert, \
- KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \
- assert_type, \
- left, \
- right, \
- fmt, \
- ##__VA_ARGS__)
-
-#define KUNIT_BINARY_PTR_LT_ASSERTION(test, assert_type, left, right) \
- KUNIT_BINARY_PTR_LT_MSG_ASSERTION(test, \
- assert_type, \
- left, \
- right, \
- NULL)
-
#define KUNIT_BINARY_LE_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\
KUNIT_BASE_LE_MSG_ASSERTION(test, \
kunit_binary_assert, \
@@ -736,28 +735,6 @@ do { \
right, \
NULL)

-#define KUNIT_BINARY_PTR_LE_MSG_ASSERTION(test, \
- assert_type, \
- left, \
- right, \
- fmt, \
- ...) \
- KUNIT_BASE_LE_MSG_ASSERTION(test, \
- kunit_binary_ptr_assert, \
- KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \
- assert_type, \
- left, \
- right, \
- fmt, \
- ##__VA_ARGS__)
-
-#define KUNIT_BINARY_PTR_LE_ASSERTION(test, assert_type, left, right) \
- KUNIT_BINARY_PTR_LE_MSG_ASSERTION(test, \
- assert_type, \
- left, \
- right, \
- NULL)
-
#define KUNIT_BINARY_GT_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\
KUNIT_BASE_GT_MSG_ASSERTION(test, \
kunit_binary_assert, \
@@ -775,28 +752,6 @@ do { \
right, \
NULL)

-#define KUNIT_BINARY_PTR_GT_MSG_ASSERTION(test, \
- assert_type, \
- left, \
- right, \
- fmt, \
- ...) \
- KUNIT_BASE_GT_MSG_ASSERTION(test, \
- kunit_binary_ptr_assert, \
- KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \
- assert_type, \
- left, \
- right, \
- fmt, \
- ##__VA_ARGS__)
-
-#define KUNIT_BINARY_PTR_GT_ASSERTION(test, assert_type, left, right) \
- KUNIT_BINARY_PTR_GT_MSG_ASSERTION(test, \
- assert_type, \
- left, \
- right, \
- NULL)
-
#define KUNIT_BINARY_GE_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\
KUNIT_BASE_GE_MSG_ASSERTION(test, \
kunit_binary_assert, \
@@ -814,28 +769,6 @@ do { \
right, \
NULL)

-#define KUNIT_BINARY_PTR_GE_MSG_ASSERTION(test, \
- assert_type, \
- left, \
- right, \
- fmt, \
- ...) \
- KUNIT_BASE_GE_MSG_ASSERTION(test, \
- kunit_binary_ptr_assert, \
- KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \
- assert_type, \
- left, \
- right, \
- fmt, \
- ##__VA_ARGS__)
-
-#define KUNIT_BINARY_PTR_GE_ASSERTION(test, assert_type, left, right) \
- KUNIT_BINARY_PTR_GE_MSG_ASSERTION(test, \
- assert_type, \
- left, \
- right, \
- NULL)
-
#define KUNIT_BINARY_STR_ASSERTION(test, \
assert_type, \
left, \
diff --git a/lib/kunit/assert.c b/lib/kunit/assert.c
index 86013d4cf891..abb6c70de925 100644
--- a/lib/kunit/assert.c
+++ b/lib/kunit/assert.c
@@ -101,8 +101,8 @@ void kunit_binary_assert_format(const struct kunit_assert *assert,
void kunit_binary_ptr_assert_format(const struct kunit_assert *assert,
struct string_stream *stream)
{
- struct kunit_binary_ptr_assert *binary_assert = container_of(
- assert, struct kunit_binary_ptr_assert, assert);
+ struct kunit_binary_assert *binary_assert = container_of(
+ assert, struct kunit_binary_assert, assert);

kunit_base_assert_format(assert, stream);
string_stream_add(stream,
@@ -112,10 +112,10 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert,
binary_assert->right_text);
string_stream_add(stream, "\t\t%s == %pK\n",
binary_assert->left_text,
- binary_assert->left_value);
+ (void *)(uintptr_t)binary_assert->left_value);
string_stream_add(stream, "\t\t%s == %pK",
binary_assert->right_text,
- binary_assert->right_value);
+ (void *)(uintptr_t)binary_assert->right_value);
kunit_assert_print_msg(assert, stream);
}

diff --git a/lib/kunit/test.c b/lib/kunit/test.c
index c83c0fa59cbd..937f3fbe5ecc 100644
--- a/lib/kunit/test.c
+++ b/lib/kunit/test.c
@@ -172,6 +172,48 @@ void kunit_do_assertion(struct kunit *test,
kunit_abort(test);
}

+void kunit_do_binary_assertion(struct kunit *test, bool pass,
+ enum kunit_assert_type type,
+ int line, const char *file,
+ const char *operation,
+ const char *left_text, long long left_value,
+ const char *right_text, long long right_value,
+ void (*format)(const struct kunit_assert *assert,
+ struct string_stream *stream),
+ const char *fmt, ...)
+{
+ va_list args;
+ struct kunit_binary_assert assert = {
+ .assert = {
+ .test = test,
+ .type = type,
+ .file = file,
+ .line = line,
+ .message.fmt = fmt,
+ .format = format,
+ },
+ .operation = operation,
+ .left_text = left_text,
+ .left_value = left_value,
+ .right_text = right_text,
+ .right_value = right_value,
+ };
+
+ if (pass)
+ return;
+
+ va_start(args, fmt);
+
+ assert.assert.message.va = &args;
+
+ kunit_fail(test, &assert.assert);
+
+ va_end(args);
+
+ if (type == KUNIT_ASSERTION)
+ kunit_abort(test);
+}
+
void kunit_init_test(struct kunit *test, const char *name)
{
spin_lock_init(&test->lock);
--
2.20.0
\
 
 \ /
  Last update: 2020-01-10 14:45    [W:0.087 / U:2.284 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site