Le 08/05/2026 à 14:52, Albert Esteve a écrit :
On Wed, May 6, 2026 at 12:11 PM Albert Esteve <[email protected]> wrote:
On Wed, May 6, 2026 at 11:40 AM David Gow <[email protected]> wrote:
Le 04/05/2026 à 3:41 PM, Albert Esteve a écrit :
From: Alessandro Carminati <[email protected]>
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 <[email protected]>
Signed-off-by: Alessandro Carminati <[email protected]>
Reviewed-by: Kees Cook <[email protected]>
Signed-off-by: Albert Esteve <[email protected]>
---
This looks pretty good to me, thanks.
Reviewed-by: David Gow <[email protected]>
It's maybe slightly over-the-top to now have three different ways of
enabling warning suppression: I'd probably personally get rid of
KUNIT_START/END_SUPPRESSED_WARNING() if we had to lose one. But if
there's a real reason to prefer keeping all three, it's not actually a
problem to do so.
Thanks for the review!
I think the three forms earn their keep: the scoped form is the go-to
for most cases, but the macros avoid indentation without requiring
users to manage a raw pointer. I initially removed the macros and
added them back later. Direct calls to the functions will be less
frequent, used only when you need the handle.
That said, if it becomes a maintenance burden, the macros are the
easiest to drop since they're thin wrappers. Let me know if you prefer
them to be dropped, and I will send a v9 with that and the
`KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT` additions to the drm test
patch.
BR,
Albert.
Regardless, this series is looking pretty ready to me. Let me know if
you're planning a v9, otherwise we'll take this when you're ready.
I have been thinking, and despite my last response arguing against it,
I think I will send that v9 and remove
KUNIT_START/END_SUPPRESSED_WARNING(). Since the scoped approach with a
reduced extent should be the default style for most cases, the direct
calls can cover any other use cases without needing macros. Plus,
since macros set the handler name for you, it seems odd not to be able
to use them more than once per test.
Yeah, that was a part of my thought: all of the possible uses of
KUNIT_START/END_SUPPRESSED_WARNING() can be replaced with the scoped
version except for the one case where you want to check the number of
warnings specifically after the scope. I'm not sure the latter would be
common, and in the few places it's useful, the direct calls are not
_that_ much more difficult to use.
I hope that's ok. After that I think it should be ready (at least from my side).
Sounds good: assuming no last-minute disasters, we'll take v9 then.
Cheers,
-- David