[PATCH v7 2/5] bug/kunit: Reduce runtime impact of warning backtrace suppression

From: Albert Esteve

Date: Mon Apr 20 2026 - 08:31:52 EST


From: Alessandro Carminati <acarmina@xxxxxxxxxx>

KUnit support is not consistently present across distributions, some
include it in their stock kernels, while others do not.
While both KUNIT and KUNIT_SUPPRESS_BACKTRACE can be considered debug
features, the fact that some distros ship with KUnit enabled means it's
important to minimize the runtime impact of this patch.

To that end, this patch adds an atomic counter that tracks the number
of active suppressions. __kunit_is_suppressed_warning() checks this
counter first and returns immediately when no suppressions are active,
avoiding RCU-protected list traversal in the common case.

Signed-off-by: Alessandro Carminati <acarmina@xxxxxxxxxx>
Signed-off-by: Albert Esteve <aesteve@xxxxxxxxxx>
---
lib/kunit/bug.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/lib/kunit/bug.c b/lib/kunit/bug.c
index 356c8a5928828..a7a88f0670d44 100644
--- a/lib/kunit/bug.c
+++ b/lib/kunit/bug.c
@@ -8,6 +8,7 @@

#include <kunit/bug.h>
#include <kunit/resource.h>
+#include <linux/atomic.h>
#include <linux/export.h>
#include <linux/rculist.h>
#include <linux/sched.h>
@@ -15,11 +16,13 @@
#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE

static LIST_HEAD(suppressed_warnings);
+static atomic_t suppressed_warnings_cnt = ATOMIC_INIT(0);

static void __kunit_suppress_warning_remove(struct __suppressed_warning *warning)
{
list_del_rcu(&warning->node);
synchronize_rcu(); /* Wait for readers to finish */
+ atomic_dec(&suppressed_warnings_cnt);
}

KUNIT_DEFINE_ACTION_WRAPPER(__kunit_suppress_warning_cleanup,
@@ -37,6 +40,7 @@ __kunit_start_suppress_warning(struct kunit *test)
return NULL;

warning->task = current;
+ atomic_inc(&suppressed_warnings_cnt);
list_add_rcu(&warning->node, &suppressed_warnings);

ret = kunit_add_action_or_reset(test,
@@ -68,6 +72,9 @@ bool __kunit_is_suppressed_warning(void)
{
struct __suppressed_warning *warning;

+ if (!atomic_read(&suppressed_warnings_cnt))
+ return false;
+
rcu_read_lock();
list_for_each_entry_rcu(warning, &suppressed_warnings, node) {
if (warning->task == current) {

--
2.52.0