Re: [PATCH v6 0/5] kunit: Add support for suppressing warning backtraces

Vlastimil Babka (SUSE)
2026-03-17T11:20:33Z

On 3/17/26 10:24, Albert Esteve wrote:
> 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.
>
> One option to address the problem would be to add messages such as
> "expected warning backtraces start/end here" to the kernel log.
> However, that would again require filter scripts, might result in
> missing real problematic warning backtraces triggered while the test
> is running, and the irrelevant backtrace(s) would still clog the
> kernel log.
>
> Solve the problem by providing a means to identify and suppress specific
> warning backtraces while executing test code. Support suppressing multiple
> backtraces while at the same time limiting changes to generic code to the
> absolute minimum.
>
> Overview:
> Patch#1 Introduces the suppression infrastructure.
> Patch#2 Mitigate the impact at WARN*() sites.
> Patch#3 Adds selftests to validate the functionality.
> Patch#4 Demonstrates real-world usage in the DRM subsystem.
> Patch#5 Documents the new API and usage guidelines.
>
> Design Notes:
> The objective is to suppress unwanted WARN*() generated messages.
>
> Although most major architectures share common bug handling via `lib/bug.c`
> and `report_bug()`, some minor or legacy architectures still rely on their
> own platform-specific handling. This divergence must be considered in any
> such feature. Additionally, a key challenge in implementing this feature is
> the fragmentation of `WARN*()` messages emission: specific part in the
> macro, common with BUG*() part in the exception handler.
> As a result, any intervention to suppress the message must occur before the
> illegal instruction.
>
> Lessons from the Previous Attempt
> In earlier iterations, suppression logic was added inside the
> `__report_bug()` function to intercept WARN*() messages not producing
> messages in the macro.
> To implement the check in the bug handler code, two strategies were
> considered:
>
> * Strategy #1: Use `kallsyms` to infer the originating functionid, namely
> a pointer to the function. Since in any case, the user interface relies
> on function names, they must be translated in addresses at suppression-
> time or at check-time.
> Assuming to translate at suppression-time, the `kallsyms` subsystem needs
> to be used to determine the symbol address from the name, and again to
> produce the functionid from `bugaddr`. This approach proved unreliable
> due to compiler-induced transformations such as inlining, cloning, and
> code fragmentation. Attempts to preventing them is also unconvenient
> because several `WARN()` sites are in functions intentionally declared
> as `__always_inline`.
>
> * Strategy #2: Store function name `__func__` in `struct bug_entry` in
> the `__bug_table`. This implementation was used in the previous version.
> However, `__func__` is a compiler-generated symbol, which complicates
> relocation and linking in position-independent code. Workarounds such as
> storing offsets from `.rodata` or embedding string literals directly into
> the table would have significantly either increased complexity or
> increase the __bug_table size.
> Additionally, architectures not using the unified `BUG()` path would
> still require ad-hoc handling. Because current WARN*() message production
> strategy, a few WARN*() macros still need a check to suppress the part of
> the message produced in the macro itself.
>
> As a result, previous version proposed a per-macro solution, which offers
> better control on where the suppression logic is applied.
>
> For this iteration, the `__report_bug()` centralized approach was
> revisited after the discussion in the previous version [1].

Discussion with PeterZ, who is not CC'd here? (did it now for my reply).

> However, again this approach did not work because:
> - Some warning output is generated directly in the macros before calling
> the centralized functions (e.g., `__warn_printk()` in `__WARN_printf()`)
> - Functions in the warning path like `warn_slowpath_fmt()` are marked
> `__always_inline`, making it difficult to intercept early enough
> - So, by the time `__report_bug()` is called, output has already been written
> to the console, making suppression ineffective
>
> Current Proposal: Check Directly in the `WARN()` Macros.
> This avoids the need for function symbol resolution or ELF section
> modification.
> Suppression is implemented directly in the `WARN*()` macros.

So does that bloat every warn/bug site (as Peter objected to) or not?
And is it compatible with x86? I see you modify include/asm-generic/bug.h
but x86 has its own version of e.g. __WARN_printf ?

