From nobody Mon May 4 13:05:03 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4EC983033D8 for ; Mon, 4 May 2026 07:41:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777880516; cv=none; b=TIGxEy7SSdo2sEMwY9jVX1ZE7pmOgUTf/zt/NgyfeEJVlxpTZ3fjbGiylcoHkzN8rsdsA8S3qTlHlD0DY1gLVjwn2F3eC0ixIIQHIYtBDKKqHwmZpAe6E8hjPXdPQB5KTqw8lCnRrT3wefFCx0VZ+YWS4l0YaRsYtSgcFgZvEdE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777880516; c=relaxed/simple; bh=GNdvAC8sHBx5/8S/Zejd93zYlV6/VkBsLGLLeTwRn2U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RVD+H9wtiFX3swKvvOvahayis5/9NYerOLb9YPK0BHumxNC6BMw35FrbvUh1leyE30ioma+2IW6BabTvKIesBM/PpthsuaYCRxF4DWmR/si4k8noaOWRpHl9IB6B41Xs2O6r4qYOqD2AC7O3LTgZrgOy0kvuQztJUsor8nwa6M8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=iXwfPmSq; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="iXwfPmSq" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777880513; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SihS4JGcYsSmzE0brJNfGHdNWEU7ElGTdUVbaM8VyK0=; b=iXwfPmSqo6Vtg2yH12fgD5BExWs445ry5sJAKN18gM4L+TeNAdE+c6K1XcXPCdcHXmRuYX ofhDsyoWwJsCDmoCuDCjJHd6WogW85JcUKplo5W+Cww9v3h2p5+hmAgaISyjyR/cOeko7l r3sspHXdnicF/X+qiT/qpTheWeO4EzQ= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-47-offhDADgPUiP1Zaj9PkHRg-1; Mon, 04 May 2026 03:41:52 -0400 X-MC-Unique: offhDADgPUiP1Zaj9PkHRg-1 X-Mimecast-MFC-AGG-ID: offhDADgPUiP1Zaj9PkHRg_1777880509 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 60108195608B; Mon, 4 May 2026 07:41:48 +0000 (UTC) Received: from [192.168.1.153] (headnet01.pony-001.prod.iad2.dc.redhat.com [10.2.32.101]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 66CC61955D84; Mon, 4 May 2026 07:41:40 +0000 (UTC) From: Albert Esteve Date: Mon, 04 May 2026 09:41:25 +0200 Subject: [PATCH v8 1/4] bug/kunit: Core support for suppressing warning backtraces Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260504-kunit_add_support-v8-1-3e5957cdd235@redhat.com> References: <20260504-kunit_add_support-v8-0-3e5957cdd235@redhat.com> In-Reply-To: <20260504-kunit_add_support-v8-0-3e5957cdd235@redhat.com> To: Arnd Bergmann , Brendan Higgins , David Gow , Rae Moar , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Jonathan Corbet , Shuah Khan , Andrew Morton , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti Cc: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, dri-devel@lists.freedesktop.org, workflows@vger.kernel.org, linux-riscv@lists.infradead.org, linux-doc@vger.kernel.org, peterz@infradead.org, Alessandro Carminati , Guenter Roeck , Kees Cook , Albert Esteve X-Developer-Signature: v=1; a=ed25519-sha256; t=1777880489; l=18309; i=aesteve@redhat.com; s=20260303; h=from:subject:message-id; bh=uN2I6Fp+4/YHL/oz10z31iz8wYI+THuQblw36b8ziNY=; b=FPH6CHtOk9//Vph8dml/BTJVFCUvNIPWO6dOpEmWF3MIdpOWF7KSeM9QnyTMoHc8/zhhP4gWB 6LHRAVuQTYVCKQG4ofWYsOvPAbemtHmC1O14uPqPbi9VHm4MxaBnsd4 X-Developer-Key: i=aesteve@redhat.com; a=ed25519; pk=YSFz6sOHd2L45+Fr8DIvHTi6lSIjhLZ5T+rkxspJt1s= X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 From: Alessandro Carminati Some unit tests intentionally trigger warning backtraces by passing bad parameters to kernel API functions. Such unit tests typically check the return value from such calls, not the existence of the warning backtrace. Such intentionally generated warning backtraces are neither desirable nor useful for a number of reasons: - They can result in overlooked real problems. - A warning that suddenly starts to show up in unit tests needs to be investigated and has to be marked to be ignored, for example by adjusting filter scripts. Such filters are ad hoc because there is no real standard format for warnings. On top of that, such filter scripts would require constant maintenance. Solve the problem by providing a means to suppress warning backtraces originating from the current kthread while executing test code. Since each KUnit test runs in its own kthread, this effectively scopes suppression to the test that enabled it. Limit changes to generic code to the absolute minimum. Implementation details: Suppression is integrated into the existing KUnit hooks infrastructure in test-bug.h, reusing the kunit_running static branch for zero overhead when no tests are running. Suppression is checked at three points in the warning path: - In warn_slowpath_fmt(), the check runs before any output, fully suppressing both message and backtrace. This covers architectures without __WARN_FLAGS. - In __warn_printk(), the check suppresses the warning message text. This covers architectures that define __WARN_FLAGS but not their own __WARN_printf (arm64, loongarch, parisc, powerpc, riscv, sh), where the message is printed before the trap enters __report_bug(). - In __report_bug(), the check runs before __warn() is called, suppressing the backtrace and stack dump. To avoid double-counting on architectures where both __warn_printk() and __report_bug() run for the same warning, kunit_is_suppressed_warning() takes a bool parameter: true to increment the suppression counter (used in warn_slowpath_fmt and __report_bug), false to check only (used in __warn_printk). The suppression state is dynamically allocated via kunit_kzalloc() and tied to the KUnit test lifecycle via kunit_add_action(), ensuring automatic cleanup at test exit. Writer-side access to the global suppression list is serialized with a spinlock; readers use RCU. Three API forms are provided: - kunit_warning_suppress(test) { ... }: scoped, uses __cleanup for automatic teardown on scope exit, kunit_add_action() as safety net for abnormal exits (e.g. kthread_exit from failed assertions). Suppression handle is only accessible inside the block. - KUNIT_START/END_SUPPRESSED_WARNING(test): manual macros for larger blocks or when warning counts need to be checked after suppression ends. Limited to one pair per scope. - kunit_start/end_suppress_warning(test): direct functions returning an explicit handle, for retaining the handle within the test, or for cross-function usage. Signed-off-by: Guenter Roeck Signed-off-by: Alessandro Carminati Reviewed-by: Kees Cook Signed-off-by: Albert Esteve --- include/kunit/test-bug.h | 25 +++++++++ include/kunit/test.h | 138 +++++++++++++++++++++++++++++++++++++++++++= ++++ kernel/panic.c | 15 +++++- lib/bug.c | 10 ++++ lib/kunit/Makefile | 3 +- lib/kunit/bug.c | 115 +++++++++++++++++++++++++++++++++++++++ lib/kunit/hooks-impl.h | 2 + 7 files changed, 305 insertions(+), 3 deletions(-) diff --git a/include/kunit/test-bug.h b/include/kunit/test-bug.h index 47aa8f21ccce8..6237e48ceadfd 100644 --- a/include/kunit/test-bug.h +++ b/include/kunit/test-bug.h @@ -23,6 +23,7 @@ DECLARE_STATIC_KEY_FALSE(kunit_running); extern struct kunit_hooks_table { __printf(3, 4) void (*fail_current_test)(const char*, int, const char*, .= ..); void *(*get_static_stub_address)(struct kunit *test, void *real_fn_addr); + bool (*is_suppressed_warning)(bool count); } kunit_hooks; =20 /** @@ -60,9 +61,33 @@ static inline struct kunit *kunit_get_current_test(void) } \ } while (0) =20 +/** + * kunit_is_suppressed_warning() - Check if warnings are being suppressed + * by the current KUnit test. + * @count: if true, increment the suppression counter on match. + * + * Returns true if the current task has active warning suppression. + * Uses the kunit_running static branch for zero overhead when no tests ru= n. + * + * A single WARN*() may traverse multiple call sites in the warning path + * (e.g., __warn_printk() and __report_bug()). Pass @count =3D true at the + * primary suppression point to count each warning exactly once, and + * @count =3D false at secondary points to suppress output without + * inflating the count. + */ +static inline bool kunit_is_suppressed_warning(bool count) +{ + if (!static_branch_unlikely(&kunit_running)) + return false; + + return kunit_hooks.is_suppressed_warning && + kunit_hooks.is_suppressed_warning(count); +} + #else =20 static inline struct kunit *kunit_get_current_test(void) { return NULL; } +static inline bool kunit_is_suppressed_warning(bool count) { return false;= } =20 #define kunit_fail_current_test(fmt, ...) do {} while (0) =20 diff --git a/include/kunit/test.h b/include/kunit/test.h index 9cd1594ab697d..f278ec028019c 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -1795,4 +1795,142 @@ do { \ // include resource.h themselves if they need it. #include =20 +/* + * Warning backtrace suppression API. + * + * Suppresses WARN*() backtraces on the current task while active. Three f= orms + * are provided, in order of convenience: + * + * - Scoped: kunit_warning_suppress(test) { ... } + * Suppression is active for the duration of the block. On normal exit, + * the for-loop increment deactivates suppression. On early exit (break, + * return, goto), the __cleanup attribute fires. On kthread_exit() (e.g., + * a failed KUnit assertion), kunit_add_action() cleans up at test + * teardown. The suppression handle is only accessible inside the block, + * so warning counts must be checked before the block exits. + * + * - Manual macros: KUNIT_[START|END]_SUPPRESSED_WARNING(test) + * Suppression spans an explicit range in the same scope. kunit_add_acti= on() + * guarantees cleanup even if KUNIT_END_SUPPRESSED_WARNING() is not reac= hed. + * Prefer this form when suppressing warnings across a large block where + * extra indentation is undesirable, or when the warning count needs to = be + * checked after suppression ends. Limited to one pair per scope. + * + * - Direct: kunit_start_suppress_warning() / kunit_end_suppress_warning() + * The underlying functions, returning an explicit handle pointer. Use + * when the handle needs to be retained (e.g., for post-suppression + * count checks) or passed across helper functions. + */ +struct kunit_suppressed_warning; + +struct kunit_suppressed_warning * +kunit_start_suppress_warning(struct kunit *test); +void kunit_end_suppress_warning(struct kunit *test, + struct kunit_suppressed_warning *w); +int kunit_suppressed_warning_count(struct kunit_suppressed_warning *w); +void __kunit_suppress_auto_cleanup(struct kunit_suppressed_warning **wp); +bool kunit_has_active_suppress_warning(void); + +/** + * kunit_warning_suppress() - Suppress WARN*() backtraces for the duration + * of a block. + * @test: The test context object. + * + * Scoped form of the suppression API. Suppression starts when the block is + * entered and ends automatically when the block exits through any path. S= ee + * the section comment above for the cleanup guarantees on each exit path. + * Fails the test if suppression is already active; nesting is not support= ed. + * + * The warning count can be checked inside the block via + * KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(). The handle is not accessible + * after the block exits. + * + * Example:: + * + * kunit_warning_suppress(test) { + * trigger_warning(); + * KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); + * } + */ +#define kunit_warning_suppress(test) \ + for (struct kunit_suppressed_warning *__kunit_suppress \ + __cleanup(__kunit_suppress_auto_cleanup) =3D \ + kunit_start_suppress_warning(test); \ + __kunit_suppress; \ + kunit_end_suppress_warning(test, __kunit_suppress), \ + __kunit_suppress =3D NULL) + +/** + * KUNIT_START_SUPPRESSED_WARNING() - Begin suppressing WARN*() backtraces. + * @test: The test context object. + * + * Manual form of the suppression API. Must be paired with + * KUNIT_END_SUPPRESSED_WARNING() in the same scope. See the section comme= nt + * above for cleanup guarantees. Fails the test if suppression is already + * active; nesting is not supported. Limited to one pair per scope; use + * sequential kunit_warning_suppress() blocks or the direct function API + * when more than one suppression region is needed. + * + * Example:: + * + * KUNIT_START_SUPPRESSED_WARNING(test); + * trigger_code_that_should_warn_once(); + * KUNIT_END_SUPPRESSED_WARNING(test); + * KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); + */ +#define KUNIT_START_SUPPRESSED_WARNING(test) \ + struct kunit_suppressed_warning *__kunit_suppress =3D \ + kunit_start_suppress_warning(test) + +/** + * KUNIT_END_SUPPRESSED_WARNING() - End suppressing WARN*() backtraces. + * @test: The test context object. + * + * Deactivates suppression started by KUNIT_START_SUPPRESSED_WARNING(). + * The warning count remains readable via KUNIT_SUPPRESSED_WARNING_COUNT() + * after this call. + */ +#define KUNIT_END_SUPPRESSED_WARNING(test) \ + kunit_end_suppress_warning(test, __kunit_suppress) + +/** + * KUNIT_SUPPRESSED_WARNING_COUNT() - Returns the suppressed warning count. + * + * Returns the number of WARN*() calls suppressed since the current + * suppression block started, or 0 if the handle is NULL. Usable inside a + * kunit_warning_suppress() block or after KUNIT_END_SUPPRESSED_WARNING(). + */ +#define KUNIT_SUPPRESSED_WARNING_COUNT() \ + kunit_suppressed_warning_count(__kunit_suppress) + +/** + * KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT() - Sets an expectation that the + * suppressed warning count equa= ls + * @expected. + * @test: The test context object. + * @expected: an expression that evaluates to the expected warning count. + * + * Sets an expectation that the number of suppressed WARN*() calls equals + * @expected. This is semantically equivalent to + * KUNIT_EXPECT_EQ(@test, KUNIT_SUPPRESSED_WARNING_COUNT(), @expected). + * See KUNIT_EXPECT_EQ() for more information. + */ +#define KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, expected) \ + KUNIT_EXPECT_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), expected) + +/** + * KUNIT_ASSERT_SUPPRESSED_WARNING_COUNT() - Sets an assertion that the + * suppressed warning count equa= ls + * @expected. + * @test: The test context object. + * @expected: an expression that evaluates to the expected warning count. + * + * Sets an assertion that the number of suppressed WARN*() calls equals + * @expected. This is the same as KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(), + * except it causes an assertion failure (see KUNIT_ASSERT_TRUE()) when the + * assertion is not met. + */ +#define KUNIT_ASSERT_SUPPRESSED_WARNING_COUNT(test, expected) \ + KUNIT_ASSERT_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), expected) + #endif /* _KUNIT_TEST_H */ diff --git a/kernel/panic.c b/kernel/panic.c index c78600212b6c1..697d8ca054bef 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -39,6 +39,7 @@ #include #include #include +#include =20 #define PANIC_TIMER_STEP 100 #define PANIC_BLINK_SPD 18 @@ -1080,9 +1081,14 @@ void __warn(const char *file, int line, void *caller= , unsigned taint, void warn_slowpath_fmt(const char *file, int line, unsigned taint, const char *fmt, ...) { - bool rcu =3D warn_rcu_enter(); + bool rcu; struct warn_args args; =20 + if (kunit_is_suppressed_warning(true)) + return; + + rcu =3D warn_rcu_enter(); + pr_warn(CUT_HERE); =20 if (!fmt) { @@ -1102,9 +1108,14 @@ EXPORT_SYMBOL(warn_slowpath_fmt); #else void __warn_printk(const char *fmt, ...) { - bool rcu =3D warn_rcu_enter(); + bool rcu; va_list args; =20 + if (kunit_is_suppressed_warning(false)) + return; + + rcu =3D warn_rcu_enter(); + pr_warn(CUT_HERE); =20 va_start(args, fmt); diff --git a/lib/bug.c b/lib/bug.c index 623c467a8b76c..a5cebde554ed8 100644 --- a/lib/bug.c +++ b/lib/bug.c @@ -48,6 +48,7 @@ #include #include #include +#include =20 extern struct bug_entry __start___bug_table[], __stop___bug_table[]; =20 @@ -223,6 +224,15 @@ static enum bug_trap_type __report_bug(struct bug_entr= y *bug, unsigned long buga no_cut =3D bug->flags & BUGFLAG_NO_CUT_HERE; has_args =3D bug->flags & BUGFLAG_ARGS; =20 +#ifdef CONFIG_KUNIT + /* + * Before the once logic so suppressed warnings do not consume + * the single-fire budget of WARN_ON_ONCE(). + */ + if (warning && kunit_is_suppressed_warning(true)) + return BUG_TRAP_TYPE_WARN; +#endif + if (warning && once) { if (done) return BUG_TRAP_TYPE_WARN; diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile index 656f1fa35abcc..4592f9d0aa8dd 100644 --- a/lib/kunit/Makefile +++ b/lib/kunit/Makefile @@ -10,7 +10,8 @@ kunit-objs +=3D test.o \ executor.o \ attributes.o \ device.o \ - platform.o + platform.o \ + bug.o =20 ifeq ($(CONFIG_KUNIT_DEBUGFS),y) kunit-objs +=3D debugfs.o diff --git a/lib/kunit/bug.c b/lib/kunit/bug.c new file mode 100644 index 0000000000000..b0b6778d7399a --- /dev/null +++ b/lib/kunit/bug.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KUnit helpers for backtrace suppression + * + * Copyright (C) 2025 Alessandro Carminati + * Copyright (C) 2024 Guenter Roeck + */ + +#include +#include +#include +#include +#include + +#include "hooks-impl.h" + +struct kunit_suppressed_warning { + struct list_head node; + struct task_struct *task; + struct kunit *test; + int counter; +}; + +static LIST_HEAD(suppressed_warnings); +static DEFINE_SPINLOCK(suppressed_warnings_lock); + +static void kunit_suppress_warning_remove(struct kunit_suppressed_warning = *w) +{ + unsigned long flags; + + spin_lock_irqsave(&suppressed_warnings_lock, flags); + list_del_rcu(&w->node); + spin_unlock_irqrestore(&suppressed_warnings_lock, flags); + synchronize_rcu(); /* Wait for readers to finish */ +} + +KUNIT_DEFINE_ACTION_WRAPPER(kunit_suppress_warning_cleanup, + kunit_suppress_warning_remove, + struct kunit_suppressed_warning *); + +bool kunit_has_active_suppress_warning(void) +{ + return __kunit_is_suppressed_warning_impl(false); +} +EXPORT_SYMBOL_GPL(kunit_has_active_suppress_warning); + +struct kunit_suppressed_warning * +kunit_start_suppress_warning(struct kunit *test) +{ + struct kunit_suppressed_warning *w; + unsigned long flags; + int ret; + + if (kunit_has_active_suppress_warning()) { + KUNIT_FAIL(test, "Another suppression block is already active"); + return NULL; + } + + w =3D kunit_kzalloc(test, sizeof(*w), GFP_KERNEL); + if (!w) + return NULL; + + w->task =3D current; + w->test =3D test; + + spin_lock_irqsave(&suppressed_warnings_lock, flags); + list_add_rcu(&w->node, &suppressed_warnings); + spin_unlock_irqrestore(&suppressed_warnings_lock, flags); + + ret =3D kunit_add_action_or_reset(test, + kunit_suppress_warning_cleanup, w); + if (ret) + return NULL; + + return w; +} +EXPORT_SYMBOL_GPL(kunit_start_suppress_warning); + +void kunit_end_suppress_warning(struct kunit *test, + struct kunit_suppressed_warning *w) +{ + if (!w) + return; + kunit_release_action(test, kunit_suppress_warning_cleanup, w); +} +EXPORT_SYMBOL_GPL(kunit_end_suppress_warning); + +void __kunit_suppress_auto_cleanup(struct kunit_suppressed_warning **wp) +{ + if (*wp) + kunit_end_suppress_warning((*wp)->test, *wp); +} +EXPORT_SYMBOL_GPL(__kunit_suppress_auto_cleanup); + +int kunit_suppressed_warning_count(struct kunit_suppressed_warning *w) +{ + return w ? w->counter : 0; +} +EXPORT_SYMBOL_GPL(kunit_suppressed_warning_count); + +bool __kunit_is_suppressed_warning_impl(bool count) +{ + struct kunit_suppressed_warning *w; + + guard(rcu)(); + list_for_each_entry_rcu(w, &suppressed_warnings, node) { + if (w->task =3D=3D current) { + if (count) + w->counter++; + return true; + } + } + + return false; +} diff --git a/lib/kunit/hooks-impl.h b/lib/kunit/hooks-impl.h index 4e71b2d0143ba..d8720f2616925 100644 --- a/lib/kunit/hooks-impl.h +++ b/lib/kunit/hooks-impl.h @@ -19,6 +19,7 @@ void __printf(3, 4) __kunit_fail_current_test_impl(const = char *file, int line, const char *fmt, ...); void *__kunit_get_static_stub_address_impl(struct kunit *test, void *real_= fn_addr); +bool __kunit_is_suppressed_warning_impl(bool count); =20 /* Code to set all of the function pointers. */ static inline void kunit_install_hooks(void) @@ -26,6 +27,7 @@ static inline void kunit_install_hooks(void) /* Install the KUnit hook functions. */ kunit_hooks.fail_current_test =3D __kunit_fail_current_test_impl; kunit_hooks.get_static_stub_address =3D __kunit_get_static_stub_address_i= mpl; + kunit_hooks.is_suppressed_warning =3D __kunit_is_suppressed_warning_impl; } =20 #endif /* _KUNIT_HOOKS_IMPL_H */ --=20 2.53.0 From nobody Mon May 4 13:05:03 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D432C3093DF for ; Mon, 4 May 2026 07:42:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777880525; cv=none; b=MIrIFrV61HahhjbTfrWZwCxZRb45f+wEXeYjNaXydgbGJOvYrV4HOcONDft/PqIfSHoDr4VoH+YsH6Vn7MDrB6c3tUKLm+MM5O0W6yczYPmUU5YbEdnx2+ddaWXtj9knGQA44dy4AdlM25mGBRHOILquIwVuUHBXt6yWbyooDYU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777880525; c=relaxed/simple; bh=rY7XnBlB/wz8bNJ58xpd3pRURX0Y3QSzrdxzWXp0whU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sR+lpVUhIiRJGrZbNZ9hszPCWA+U9bcqwVqfTiszCZsTARwE4KoNSQimPcmcGpNeaxX5mmbQGOtV/wKas7av14luOvSMLZQAypUlyReYPWt7BLzQuxWZzbeF93OgWYLmztPGPZb6dJpQbNVQ1NIaZV4EeQeEHolPQoh4pxU1VOQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ImHIaEkR; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ImHIaEkR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777880522; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tnys7K/9v0O55CEJGXyqjjo3X9Li4otJ+Uz/nwlsSjY=; b=ImHIaEkRZBc/R6WUBfV7tga4e/lSiUxnjjaIvpTJ1yTOuk3yvzhKlZ3w8QoNcTxnWz/MOg et5C1nX/phSuaAU+uXn12pPFWbEOdZxDT0XEpa8MKhtLdGcQQ0grQwwfH53H1an3MQqn5r kaLYHoqE2MEoApqgldNH7rk2pGTSysg= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-244-DXJaZ9owOZ-t6DGFIciKDQ-1; Mon, 04 May 2026 03:42:00 -0400 X-MC-Unique: DXJaZ9owOZ-t6DGFIciKDQ-1 X-Mimecast-MFC-AGG-ID: DXJaZ9owOZ-t6DGFIciKDQ_1777880517 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7D3C31956095; Mon, 4 May 2026 07:41:56 +0000 (UTC) Received: from [192.168.1.153] (headnet01.pony-001.prod.iad2.dc.redhat.com [10.2.32.101]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CC3DA1953952; Mon, 4 May 2026 07:41:48 +0000 (UTC) From: Albert Esteve Date: Mon, 04 May 2026 09:41:26 +0200 Subject: [PATCH v8 2/4] kunit: Add backtrace suppression self-tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260504-kunit_add_support-v8-2-3e5957cdd235@redhat.com> References: <20260504-kunit_add_support-v8-0-3e5957cdd235@redhat.com> In-Reply-To: <20260504-kunit_add_support-v8-0-3e5957cdd235@redhat.com> To: Arnd Bergmann , Brendan Higgins , David Gow , Rae Moar , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Jonathan Corbet , Shuah Khan , Andrew Morton , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti Cc: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, dri-devel@lists.freedesktop.org, workflows@vger.kernel.org, linux-riscv@lists.infradead.org, linux-doc@vger.kernel.org, peterz@infradead.org, Guenter Roeck , Linux Kernel Functional Testing , Dan Carpenter , Alessandro Carminati , Albert Esteve , Kees Cook X-Developer-Signature: v=1; a=ed25519-sha256; t=1777880489; l=7602; i=aesteve@redhat.com; s=20260303; h=from:subject:message-id; bh=MPqWQRUdtbNfJXopMeu+OACXdzeU52PSCq9boOzmY9E=; b=Brw74qOGhkGRJzJXdV3ap46kPR0GwcVV2hbIPTXWh6XX1i4So0lelm46aXQ8ErU4mZdRw2tft kThCZ3+aRU8DZjjfqZKm0nj0Duf2wZZkbi698pxBUazWfmxY2Mfo1X+ X-Developer-Key: i=aesteve@redhat.com; a=ed25519; pk=YSFz6sOHd2L45+Fr8DIvHTi6lSIjhLZ5T+rkxspJt1s= X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 From: Guenter Roeck Add unit tests to verify that warning backtrace suppression works. Tests cover all three API forms: - Scoped: kunit_warning_suppress() with in-block count verification and post-block inactivity check. - Manual macros: KUNIT_START/END_SUPPRESSED_WARNING() with WARN() and WARN_ON(), both direct and through helper functions, as well as multiple warnings in a single block. - Direct functions: kunit_start/end_suppress_warning() with sequential independent suppression blocks and per-block counts. Furthermore, tests verify incremental warning counting, that kunit_has_active_suppress_warning() transitions correctly around suppression boundaries, and that suppression active in the test kthread does not leak to a separate kthread. If backtrace suppression does _not_ work, the unit tests will likely trigger unsuppressed backtraces, which should actually help to get the affected architectures / platforms fixed. Tested-by: Linux Kernel Functional Testing Acked-by: Dan Carpenter Reviewed-by: Kees Cook Signed-off-by: Guenter Roeck Signed-off-by: Alessandro Carminati Reviewed-by: David Gow Signed-off-by: Albert Esteve --- lib/kunit/Makefile | 1 + lib/kunit/backtrace-suppression-test.c | 184 +++++++++++++++++++++++++++++= ++++ 2 files changed, 185 insertions(+) diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile index 4592f9d0aa8dd..2e8a6b71a2ab0 100644 --- a/lib/kunit/Makefile +++ b/lib/kunit/Makefile @@ -22,6 +22,7 @@ obj-$(if $(CONFIG_KUNIT),y) +=3D hooks.o =20 obj-$(CONFIG_KUNIT_TEST) +=3D kunit-test.o obj-$(CONFIG_KUNIT_TEST) +=3D platform-test.o +obj-$(CONFIG_KUNIT_TEST) +=3D backtrace-suppression-test.o =20 # string-stream-test compiles built-in only. ifeq ($(CONFIG_KUNIT_TEST),y) diff --git a/lib/kunit/backtrace-suppression-test.c b/lib/kunit/backtrace-s= uppression-test.c new file mode 100644 index 0000000000000..0e6fb685d2cbb --- /dev/null +++ b/lib/kunit/backtrace-suppression-test.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KUnit test for suppressing warning tracebacks. + * + * Copyright (C) 2024, Guenter Roeck + * Author: Guenter Roeck + */ + +#include +#include +#include +#include + +static void backtrace_suppression_test_warn_direct(struct kunit *test) +{ + kunit_warning_suppress(test) { + WARN(1, "This backtrace should be suppressed"); + /* + * Count must be checked inside the scope; the handle + * is not accessible after the block exits. + */ + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); + } + KUNIT_EXPECT_FALSE(test, kunit_has_active_suppress_warning()); +} + +static void trigger_backtrace_warn(void) +{ + WARN(1, "This backtrace should be suppressed"); +} + +static void backtrace_suppression_test_warn_indirect(struct kunit *test) +{ + KUNIT_START_SUPPRESSED_WARNING(test); + trigger_backtrace_warn(); + KUNIT_END_SUPPRESSED_WARNING(test); + + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); +} + +static void backtrace_suppression_test_warn_multi(struct kunit *test) +{ + KUNIT_START_SUPPRESSED_WARNING(test); + WARN(1, "This backtrace should be suppressed"); + trigger_backtrace_warn(); + KUNIT_END_SUPPRESSED_WARNING(test); + + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 2); +} + +static void backtrace_suppression_test_warn_on_direct(struct kunit *test) +{ + if (!IS_ENABLED(CONFIG_DEBUG_BUGVERBOSE) && !IS_ENABLED(CONFIG_KALLSYMS)) + kunit_skip(test, "requires CONFIG_DEBUG_BUGVERBOSE or CONFIG_KALLSYMS"); + + KUNIT_START_SUPPRESSED_WARNING(test); + WARN_ON(1); + KUNIT_END_SUPPRESSED_WARNING(test); + + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); +} + +static void trigger_backtrace_warn_on(void) +{ + WARN_ON(1); +} + +static void backtrace_suppression_test_warn_on_indirect(struct kunit *test) +{ + if (!IS_ENABLED(CONFIG_DEBUG_BUGVERBOSE)) + kunit_skip(test, "requires CONFIG_DEBUG_BUGVERBOSE"); + + KUNIT_START_SUPPRESSED_WARNING(test); + trigger_backtrace_warn_on(); + KUNIT_END_SUPPRESSED_WARNING(test); + + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); +} + +static void backtrace_suppression_test_count(struct kunit *test) +{ + KUNIT_START_SUPPRESSED_WARNING(test); + + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 0); + + WARN(1, "suppressed"); + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); + + WARN(1, "suppressed again"); + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 2); + + KUNIT_END_SUPPRESSED_WARNING(test); +} + +static void backtrace_suppression_test_active_state(struct kunit *test) +{ + KUNIT_EXPECT_FALSE(test, kunit_has_active_suppress_warning()); + + KUNIT_START_SUPPRESSED_WARNING(test); + KUNIT_EXPECT_TRUE(test, kunit_has_active_suppress_warning()); + KUNIT_END_SUPPRESSED_WARNING(test); + + KUNIT_EXPECT_FALSE(test, kunit_has_active_suppress_warning()); + + kunit_warning_suppress(test) { + KUNIT_EXPECT_TRUE(test, kunit_has_active_suppress_warning()); + } + + KUNIT_EXPECT_FALSE(test, kunit_has_active_suppress_warning()); +} + +static void backtrace_suppression_test_multi_scope(struct kunit *test) +{ + struct kunit_suppressed_warning *sw1, *sw2; + + if (!IS_ENABLED(CONFIG_DEBUG_BUGVERBOSE)) + kunit_skip(test, "requires CONFIG_DEBUG_BUGVERBOSE"); + + sw1 =3D kunit_start_suppress_warning(test); + trigger_backtrace_warn_on(); + WARN(1, "suppressed by sw1"); + kunit_end_suppress_warning(test, sw1); + + sw2 =3D kunit_start_suppress_warning(test); + WARN(1, "suppressed by sw2"); + kunit_end_suppress_warning(test, sw2); + + KUNIT_EXPECT_EQ(test, kunit_suppressed_warning_count(sw1), 2); + KUNIT_EXPECT_EQ(test, kunit_suppressed_warning_count(sw2), 1); +} + +struct cross_kthread_data { + bool was_active; + struct completion done; +}; + +static int cross_kthread_fn(void *data) +{ + struct cross_kthread_data *d =3D data; + + d->was_active =3D kunit_has_active_suppress_warning(); + complete(&d->done); + return 0; +} + +static void backtrace_suppression_test_cross_kthread(struct kunit *test) +{ + struct cross_kthread_data data; + struct task_struct *task; + + init_completion(&data.done); + + KUNIT_START_SUPPRESSED_WARNING(test); + + task =3D kthread_run(cross_kthread_fn, &data, "kunit-cross-test"); + KUNIT_ASSERT_FALSE(test, IS_ERR(task)); + wait_for_completion(&data.done); + + KUNIT_END_SUPPRESSED_WARNING(test); + + KUNIT_EXPECT_FALSE(test, data.was_active); +} + +static struct kunit_case backtrace_suppression_test_cases[] =3D { + KUNIT_CASE(backtrace_suppression_test_warn_direct), + KUNIT_CASE(backtrace_suppression_test_warn_indirect), + KUNIT_CASE(backtrace_suppression_test_warn_multi), + KUNIT_CASE(backtrace_suppression_test_warn_on_direct), + KUNIT_CASE(backtrace_suppression_test_warn_on_indirect), + KUNIT_CASE(backtrace_suppression_test_count), + KUNIT_CASE(backtrace_suppression_test_active_state), + KUNIT_CASE(backtrace_suppression_test_multi_scope), + KUNIT_CASE(backtrace_suppression_test_cross_kthread), + {} +}; + +static struct kunit_suite backtrace_suppression_test_suite =3D { + .name =3D "backtrace-suppression-test", + .test_cases =3D backtrace_suppression_test_cases, +}; +kunit_test_suites(&backtrace_suppression_test_suite); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("KUnit test to verify warning backtrace suppression"); --=20 2.53.0 From nobody Mon May 4 13:05:03 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6350A30ACFF for ; Mon, 4 May 2026 07:42:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777880535; cv=none; b=rs4F4tTad96bWWUoiTCaWz3AB2jw+/o+j/uUyIzUz6yLtrXEBozF1i3ZLeRpeH7PP5k5ql986wSQz0sAMbRIOeWlDxWGSYjgFtQr1mOb2ecomJVEJFyA9MmvTy9jZoKBwK0r9qEOJE/6uymgyl3I7GU2Sw13Wn+XHI3vLyI+npE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777880535; c=relaxed/simple; bh=8CmZDGYXicehtCZjE1XNTtDp93zzvSMc/ymRifgJo64=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YrGMK0ULq1sTrLrUEDMpmn+H/5iew48EzuqauI0Io7kPaeVRVdX6MvI2yD3XT/vg00V/p4zEAta9skshgZxHr0Eoh5KY5raHY3aRQDnp1+L6R2wFvWWB+ftxsn+iCDr1F+cStl8crbnL0SLu6N+6ZGjK5c+h0n7wrXLH+GrhXzY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=dSPH8LJ0; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="dSPH8LJ0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777880532; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gOKf73DcJr3/JAze0LuQpsRljfWR1d0ve3pogQMoikE=; b=dSPH8LJ0NRueq2K0sQ17Ss9UysC2xjoVfHo7vAXeGL6rPBSm88R4oxxNfRhOgrjmx1qkfs BDa6C8F6h+kSSgr01p/3GFi7dSMtobt7m0s3hdTwjdNq2FuRZ+3ELbhX5SeUgoNpC5pERb 6z7TwMQOss5yJDMqz9eNPW4njpE1z64= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-577-oRkOntUwMsyWrjHIIS31fQ-1; Mon, 04 May 2026 03:42:09 -0400 X-MC-Unique: oRkOntUwMsyWrjHIIS31fQ-1 X-Mimecast-MFC-AGG-ID: oRkOntUwMsyWrjHIIS31fQ_1777880525 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id AE5E21956088; Mon, 4 May 2026 07:42:04 +0000 (UTC) Received: from [192.168.1.153] (headnet01.pony-001.prod.iad2.dc.redhat.com [10.2.32.101]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CE79D1955D84; Mon, 4 May 2026 07:41:56 +0000 (UTC) From: Albert Esteve Date: Mon, 04 May 2026 09:41:27 +0200 Subject: [PATCH v8 3/4] drm: Suppress intentional warning backtraces in scaling unit tests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260504-kunit_add_support-v8-3-3e5957cdd235@redhat.com> References: <20260504-kunit_add_support-v8-0-3e5957cdd235@redhat.com> In-Reply-To: <20260504-kunit_add_support-v8-0-3e5957cdd235@redhat.com> To: Arnd Bergmann , Brendan Higgins , David Gow , Rae Moar , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Jonathan Corbet , Shuah Khan , Andrew Morton , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti Cc: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, dri-devel@lists.freedesktop.org, workflows@vger.kernel.org, linux-riscv@lists.infradead.org, linux-doc@vger.kernel.org, peterz@infradead.org, Guenter Roeck , Linux Kernel Functional Testing , Dan Carpenter , =?utf-8?q?Ma=C3=ADra_Canal?= , Alessandro Carminati , Albert Esteve , Simona Vetter X-Developer-Signature: v=1; a=ed25519-sha256; t=1777880489; l=2693; i=aesteve@redhat.com; s=20260303; h=from:subject:message-id; bh=bGqCNzhIOGnVl/NfnUqExLX0/n0ZkI03UY6zDNsA5Oc=; b=Jb29iLKaaVTR7v5Dlr1/i2Ay+tOHiXVtL5zSM8WqXh29zv8ysgXgUHMDrE0l6z7IQH7slKIiX vNIBwlPkSVqAHz8EpMgT6x8oGYb3Y71H/+mI7IaMSCNPTqLSIsvuS26 X-Developer-Key: i=aesteve@redhat.com; a=ed25519; pk=YSFz6sOHd2L45+Fr8DIvHTi6lSIjhLZ5T+rkxspJt1s= X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 From: Guenter Roeck The drm_test_rect_calc_hscale and drm_test_rect_calc_vscale unit tests intentionally trigger warning backtraces by providing bad parameters to the tested functions. What is tested is the return value, not the existence of a warning backtrace. Suppress the backtraces to avoid clogging the kernel log and distraction from real problems. Tested-by: Linux Kernel Functional Testing Acked-by: Dan Carpenter Acked-by: Ma=C3=ADra Canal Cc: Maarten Lankhorst Cc: David Airlie Cc: Daniel Vetter Signed-off-by: Guenter Roeck Signed-off-by: Alessandro Carminati Acked-by: David Gow Signed-off-by: Albert Esteve --- drivers/gpu/drm/tests/drm_rect_test.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tests/drm_rect_test.c b/drivers/gpu/drm/tests/= drm_rect_test.c index 17e1f34b76101..818e16e80c8f9 100644 --- a/drivers/gpu/drm/tests/drm_rect_test.c +++ b/drivers/gpu/drm/tests/drm_rect_test.c @@ -409,8 +409,16 @@ static void drm_test_rect_calc_hscale(struct kunit *te= st) const struct drm_rect_scale_case *params =3D test->param_value; int scaling_factor; =20 - scaling_factor =3D drm_rect_calc_hscale(¶ms->src, ¶ms->dst, - params->min_range, params->max_range); + /* + * drm_rect_calc_hscale() generates a warning backtrace whenever bad + * parameters are passed to it. This affects all unit tests with an + * error code in expected_scaling_factor. + */ + kunit_warning_suppress(test) { + scaling_factor =3D drm_rect_calc_hscale(¶ms->src, ¶ms->dst, + params->min_range, + params->max_range); + } =20 KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor); } @@ -420,8 +428,15 @@ static void drm_test_rect_calc_vscale(struct kunit *te= st) const struct drm_rect_scale_case *params =3D test->param_value; int scaling_factor; =20 - scaling_factor =3D drm_rect_calc_vscale(¶ms->src, ¶ms->dst, - params->min_range, params->max_range); + /* + * drm_rect_calc_vscale() generates a warning backtrace whenever bad + * parameters are passed to it. This affects all unit tests with an + * error code in expected_scaling_factor. + */ + kunit_warning_suppress(test) { + scaling_factor =3D drm_rect_calc_vscale(¶ms->src, ¶ms->dst, + params->min_range, params->max_range); + } =20 KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor); } --=20 2.53.0 From nobody Mon May 4 13:05:03 2026 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D184F2472A2 for ; Mon, 4 May 2026 07:42:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777880546; cv=none; b=KzDD3sFkxk0MleNj2nSKK0AwWhu1zpWuaXxMMb85TmKlOzcVrejzbc2DISdKXBoLYchzxoACC2gvN3QIwYFKvmBneIFAzGF8t1CnSu9CRvhAC+ea+KUH8AhnQEZ3r7yBVeivpXhCt6NMMzwz+jl3H/1TeL+O+A1dKOKVun/siM8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777880546; c=relaxed/simple; bh=A80E02qU1TS6z15q14xBiSQVueYwuoIuM7q+neSZq1s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OQeklpMpxlHD3xlDJtdYwaR+BxBTgACZoVARqd/IG7e6fqRSUmEPrB0zLnlYrwK0q8kW7fSFszjGPbf4p5Z5clZUtQeUlvP9qoQYOAGQ7XARR1tiht/d3eIjjp5+dmWzTSCh37mV0RuZW7GowIscW1SQg+CJCDDp3OPP5YXp8XM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=TcwfeWJp; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="TcwfeWJp" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1777880543; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=17DG/jFD4UJY3jOr7jCFbgLNy+ifxGIJEYAAkiazHmo=; b=TcwfeWJpqyjrzahKd6LKZO7m8AjcMTQCiTYphBDFg4VLlY5Z9Ktie36gH49L/a2pcQHcTD bgfv+hhkhsgui/Jvc3mQn7TUveYRAJ30V1TVB5vXgI8i5XKy1xlYbaR/SSQKxWjxwCKmyI dkcUrjDI/WcVDIaY3HqiDCKRFMPjDJk= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-517-QAvuwnggOIKkmeYZGApe3g-1; Mon, 04 May 2026 03:42:16 -0400 X-MC-Unique: QAvuwnggOIKkmeYZGApe3g-1 X-Mimecast-MFC-AGG-ID: QAvuwnggOIKkmeYZGApe3g_1777880533 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2A4AF19560A1; Mon, 4 May 2026 07:42:12 +0000 (UTC) Received: from [192.168.1.153] (headnet01.pony-001.prod.iad2.dc.redhat.com [10.2.32.101]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1C9EA1953952; Mon, 4 May 2026 07:42:04 +0000 (UTC) From: Albert Esteve Date: Mon, 04 May 2026 09:41:28 +0200 Subject: [PATCH v8 4/4] kunit: Add documentation for warning backtrace suppression API Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260504-kunit_add_support-v8-4-3e5957cdd235@redhat.com> References: <20260504-kunit_add_support-v8-0-3e5957cdd235@redhat.com> In-Reply-To: <20260504-kunit_add_support-v8-0-3e5957cdd235@redhat.com> To: Arnd Bergmann , Brendan Higgins , David Gow , Rae Moar , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Jonathan Corbet , Shuah Khan , Andrew Morton , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexandre Ghiti Cc: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, dri-devel@lists.freedesktop.org, workflows@vger.kernel.org, linux-riscv@lists.infradead.org, linux-doc@vger.kernel.org, peterz@infradead.org, Guenter Roeck , Linux Kernel Functional Testing , Dan Carpenter , Alessandro Carminati , Albert Esteve , Kees Cook , David Gow X-Developer-Signature: v=1; a=ed25519-sha256; t=1777880489; l=3385; i=aesteve@redhat.com; s=20260303; h=from:subject:message-id; bh=2r+YaNLYekCHScvfkm3SGKZhcNXhOrPXur/abYPqMto=; b=pimAHn6mKykigLlO10+2vvAltRY7TPIdHOYgqeW98bdEc+ZK26YT7z1+cMMQAe9pp5J0fvRMB Egmh5d5sKOyC8rUTjiV0qZJLE2iKtU53WjTgAs/8LI4pkK+8kn5azN9 X-Developer-Key: i=aesteve@redhat.com; a=ed25519; pk=YSFz6sOHd2L45+Fr8DIvHTi6lSIjhLZ5T+rkxspJt1s= X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 From: Guenter Roeck Document API functions for suppressing warning backtraces. Tested-by: Linux Kernel Functional Testing Acked-by: Dan Carpenter Reviewed-by: Kees Cook Signed-off-by: Guenter Roeck Reviewed-by: David Gow Signed-off-by: Alessandro Carminati Reviewed-by: David Gow Signed-off-by: Albert Esteve --- Documentation/dev-tools/kunit/usage.rst | 63 +++++++++++++++++++++++++++++= +++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/Documentation/dev-tools/kunit/usage.rst b/Documentation/dev-to= ols/kunit/usage.rst index ebd06f5ea4550..25724f7e72969 100644 --- a/Documentation/dev-tools/kunit/usage.rst +++ b/Documentation/dev-tools/kunit/usage.rst @@ -157,6 +157,67 @@ Alternatively, one can take full control over the erro= r message by using if (some_setup_function()) KUNIT_FAIL(test, "Failed to setup thing for testing"); =20 +Suppressing warning backtraces +------------------------------ + +Some unit tests trigger warning backtraces either intentionally or as a si= de +effect. Such backtraces are normally undesirable since they distract from +the actual test and may result in the impression that there is a problem. + +Backtraces can be suppressed with **task-scoped suppression**: while +suppression is active on the current task, the backtrace and stack dump fr= om +``WARN*()``, ``WARN_ON*()``, and related macros on that task are suppresse= d. +Three API forms are available, in order of convenience. + +- Scoped suppression is the simplest form. Wrap the code that triggers + warnings in a ``kunit_warning_suppress()`` block: + +.. code-block:: c + + static void some_test(struct kunit *test) + { + kunit_warning_suppress(test) { + trigger_backtrace(); + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); + } + } + +.. note:: + The warning count must be checked inside the block; the suppression han= dle + is not accessible after the block exits. + +- Manual macros are useful when the suppressed region is large enough that + extra indentation is undesirable, or when the warning count needs to be + checked after suppression ends. ``KUNIT_START_SUPPRESSED_WARNING()`` must + appear before ``KUNIT_END_SUPPRESSED_WARNING()`` in the same scope. + Limited to one pair per scope. + +.. code-block:: c + + static void some_test(struct kunit *test) + { + KUNIT_START_SUPPRESSED_WARNING(test); + trigger_backtrace(); + KUNIT_END_SUPPRESSED_WARNING(test); + + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); + } + +- Direct functions return an explicit handle pointer. Use them when the ha= ndle + needs to be retained or passed across helper functions: + +.. code-block:: c + + static void some_test(struct kunit *test) + { + struct kunit_suppressed_warning *w; + + w =3D kunit_start_suppress_warning(test); + trigger_backtrace(); + kunit_end_suppress_warning(test, w); + + KUNIT_EXPECT_EQ(test, kunit_suppressed_warning_count(w), 1); + } =20 Test Suites ~~~~~~~~~~~ @@ -1211,4 +1272,4 @@ For example: dev_managed_string =3D devm_kstrdup(fake_device, "Hello, World!"); =20 // Everything is cleaned up automatically when the test ends. - } \ No newline at end of file + } --=20 2.53.0