> A helper function, `__kunit_is_suppressed_warning()`, is used to determine
> whether suppression applies. It is marked as `noinstr`, since some `WARN*()`
> sites reside in non-instrumentable sections. The function uses a static
> branch for the fast path check (which is `noinstr`-safe), and only calls
> the actual suppression check (which uses `strcmp`, and is surrounded by
> instrumentation_begin()/end() calls) when suppressions are active.
> The list of suppressed warnings is protected with RCU (Read-Copy-Update)
> to allow concurrent read access without locks.
>
> To minimize runtime impact when no suppressions are active, static branching
> is used via a static key (`kunit_suppress_warnings_key`). The branch is
> automatically enabled when the first suppression starts and disabled when the
> last suppression ends, tracked via an atomic counter. This keeps the suppression
> check code out-of-line, reducing code bloat at each `WARN*()` site while
> maintaining minimal runtime overhead in the common case (no active suppressions).
>
> This series is based on the RFC patch and subsequent discussion at
> https://patchwork.kernel.org/project/linux-kselftest/patch/02546e59-1afe-4b08-ba81-d94f3b691c9a@moroto.mountain/
> and offers a more comprehensive solution of the problem discussed there.
>
> [1] https://lore.kernel.org/all/CAGegRW76X8Fk_5qqOBw_aqBwAkQTsc8kXKHEuu9ECeXzdJwMSw@mail.gmail.com/
>
> Changes since RFC:
> - Introduced CONFIG_KUNIT_SUPPRESS_BACKTRACE
> - Minor cleanups and bug fixes
> - Added support for all affected architectures
> - Added support for counting suppressed warnings
> - Added unit tests using those counters
> - Added patch to suppress warning backtraces in dev_addr_lists tests
>
> Changes since v1:
> - Rebased to v6.9-rc1
> - Added Tested-by:, Acked-by:, and Reviewed-by: tags
> [I retained those tags since there have been no functional changes]
> - Introduced KUNIT_SUPPRESS_BACKTRACE configuration option, enabled by
> default.
>
> Changes since v2:
> - Rebased to v6.9-rc2
> - Added comments to drm warning suppression explaining why it is needed.
> - Added patch to move conditional code in arch/sh/include/asm/bug.h
> to avoid kerneldoc warning
> - Added architecture maintainers to Cc: for architecture specific patches
> - No functional changes
>
> Changes since v3:
> - Rebased to v6.14-rc6
> - Dropped net: "kunit: Suppress lock warning noise at end of dev_addr_lists tests"
> since 3db3b62955cd6d73afde05a17d7e8e106695c3b9
> - Added __kunit_ and KUNIT_ prefixes.
> - Tested on interessed architectures.
>
> Changes since v4:
> - Rebased to v6.15-rc7
> - Dropped all code in __report_bug()
> - Moved all checks in WARN*() macros.
> - Dropped all architecture specific code.
> - Made __kunit_is_suppressed_warning nice to noinstr functions.
>
> Changes since v5:
> - Rebased to v7.0-rc3
> - Added RCU protection for the suppressed warnings list.
> - Added static key and branching optimization.
> - Removed custom `strcmp` implementation and reworked
> __kunit_is_suppressed_warning() entrypoint function.
>
> Alessandro Carminati (2):
> bug/kunit: Core support for suppressing warning backtraces
> bug/kunit: Suppressing warning backtraces reduced impact on WARN*()
> sites
>
> Guenter Roeck (3):
> Add unit tests to verify that warning backtrace suppression works.
> drm: Suppress intentional warning backtraces in scaling unit tests
> kunit: Add documentation for warning backtrace suppression API
>
> Documentation/dev-tools/kunit/usage.rst | 30 ++++++-
> drivers/gpu/drm/tests/drm_rect_test.c | 16 ++++
> include/asm-generic/bug.h | 48 +++++++----
> include/kunit/bug.h | 62 ++++++++++++++
> include/kunit/test.h | 1 +
> lib/kunit/Kconfig | 9 ++
> lib/kunit/Makefile | 9 +-
> lib/kunit/backtrace-suppression-test.c | 105 ++++++++++++++++++++++++
> lib/kunit/bug.c | 54 ++++++++++++
> 9 files changed, 316 insertions(+), 18 deletions(-)
> create mode 100644 include/kunit/bug.h
> create mode 100644 lib/kunit/backtrace-suppression-test.c
> create mode 100644 lib/kunit/bug.c
>
> --
> 2.34.1
>
> ---
> Alessandro Carminati (2):
> bug/kunit: Core support for suppressing warning backtraces
> bug/kunit: Suppressing warning backtraces reduced impact on WARN*() sites
>
> Guenter Roeck (3):
> Add unit tests to verify that warning backtrace suppression works.
> drm: Suppress intentional warning backtraces in scaling unit tests
> kunit: Add documentation for warning backtrace suppression API
>
> Documentation/dev-tools/kunit/usage.rst | 30 ++++++++-
> drivers/gpu/drm/tests/drm_rect_test.c | 16 +++++
> include/asm-generic/bug.h | 44 ++++++++-----
> include/kunit/bug.h | 61 ++++++++++++++++++
> include/kunit/test.h | 1 +
> lib/kunit/Kconfig | 9 +++
> lib/kunit/Makefile | 9 ++-
> lib/kunit/backtrace-suppression-test.c | 109 ++++++++++++++++++++++++++++++++
> lib/kunit/bug.c | 71 +++++++++++++++++++++
> 9 files changed, 332 insertions(+), 18 deletions(-)
> ---
> base-commit: 80234b5ab240f52fa45d201e899e207b9265ef91
> change-id: 20260312-kunit_add_support-2f35806b19dd
>
> Best regards,