* [PATCH v3 0/9] Kernel API Specification Framework
From: Sasha Levin @ 2026-04-24 16:51 UTC (permalink / raw)
To: linux-api, linux-kernel
Cc: linux-doc, linux-fsdevel, linux-kbuild, linux-kselftest,
workflows, tools, x86, Thomas Gleixner, Paul E . McKenney,
Greg Kroah-Hartman, Jonathan Corbet, Dmitry Vyukov, Randy Dunlap,
Cyril Hrubis, Kees Cook, Jake Edge, David Laight, Askar Safin,
Gabriele Paoloni, Mauro Carvalho Chehab, Christian Brauner,
Alexander Viro, Andrew Morton, Masahiro Yamada, Shuah Khan,
Ingo Molnar, Arnd Bergmann, Sasha Levin
This proposal introduces machinery for documenting kernel APIs, addressing the
long-standing challenge of maintaining stable interfaces between the kernel and
user-space programs. Despite the kernel's commitment to never breaking user
space, the lack of machine-readable API specifications has led to breakages
across kernel interfaces.
Specifications can document parameter types, valid ranges, constraints, and
alignment requirements. They capture return value semantics including success
conditions and error codes with their meaning. Execution context requirements,
capabilities, locking constraints, signal handling behavior, and side effects
can all be formally specified.
These specifications live alongside the code they document and are both
human-readable and machine-parseable. They can be validated at runtime when
CONFIG_KAPI_RUNTIME_CHECKS is enabled, exported via debugfs for userspace
tools, and extracted from either vmlinux or source code.
This enables static analysis tools to verify userspace API usage at compile
time, test generation based on formal specifications, consistent error handling
validation, automated documentation generation, and formal verification of
kernel interfaces.
The implementation includes a core framework with ELF section storage,
kerneldoc integration for inline specification, a debugfs interface for runtime
querying, and a Rust-based extraction tool (tools/kapi) supporting JSON, RST,
and plain text output formats. Example specifications are provided for the four
fundamental file syscalls (sys_open, sys_close, sys_read, sys_write). The
series also includes a KUnit test suite with 27 tests and a runtime
verification selftest with 29 TAP tests.
The series with runtime testing enabled (CONFIG_KAPI_RUNTIME_CHECKS=y)
currently survives LTP tests in a KVM VM.
Changes since v2:
- Replace statically sized arrays in the spec structs with const char *
pointers to reduce memory footprint and remove string truncation.
- Simplify the kerneldoc DSL to short tokens (e.g. `type: uint, input`,
`contexts: process, softirq`, `constraint-type: range(0, KMAX)`,
`side-effect: alloc_memory`) in place of raw KAPI_* enum names.
- tools/kapi: commit Cargo.lock for reproducible offline builds, add a
Makefile and README, expand the kerneldoc parser to cover the full
DSL, and refactor the vmlinux extractor for the const-pointer layout.
- tools/lib/python/kdoc/kdoc_apispec.py expanded to match the DSL so
scripts/kernel-doc --apispec emits the structure the extractor consumes.
References:
v2: https://lore.kernel.org/all/20260322121026.869758-1-sashal@kernel.org/
v1: https://lore.kernel.org/all/20260313150928.2637368-1-sashal@kernel.org/
RFC v5: https://lore.kernel.org/lkml/20251218204239.4159453-1-sashal@kernel.org/
RFC v4: https://lore.kernel.org/lkml/20250825181434.3340805-1-sashal@kernel.org/
RFC v3: https://lore.kernel.org/lkml/20250711114248.2288591-1-sashal@kernel.org/
RFC v2: https://lore.kernel.org/lkml/20250624180742.5795-1-sashal@kernel.org/
RFC v1: https://lore.kernel.org/lkml/20250614134858.790460-1-sashal@kernel.org/
Sasha Levin (9):
kernel/api: introduce kernel API specification framework
kernel/api: enable kerneldoc-based API specifications
kernel/api: add debugfs interface for kernel API specifications
tools/kapi: add kernel API specification extraction tool
kernel/api: add API specification for sys_open
kernel/api: add API specification for sys_close
kernel/api: add API specification for sys_read
kernel/api: add API specification for sys_write
kernel/api: add runtime verification selftest
.gitignore | 1 +
Documentation/dev-tools/index.rst | 1 +
Documentation/dev-tools/kernel-api-spec.rst | 704 ++++
MAINTAINERS | 11 +
arch/x86/include/asm/syscall_wrapper.h | 40 +
fs/open.c | 566 ++++
fs/read_write.c | 697 ++++
include/asm-generic/vmlinux.lds.h | 28 +
include/linux/kernel_api_spec.h | 1269 ++++++++
include/linux/syscalls.h | 38 +
init/Kconfig | 2 +
kernel/Makefile | 3 +
kernel/api/.gitignore | 2 +
kernel/api/Kconfig | 77 +
kernel/api/Makefile | 14 +
kernel/api/internal.h | 21 +
kernel/api/kapi_debugfs.c | 553 ++++
kernel/api/kapi_kunit.c | 538 ++++
kernel/api/kernel_api_spec.c | 1362 ++++++++
scripts/Makefile.build | 31 +
scripts/Makefile.clean | 3 +
tools/docs/kernel-doc | 5 +
tools/kapi/.gitignore | 4 +
tools/kapi/Cargo.lock | 679 ++++
tools/kapi/Cargo.toml | 20 +
tools/kapi/Makefile | 33 +
tools/kapi/README.md | 32 +
tools/kapi/src/extractor/debugfs.rs | 849 +++++
tools/kapi/src/extractor/kerneldoc_parser.rs | 2831 +++++++++++++++++
tools/kapi/src/extractor/mod.rs | 388 +++
tools/kapi/src/extractor/source_parser.rs | 415 +++
.../src/extractor/vmlinux/binary_utils.rs | 462 +++
.../src/extractor/vmlinux/magic_finder.rs | 115 +
tools/kapi/src/extractor/vmlinux/mod.rs | 857 +++++
tools/kapi/src/formatter/json.rs | 634 ++++
tools/kapi/src/formatter/mod.rs | 122 +
tools/kapi/src/formatter/plain.rs | 646 ++++
tools/kapi/src/formatter/rst.rs | 726 +++++
tools/kapi/src/main.rs | 123 +
tools/lib/python/kdoc/kdoc_apispec.py | 1249 ++++++++
tools/lib/python/kdoc/kdoc_output.py | 9 +-
tools/lib/python/kdoc/kdoc_parser.py | 86 +-
tools/testing/selftests/Makefile | 1 +
tools/testing/selftests/kapi/Makefile | 7 +
tools/testing/selftests/kapi/kapi_test_util.h | 33 +
tools/testing/selftests/kapi/test_kapi.c | 1096 +++++++
46 files changed, 17378 insertions(+), 5 deletions(-)
create mode 100644 Documentation/dev-tools/kernel-api-spec.rst
create mode 100644 include/linux/kernel_api_spec.h
create mode 100644 kernel/api/.gitignore
create mode 100644 kernel/api/Kconfig
create mode 100644 kernel/api/Makefile
create mode 100644 kernel/api/internal.h
create mode 100644 kernel/api/kapi_debugfs.c
create mode 100644 kernel/api/kapi_kunit.c
create mode 100644 kernel/api/kernel_api_spec.c
create mode 100644 tools/kapi/.gitignore
create mode 100644 tools/kapi/Cargo.lock
create mode 100644 tools/kapi/Cargo.toml
create mode 100644 tools/kapi/Makefile
create mode 100644 tools/kapi/README.md
create mode 100644 tools/kapi/src/extractor/debugfs.rs
create mode 100644 tools/kapi/src/extractor/kerneldoc_parser.rs
create mode 100644 tools/kapi/src/extractor/mod.rs
create mode 100644 tools/kapi/src/extractor/source_parser.rs
create mode 100644 tools/kapi/src/extractor/vmlinux/binary_utils.rs
create mode 100644 tools/kapi/src/extractor/vmlinux/magic_finder.rs
create mode 100644 tools/kapi/src/extractor/vmlinux/mod.rs
create mode 100644 tools/kapi/src/formatter/json.rs
create mode 100644 tools/kapi/src/formatter/mod.rs
create mode 100644 tools/kapi/src/formatter/plain.rs
create mode 100644 tools/kapi/src/formatter/rst.rs
create mode 100644 tools/kapi/src/main.rs
create mode 100644 tools/lib/python/kdoc/kdoc_apispec.py
create mode 100644 tools/testing/selftests/kapi/Makefile
create mode 100644 tools/testing/selftests/kapi/kapi_test_util.h
create mode 100644 tools/testing/selftests/kapi/test_kapi.c
--
2.53.0
^ permalink raw reply
* Re: [PATCH v7 4/5] drm: Suppress intentional warning backtraces in scaling unit tests
From: Jani Nikula @ 2026-04-24 12:21 UTC (permalink / raw)
To: Albert Esteve
Cc: Peter Zijlstra, Arnd Bergmann, Brendan Higgins, David Gow,
Rae Moar, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jonathan Corbet, Shuah Khan,
Andrew Morton, linux-kernel, linux-arch, linux-kselftest,
kunit-dev, dri-devel, workflows, linux-doc, Guenter Roeck,
Linux Kernel Functional Testing, Dan Carpenter, Maíra Canal,
Alessandro Carminati, Simona Vetter
In-Reply-To: <CADSE00+b-8moX5FkLjLs+wzyaW5dtJDMxvTT6Gu-QmDoDxJdVA@mail.gmail.com>
On Fri, 24 Apr 2026, Albert Esteve <aesteve@redhat.com> wrote:
> On Tue, Apr 21, 2026 at 1:51 PM Jani Nikula <jani.nikula@intel.com> wrote:
>>
>> On Tue, 21 Apr 2026, Albert Esteve <aesteve@redhat.com> wrote:
>> > On Mon, Apr 20, 2026 at 4:47 PM Peter Zijlstra <peterz@infradead.org> wrote:
>> >>
>> >> On Mon, Apr 20, 2026 at 02:28:06PM +0200, Albert Esteve wrote:
>> >> > From: Guenter Roeck <linux@roeck-us.net>
>> >> >
>> >> > 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 <lkft@linaro.org>
>> >> > Acked-by: Dan Carpenter <dan.carpenter@linaro.org>
>> >> > Acked-by: Maíra Canal <mcanal@igalia.com>
>> >> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> >> > Cc: David Airlie <airlied@gmail.com>
>> >> > Cc: Daniel Vetter <daniel@ffwll.ch>
>> >> > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
>> >> > Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
>> >> > Signed-off-by: Albert Esteve <aesteve@redhat.com>
>> >> > ---
>> >> > drivers/gpu/drm/tests/drm_rect_test.c | 14 ++++++++++++++
>> >> > 1 file changed, 14 insertions(+)
>> >> >
>> >> > diff --git a/drivers/gpu/drm/tests/drm_rect_test.c b/drivers/gpu/drm/tests/drm_rect_test.c
>> >> > index 17e1f34b76101..1dd7d819165e7 100644
>> >> > --- a/drivers/gpu/drm/tests/drm_rect_test.c
>> >> > +++ b/drivers/gpu/drm/tests/drm_rect_test.c
>> >> > @@ -409,8 +409,15 @@ static void drm_test_rect_calc_hscale(struct kunit *test)
>> >> > const struct drm_rect_scale_case *params = test->param_value;
>> >> > int scaling_factor;
>> >> >
>> >> > + /*
>> >> > + * 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_START_SUPPRESSED_WARNING(test);
>> >> > scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst,
>> >> > params->min_range, params->max_range);
>> >> > + KUNIT_END_SUPPRESSED_WARNING(test);
>> >>
>> >> Would not something like:
>> >>
>> >> scoped_kunit_suppress() {
>> >> scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst,
>> >> params->min_range, params->max_range);
>> >> }
>> >>
>> >> be better?
>> >
>> > Since KUnit already has a few macros in its API it didn't occur to me.
>> > Good idea, I like it. And I guess the scope approach matches well with
>> > your __cleanup comment in the first patch. If no one opposes, I will
>> > work toward that pattern for the next version.
>>
>> There's a catch with kunit and __cleanup and thus (scoped) guards. Kunit
>> runs in ktreads, asserts lead to kthread_exit() and the __cleanup won't
>> be called.
>
> Hi Jani,
>
> Good point. In this specific case, the actual cleanup is handled by
> kunit_add_action_or_reset(), so __cleanup not firing on assert is
> harmless.
Right.
>
>>
>> Warning suppression being part of kunit infrastructure, asserts can and
>> should end the suppression too. But setting the example (scoped) guards
>> are safe in kunit tests in general feels like a trap waiting to happen.
>>
>
> ... but I agree it sets a misleading precedent. I'll stick with the
> explicit start/end API, then? Or maybe we can clearly document why the
> scoped approach is safe in this case and use it.
I don't know what the right approach is, just wanted to make sure you're
aware of this particular gotcha with guards and kunit.
BR,
Jani.
>
>>
>> BR,
>> Jani.
>>
>>
>> >
>> >>
>> >> Also, how can you stand all this screaming in the code?
>> >>
>> >
>> > Again, KUnit already contains many macros, so this use didn't register
>> > as such. Now I will not be able to unsee it.
>> >
>> >
>>
>> --
>> Jani Nikula, Intel
>>
>
--
Jani Nikula, Intel
^ permalink raw reply
* Re: [PATCH v7 3/5] kunit: Add backtrace suppression self-tests
From: Albert Esteve @ 2026-04-24 8:25 UTC (permalink / raw)
To: David Gow
Cc: Arnd Bergmann, Brendan Higgins, Rae Moar, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Andrew Morton, linux-kernel,
linux-arch, linux-kselftest, kunit-dev, dri-devel, workflows,
linux-doc, peterz, Guenter Roeck, Linux Kernel Functional Testing,
Dan Carpenter, Alessandro Carminati, Kees Cook
In-Reply-To: <6209f24e-750d-4a7d-ad63-1695f5fd1caa@davidgow.net>
On Wed, Apr 22, 2026 at 2:22 PM David Gow <david@davidgow.net> wrote:
>
> Le 20/04/2026 à 8:28 PM, Albert Esteve a écrit :
> > From: Guenter Roeck <linux@roeck-us.net>
> >
> > Add unit tests to verify that warning backtrace suppression works,
> > covering WARN() and WARN_ON() with direct calls, indirect calls
> > through helper functions, and multiple warnings in a single window.
> >
> > 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 <lkft@linaro.org>
> > Acked-by: Dan Carpenter <dan.carpenter@linaro.org>
> > Reviewed-by: Kees Cook <keescook@chromium.org>
> > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> > Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
> > Signed-off-by: Albert Esteve <aesteve@redhat.com>
> > ---
>
> Thanks very much for including tests!
>
> Maybe it'd be nice to test that the suppression is disabled after
> KUNIT_END_SUPPRESSED_WARNING(). Of course, then triggering an actual
> stacktrace would be a pain, but maybe we could check that
> __kunit_is_suppressed_warning() returns false? If you wanted to be
> really fancy, you could test that it returns false on another kthread
> even while the suppression is active, too, but I won't hold you to it.
> Equally, you could try setting up a fake test context and ensuring the
> cleanup is called correctly, but I think that's mostly covered by the
> existing KUnit resource tests.
Good suggestions. I'll add a test for __kunit_is_suppressed_warning()
returning false after END. The cross-kthread test is a nice idea too.
I'll see if I can fit it in without overcomplicating things.
>
> Otherwise, looking good. A couple of other minor suggestions below,
> which may require some reworking of the __kunit_suppress scope, but all
> optional suggestions.
>
> Reviewed-by: David Gow <david@davidgow.net>
Thanks for the review!
>
> > lib/kunit/Makefile | 3 ++
> > lib/kunit/backtrace-suppression-test.c | 90 ++++++++++++++++++++++++++++++++++
> > 2 files changed, 93 insertions(+)
> >
> > diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile
> > index fe177ff3ebdef..b2f2b8ada7b71 100644
> > --- a/lib/kunit/Makefile
> > +++ b/lib/kunit/Makefile
> > @@ -23,6 +23,9 @@ obj-$(if $(CONFIG_KUNIT),y) += hooks.o \
> >
> > obj-$(CONFIG_KUNIT_TEST) += kunit-test.o
> > obj-$(CONFIG_KUNIT_TEST) += platform-test.o
> > +ifeq ($(CONFIG_KUNIT_SUPPRESS_BACKTRACE),y)
> > +obj-$(CONFIG_KUNIT_TEST) += backtrace-suppression-test.o
> > +endif
> >
> > # 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-suppression-test.c
> > new file mode 100644
> > index 0000000000000..2ba5dcb5fef35
> > --- /dev/null
> > +++ b/lib/kunit/backtrace-suppression-test.c
> > @@ -0,0 +1,90 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * KUnit test for suppressing warning tracebacks.
> > + *
> > + * Copyright (C) 2024, Guenter Roeck
> > + * Author: Guenter Roeck <linux@roeck-us.net>
> > + */
> > +
> > +#include <kunit/test.h>
> > +#include <linux/bug.h>
> > +
> > +static void backtrace_suppression_test_warn_direct(struct kunit *test)
> > +{
> > + KUNIT_START_SUPPRESSED_WARNING(test);
> > + WARN(1, "This backtrace should be suppressed");
> > + KUNIT_END_SUPPRESSED_WARNING(test);
> > +
> > + KUNIT_EXPECT_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), 1);
> > +}
> > +
> > +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_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), 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_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), 2);
>
> Would it make sense to test KUNIT_SUPPRESSED_WARNING_COUNT() more
> thoroughly here by checking that it's 0 before any warnings, and
> checking that it's 1 in-between the two warnings?
>
> Of course, the first case doesn't work due to __kunit_suppress not being
> defined, but if the implementation changes to support this, let's add it
> to the test, too.
I thought this was a test gap when you commented the limitation in
patch #1, so I agree to add more granular COUNT checks once the API
supports it (which it should after the rework to expose the pointer).
Thanks!
>
> > +}
> > +
> > +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_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), 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_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), 1);
> > +}
> > +
> > +static struct kunit_case backtrace_suppression_test_cases[] = {
> > + 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),
> > + {}
> > +};
> > +
> > +static struct kunit_suite backtrace_suppression_test_suite = {
> > + .name = "backtrace-suppression-test",
> > + .test_cases = backtrace_suppression_test_cases,
> > +};
> > +kunit_test_suites(&backtrace_suppression_test_suite);
> > +
> > +MODULE_LICENSE("GPL");
> > +MODULE_DESCRIPTION("KUnit test to verify warning backtrace suppression");
> >
>
^ permalink raw reply
* Re: [PATCH v7 2/5] bug/kunit: Reduce runtime impact of warning backtrace suppression
From: Albert Esteve @ 2026-04-24 8:17 UTC (permalink / raw)
To: David Gow
Cc: Arnd Bergmann, Brendan Higgins, Rae Moar, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Andrew Morton, linux-kernel,
linux-arch, linux-kselftest, kunit-dev, dri-devel, workflows,
linux-doc, peterz, Alessandro Carminati
In-Reply-To: <a1ddabac-8e50-4730-b936-4ddef949487e@davidgow.net>
On Wed, Apr 22, 2026 at 2:21 PM David Gow <david@davidgow.net> wrote:
>
> Le 20/04/2026 à 8:28 PM, Albert Esteve a écrit :
> > From: Alessandro Carminati <acarmina@redhat.com>
> >
> > 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@redhat.com>
> > Signed-off-by: Albert Esteve <aesteve@redhat.com>
> > ---
>
> I'm not sure how much of an improvement this is.
>
> It might be worth putting things behind the kunit_running static branch.
>
> You could even add a new kunit_has_suppressed_warnings static branch,
> though I doubt anyone's too worried about the runtime performance of
> WARN() during testing, but with no suppressions, so it's likely not
> worth it.
>
> Have a look at, e.g., kunit_fail_current_test() in
> include/kunit/test-bug.h, which uses the existing hooks implementation
> and static branch to reduce the overhead as much as I'd expect we need.
> That'd also potentially let you move the backtrace suppression code into
> the kunit.ko module, so you're not even paying more than ~a pointer's
> worth of memory if no tests are even loaded.
Agreed. This patch can be removed entirely once I integrate it into
the hooks infrastructure as discussed. The kunit_running static branch
is indeed a better fast-path than the counter, and leverages existing
architecture.
>
> Cheers,
> -- David
>
^ permalink raw reply
* Re: [PATCH v7 1/5] bug/kunit: Core support for suppressing warning backtraces
From: Albert Esteve @ 2026-04-24 8:06 UTC (permalink / raw)
To: David Gow
Cc: Arnd Bergmann, Brendan Higgins, Rae Moar, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Jonathan Corbet, Shuah Khan, Andrew Morton, linux-kernel,
linux-arch, linux-kselftest, kunit-dev, dri-devel, workflows,
linux-doc, peterz, Alessandro Carminati, Guenter Roeck, Kees Cook
In-Reply-To: <c71899ce-95a5-419b-8e83-9146ff9c7b7f@davidgow.net>
On Wed, Apr 22, 2026 at 2:21 PM David Gow <david@davidgow.net> wrote:
>
> Thanks very much for keeping this series alive! I'm very much in favour
> of it, and I think the overall design is good. Lots of more detailed
> nitpicks below, though.
>
Hi David,
Thank you for taking the time to review the series!
> Le 20/04/2026 à 8:28 PM, Albert Esteve a écrit :
> > From: Alessandro Carminati <acarmina@redhat.com>
> >
> > 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 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.
>
> It sounds from the description here that suppressing "specific
> backtraces" means that we're matching on the _contents_ of the stack
> trace. This sort-of does that implicitly by checking they're in the same
> kthread, but I think the fact that it's matching based on kthread should
> be explicit in the commit message, like it is in the documentation.
>
You are right. Previous version was based on function name matches. I
mostly fixed all commit messages, but this section remained. I will
rewrite it.
> >
> > Implementation details:
> > Suppression is checked at two points in the warning path:
> > - In warn_slowpath_fmt(), the check runs before any output, fully
> > suppressing both message and backtrace.
> > - In __report_bug(), the check runs before __warn() is called,
> > suppressing the backtrace and stack dump. Note that on this path,
> > the WARN() format message may still appear in the kernel log since
> > __warn_printk() runs before the trap that enters __report_bug().
>
> Would it make sense to output a 'backtrace suppressed due to running
> test' message in this latter case, so we don't just end up with the
> WARN() format message by itself? (My gut feeling is 'no, it isn't worth
> it', but it's food for thought.)
>
I had the same thought and landed on the same conclusion. It would
also become moot if we add the suppression check to __warn_printk() as
discussed with Peter, since the message would be fully suppressed on
that path too.
> >
> > A helper function, `__kunit_is_suppressed_warning()`, walks an
> > RCU-protected list of active suppressions, matching by current task.
> > The suppression state is tied to the KUnit test lifecycle via
> > kunit_add_action(), ensuring automatic cleanup at test exit.
> >
> > The list of suppressed warnings is protected with RCU to allow
> > concurrent read access without locks.
> >
> > The implementation is deliberately simple and avoids architecture-specific
> > optimizations to preserve portability.
> >
> > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> > Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
> > Reviewed-by: Kees Cook <kees@kernel.org>
> > Signed-off-by: Albert Esteve <aesteve@redhat.com>
> > ---
> > include/kunit/bug.h | 56 +++++++++++++++++++++++++++++++++++
> > include/kunit/test.h | 1 +
> > kernel/panic.c | 8 ++++-
> > lib/bug.c | 8 +++++
> > lib/kunit/Kconfig | 9 ++++++
> > lib/kunit/Makefile | 6 ++--
> > lib/kunit/bug.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 7 files changed, 169 insertions(+), 3 deletions(-)
> >
> > diff --git a/include/kunit/bug.h b/include/kunit/bug.h
> > new file mode 100644
> > index 0000000000000..e52c9d21d9fe6
> > --- /dev/null
> > +++ b/include/kunit/bug.h
>
> It's a bit confusing to name this bug.h when we have the (admittedly
> terribly-named) test-bug.h header already. I'm pretty tempted to rename
> the latter to something like 'hooks.h', as that's really what it's for,
> and having a separate bug.h would be an incentive to do so, though, sit
> it's not a big problem.
>
> I do think that it'd be reasonable to include the backtrace suppression
> tuff in the same file, though, if you'd rather. The
> __kunit_is_suppressed_warning() stuff in particular fits the category of
> "code called to change behaviour based on whether or not a test is
> running", which is generally what the hooks are for. (And, if you'd
> rather, there's a bunch of existing hooks and hook infrastructure you
> could use.)
I wasn't aware of the hooks infrastructure! I was so focused on the
solution carried over from initial versions that I did not seek
alternatives.
Honestly, that's a much better fit -- I'll integrate it into
test-bug.h for next version.
>
> > @@ -0,0 +1,56 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * KUnit helpers for backtrace suppression
> > + *
> > + * Copyright (C) 2025 Alessandro Carminati <acarmina@redhat.com>
> > + * Copyright (C) 2024 Guenter Roeck <linux@roeck-us.net>
> > + */
> > +
> > +#ifndef _KUNIT_BUG_H
> > +#define _KUNIT_BUG_H
> > +
> > +#ifndef __ASSEMBLY__
> > +
> > +#include <linux/kconfig.h>
> > +
> > +struct kunit;
> > +
> > +#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
> > +
> > +#include <linux/types.h>
> > +
> > +struct task_struct;
> > +
> > +struct __suppressed_warning {
> > + struct list_head node;
> > + struct task_struct *task;
> > + int counter;
> > +};
> > +
> > +struct __suppressed_warning *
> > +__kunit_start_suppress_warning(struct kunit *test);
> > +void __kunit_end_suppress_warning(struct kunit *test,
> > + struct __suppressed_warning *warning);
> > +int __kunit_suppressed_warning_count(struct __suppressed_warning *warning);
> > +bool __kunit_is_suppressed_warning(void);
> > +
> > +#define KUNIT_START_SUPPRESSED_WARNING(test) \
> > + struct __suppressed_warning *__kunit_suppress = \
> > + __kunit_start_suppress_warning(test)
> > +
> > +#define KUNIT_END_SUPPRESSED_WARNING(test) \
> > + __kunit_end_suppress_warning(test, __kunit_suppress)
> > +
> > +#define KUNIT_SUPPRESSED_WARNING_COUNT() \
> > + __kunit_suppressed_warning_count(__kunit_suppress)
>
> Using a local variable (__kunit_suppress) here means that all of the
> above macros must live in the same function. This is probably okay for
> most use-cases, but more complicated tests may have to structure things
> carefully. It also prevents there from being multiple START/END pairs in
> the same function, and the KUNIT_SUPPRESSED_WARNING_COUNT() macro from
> appearing before _START().
>
> It also makes it less obvious that this cleans up nicely if the test
> exits uncleanly, as the variable will have gone out-of-scope. (But given
> we're just storing a pointer to heap-allocated memory, and
> kunit_add_action() is used, it should be okay.)
>
> One other option would be to allocate the suppression as a named
> resource, which could then be retrieved from anywhere within the test
> with kunit_find_named_resource(). (Though handling nested suppressions
> gets a little more complicated here.)
>
> Or you could make the struct __suppressed_warning pointer returned
> explicitly user-visible, and let the user pass it around (though that
> seems more work).
>
Good points. The function matching approach used the function name to
allow concurrent suppressions to coexist. This is a limitation of the
current approach that I traded off for simplicity (without properly
considering the more complicated scenarios). I'll add a name parameter
to the macros (or expose the pointer directly) so multiple pairs and
cross-function usage work naturally. I think I lean more towards
making the return value user-visible? But I will decide based on how
the API evolves, especially if I change to the scoped approach
suggested in a different thread.
>
> > +
> > +#else /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
> > +
> > +#define KUNIT_START_SUPPRESSED_WARNING(test)
> > +#define KUNIT_END_SUPPRESSED_WARNING(test)
> > +#define KUNIT_SUPPRESSED_WARNING_COUNT() 0
> > +static inline bool __kunit_is_suppressed_warning(void) { return false; }
> > +
> > +#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
> > +#endif /* __ASSEMBLY__ */
> > +#endif /* _KUNIT_BUG_H */
> > diff --git a/include/kunit/test.h b/include/kunit/test.h
> > index 9cd1594ab697d..4ec07b3fa0204 100644
> > --- a/include/kunit/test.h
> > +++ b/include/kunit/test.h
> > @@ -10,6 +10,7 @@
> > #define _KUNIT_TEST_H
> >
> > #include <kunit/assert.h>
> > +#include <kunit/bug.h>
> > #include <kunit/try-catch.h>
> >
> > #include <linux/args.h>
> > diff --git a/kernel/panic.c b/kernel/panic.c
> > index c78600212b6c1..d7a7a679f56c4 100644
> > --- a/kernel/panic.c
> > +++ b/kernel/panic.c
> > @@ -39,6 +39,7 @@
> > #include <linux/sys_info.h>
> > #include <trace/events/error_report.h>
> > #include <asm/sections.h>
> > +#include <kunit/bug.h>
> >
> > #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 = warn_rcu_enter();
> > + bool rcu;
> > struct warn_args args;
> >
> > + if (__kunit_is_suppressed_warning())
> > + return;
> > +
> > + rcu = warn_rcu_enter();
> > +
> > pr_warn(CUT_HERE);
> >
> > if (!fmt) {
> > diff --git a/lib/bug.c b/lib/bug.c
> > index 623c467a8b76c..606205c8c302f 100644
> > --- a/lib/bug.c
> > +++ b/lib/bug.c
> > @@ -48,6 +48,7 @@
> > #include <linux/rculist.h>
> > #include <linux/ftrace.h>
> > #include <linux/context_tracking.h>
> > +#include <kunit/bug.h>
> >
> > extern struct bug_entry __start___bug_table[], __stop___bug_table[];
> >
> > @@ -223,6 +224,13 @@ static enum bug_trap_type __report_bug(struct bug_entry *bug, unsigned long buga
> > no_cut = bug->flags & BUGFLAG_NO_CUT_HERE;
> > has_args = bug->flags & BUGFLAG_ARGS;
> >
> > + /*
> > + * Before the once logic so suppressed warnings do not consume
> > + * the single-fire budget of WARN_ON_ONCE().
> > + */
> > + if (warning && __kunit_is_suppressed_warning())
> > + return BUG_TRAP_TYPE_WARN;
> > +
>
> While any competant optimiser should get rid of this entirely, it might
> be clearer to anyone reading it that this disappears if we just put it
> behind an #ifdef?
Makes sense. Will do.
>
> > if (warning && once) {
> > if (done)
> > return BUG_TRAP_TYPE_WARN;
> > diff --git a/lib/kunit/Kconfig b/lib/kunit/Kconfig
> > index 498cc51e493dc..57527418fcf09 100644
> > --- a/lib/kunit/Kconfig
> > +++ b/lib/kunit/Kconfig
> > @@ -15,6 +15,15 @@ menuconfig KUNIT
> >
> > if KUNIT
> >
> > +config KUNIT_SUPPRESS_BACKTRACE
> > + bool "KUnit - Enable backtrace suppression"
> > + default y
> > + help
> > + Enable backtrace suppression for KUnit. If enabled, backtraces
> > + generated intentionally by KUnit tests are suppressed. Disable
> > + to reduce kernel image size if image size is more important than
> > + suppression of backtraces generated by KUnit tests.
> > +
> > config KUNIT_DEBUGFS
> > bool "KUnit - Enable /sys/kernel/debug/kunit debugfs representation" if !KUNIT_ALL_TESTS
> > default KUNIT_ALL_TESTS
> > diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile
> > index 656f1fa35abcc..fe177ff3ebdef 100644
> > --- a/lib/kunit/Makefile
> > +++ b/lib/kunit/Makefile
> > @@ -16,8 +16,10 @@ ifeq ($(CONFIG_KUNIT_DEBUGFS),y)
> > kunit-objs += debugfs.o
> > endif
> >
> > -# KUnit 'hooks' are built-in even when KUnit is built as a module.
> > -obj-$(if $(CONFIG_KUNIT),y) += hooks.o
> > +# KUnit 'hooks' and bug handling are built-in even when KUnit is built
> > +# as a module.
> > +obj-$(if $(CONFIG_KUNIT),y) += hooks.o \
> > + bug.o
>
> Is there any reason we couldn't implement this on top of the hooks
> mechanism? Then we could include the bug suppression code in the
> kunit.ko module (albeit, with fewer possibilities for the compiler to
> optimise things, as they'd have to go through an indirect pointer).
>
No reason. I'll integrate this feature into the hooks infrastructure.
Thanks for the suggestion!
>
> >
> > obj-$(CONFIG_KUNIT_TEST) += kunit-test.o
> > obj-$(CONFIG_KUNIT_TEST) += platform-test.o
> > diff --git a/lib/kunit/bug.c b/lib/kunit/bug.c
> > new file mode 100644
> > index 0000000000000..356c8a5928828
> > --- /dev/null
> > +++ b/lib/kunit/bug.c
> > @@ -0,0 +1,84 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * KUnit helpers for backtrace suppression
> > + *
> > + * Copyright (C) 2025 Alessandro Carminati <acarmina@redhat.com>
> > + * Copyright (C) 2024 Guenter Roeck <linux@roeck-us.net>
> > + */
> > +
> > +#include <kunit/bug.h>
> > +#include <kunit/resource.h>
> > +#include <linux/export.h>
> > +#include <linux/rculist.h>
> > +#include <linux/sched.h>
> > +
> > +#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
> > +
> > +static LIST_HEAD(suppressed_warnings);
> > +
> > +static void __kunit_suppress_warning_remove(struct __suppressed_warning *warning)
> > +{
> > + list_del_rcu(&warning->node);
> > + synchronize_rcu(); /* Wait for readers to finish */
> > +}
> > +
> > +KUNIT_DEFINE_ACTION_WRAPPER(__kunit_suppress_warning_cleanup,
> > + __kunit_suppress_warning_remove,
> > + struct __suppressed_warning *);
> > +
> > +struct __suppressed_warning *
> > +__kunit_start_suppress_warning(struct kunit *test)
> > +{
> > + struct __suppressed_warning *warning;
> > + int ret;
> > +
> > + warning = kunit_kzalloc(test, sizeof(*warning), GFP_KERNEL);
> > + if (!warning)
> > + return NULL;
> > +
> > + warning->task = current;
> > + list_add_rcu(&warning->node, &suppressed_warnings);
> > +
> > + ret = kunit_add_action_or_reset(test,
> > + __kunit_suppress_warning_cleanup,
> > + warning);
> > + if (ret)
> > + return NULL;
> > +
> > + return warning;
> > +}
> > +EXPORT_SYMBOL_GPL(__kunit_start_suppress_warning);
> > +
> > +void __kunit_end_suppress_warning(struct kunit *test,
> > + struct __suppressed_warning *warning)
> > +{
> > + if (!warning)
> > + return;
> > + kunit_release_action(test, __kunit_suppress_warning_cleanup, warning);
> > +}
> > +EXPORT_SYMBOL_GPL(__kunit_end_suppress_warning);
> > +
> > +int __kunit_suppressed_warning_count(struct __suppressed_warning *warning)
> > +{
> > + return warning ? warning->counter : 0;
> > +}
> > +EXPORT_SYMBOL_GPL(__kunit_suppressed_warning_count);
> > +
> > +bool __kunit_is_suppressed_warning(void)
> > +{
> > + struct __suppressed_warning *warning;
> > +
> > + rcu_read_lock();
> > + list_for_each_entry_rcu(warning, &suppressed_warnings, node) {
> > + if (warning->task == current) {
> > + warning->counter++;
> > + rcu_read_unlock();
> > + return true;
> > + }
> > + }
> > + rcu_read_unlock();
> > +
> > + return false;
> > +}
>
> Note to self: this is _not_ exported, as bug.c is being built-in
> regardless of whether or not KUnit is a module. If we used the hook
> system, it could live in kunit.ko, and would be manually exported by
> kunit_install_hooks()
>
> > +
> > +#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
> >
>
>
> Thanks again,
> -- David
>
^ permalink raw reply
* Re: [PATCH v7 4/5] drm: Suppress intentional warning backtraces in scaling unit tests
From: Albert Esteve @ 2026-04-24 7:17 UTC (permalink / raw)
To: Jani Nikula
Cc: Peter Zijlstra, Arnd Bergmann, Brendan Higgins, David Gow,
Rae Moar, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jonathan Corbet, Shuah Khan,
Andrew Morton, linux-kernel, linux-arch, linux-kselftest,
kunit-dev, dri-devel, workflows, linux-doc, Guenter Roeck,
Linux Kernel Functional Testing, Dan Carpenter, Maíra Canal,
Alessandro Carminati, Simona Vetter
In-Reply-To: <8a9c125c08206296d698c79c3d3dd6aea36a7e3b@intel.com>
On Tue, Apr 21, 2026 at 1:51 PM Jani Nikula <jani.nikula@intel.com> wrote:
>
> On Tue, 21 Apr 2026, Albert Esteve <aesteve@redhat.com> wrote:
> > On Mon, Apr 20, 2026 at 4:47 PM Peter Zijlstra <peterz@infradead.org> wrote:
> >>
> >> On Mon, Apr 20, 2026 at 02:28:06PM +0200, Albert Esteve wrote:
> >> > From: Guenter Roeck <linux@roeck-us.net>
> >> >
> >> > 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 <lkft@linaro.org>
> >> > Acked-by: Dan Carpenter <dan.carpenter@linaro.org>
> >> > Acked-by: Maíra Canal <mcanal@igalia.com>
> >> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> > Cc: David Airlie <airlied@gmail.com>
> >> > Cc: Daniel Vetter <daniel@ffwll.ch>
> >> > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> >> > Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
> >> > Signed-off-by: Albert Esteve <aesteve@redhat.com>
> >> > ---
> >> > drivers/gpu/drm/tests/drm_rect_test.c | 14 ++++++++++++++
> >> > 1 file changed, 14 insertions(+)
> >> >
> >> > diff --git a/drivers/gpu/drm/tests/drm_rect_test.c b/drivers/gpu/drm/tests/drm_rect_test.c
> >> > index 17e1f34b76101..1dd7d819165e7 100644
> >> > --- a/drivers/gpu/drm/tests/drm_rect_test.c
> >> > +++ b/drivers/gpu/drm/tests/drm_rect_test.c
> >> > @@ -409,8 +409,15 @@ static void drm_test_rect_calc_hscale(struct kunit *test)
> >> > const struct drm_rect_scale_case *params = test->param_value;
> >> > int scaling_factor;
> >> >
> >> > + /*
> >> > + * 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_START_SUPPRESSED_WARNING(test);
> >> > scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst,
> >> > params->min_range, params->max_range);
> >> > + KUNIT_END_SUPPRESSED_WARNING(test);
> >>
> >> Would not something like:
> >>
> >> scoped_kunit_suppress() {
> >> scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst,
> >> params->min_range, params->max_range);
> >> }
> >>
> >> be better?
> >
> > Since KUnit already has a few macros in its API it didn't occur to me.
> > Good idea, I like it. And I guess the scope approach matches well with
> > your __cleanup comment in the first patch. If no one opposes, I will
> > work toward that pattern for the next version.
>
> There's a catch with kunit and __cleanup and thus (scoped) guards. Kunit
> runs in ktreads, asserts lead to kthread_exit() and the __cleanup won't
> be called.
Hi Jani,
Good point. In this specific case, the actual cleanup is handled by
kunit_add_action_or_reset(), so __cleanup not firing on assert is
harmless.
>
> Warning suppression being part of kunit infrastructure, asserts can and
> should end the suppression too. But setting the example (scoped) guards
> are safe in kunit tests in general feels like a trap waiting to happen.
>
... but I agree it sets a misleading precedent. I'll stick with the
explicit start/end API, then? Or maybe we can clearly document why the
scoped approach is safe in this case and use it.
>
> BR,
> Jani.
>
>
> >
> >>
> >> Also, how can you stand all this screaming in the code?
> >>
> >
> > Again, KUnit already contains many macros, so this use didn't register
> > as such. Now I will not be able to unsee it.
> >
> >
>
> --
> Jani Nikula, Intel
>
^ permalink raw reply
* Re: [PATCH] docs: maintainer-netdev: fix typo in "targeting"
From: patchwork-bot+netdevbpf @ 2026-04-23 3:40 UTC (permalink / raw)
To: Ariful Islam Shoikot; +Cc: netdev, linux-doc, workflows, linux-kernel
In-Reply-To: <20260420114554.1026-1-islamarifulshoikat@gmail.com>
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 20 Apr 2026 17:45:53 +0600 you wrote:
> Fix spelling mistake "targgeting" -> "targeting" in
> maintainer-netdev.rst
>
> No functional change.
>
> Signed-off-by: Ariful Islam Shoikot <islamarifulshoikat@gmail.com>
>
> [...]
Here is the summary with links:
- docs: maintainer-netdev: fix typo in "targeting"
https://git.kernel.org/netdev/net/c/645d044d7e5c
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH v7 5/5] kunit: Add documentation for warning backtrace suppression API
From: David Gow @ 2026-04-22 12:20 UTC (permalink / raw)
To: Albert Esteve, Arnd Bergmann, Brendan Higgins, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton
Cc: linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-doc, peterz, Guenter Roeck,
Linux Kernel Functional Testing, Dan Carpenter,
Alessandro Carminati, Kees Cook
In-Reply-To: <20260420-kunit_add_support-v7-5-e8bc6e0f70de@redhat.com>
Le 20/04/2026 à 8:28 PM, Albert Esteve a écrit :
> From: Guenter Roeck <linux@roeck-us.net>
>
> Document API functions for suppressing warning backtraces.
>
> Tested-by: Linux Kernel Functional Testing <lkft@linaro.org>
> Acked-by: Dan Carpenter <dan.carpenter@linaro.org>
> Reviewed-by: Kees Cook <keescook@chromium.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> Reviewed-by: David Gow <davidgow@google.com>
> Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
> Signed-off-by: Albert Esteve <aesteve@redhat.com>
> ---
Thanks -- it's always good to have documentation.
Apart from one note below, this looks good to me.
Reviewed-by: David Gow <david@davidgow.net>
Cheers,
-- David
> Documentation/dev-tools/kunit/usage.rst | 30 +++++++++++++++++++++++++++++-
> 1 file changed, 29 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/dev-tools/kunit/usage.rst b/Documentation/dev-tools/kunit/usage.rst
> index ebd06f5ea4550..76e85412f240e 100644
> --- a/Documentation/dev-tools/kunit/usage.rst
> +++ b/Documentation/dev-tools/kunit/usage.rst
> @@ -157,6 +157,34 @@ Alternatively, one can take full control over the error message by using
> if (some_setup_function())
> KUNIT_FAIL(test, "Failed to setup thing for testing");
>
> +Suppressing warning backtraces
> +------------------------------
> +
> +Some unit tests trigger warning backtraces either intentionally or as side
> +effect. Such backtraces are normally undesirable since they distract from
> +the actual test and may result in the impression that there is a problem.
> +
> +Such backtraces can be suppressed with **task scope suppression**: while
> +``START`` / ``END`` is active on the current task, the backtrace and stack
> +dump from warnings on that task are suppressed. Wrap the call from your test
> +in that window, like shown in the following code.
> +
> +.. code-block:: c
> +
> + static void some_test(struct kunit *test)
> + {
> + KUNIT_START_SUPPRESSED_WARNING(test);
> + trigger_backtrace();
> + KUNIT_END_SUPPRESSED_WARNING(test);
> + }
> +
> +``KUNIT_SUPPRESSED_WARNING_COUNT()`` returns the number of suppressed backtraces.
> +If the suppressed backtrace was triggered on purpose, this can be used to check
> +if the backtrace was actually triggered.
> +
> +.. code-block:: c
> +
> + KUNIT_EXPECT_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), 1);
It might be worth noting that all of these must be in the same function,
and the KUNIT_START_SUPPRESSED_WARNING() must be first. (And, in
addition, there can't be more than one START/END pair per-function).
Of course, if the implementation is changed, that wouldn't be necessary. :-)
>
> Test Suites
> ~~~~~~~~~~~
> @@ -1211,4 +1239,4 @@ For example:
> dev_managed_string = devm_kstrdup(fake_device, "Hello, World!");
>
> // Everything is cleaned up automatically when the test ends.
> - }
> \ No newline at end of file
> + }
>
^ permalink raw reply
* Re: [PATCH v7 4/5] drm: Suppress intentional warning backtraces in scaling unit tests
From: David Gow @ 2026-04-22 12:20 UTC (permalink / raw)
To: Albert Esteve, Arnd Bergmann, Brendan Higgins, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton
Cc: linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-doc, peterz, Guenter Roeck,
Linux Kernel Functional Testing, Dan Carpenter, Maíra Canal,
Alessandro Carminati, Simona Vetter
In-Reply-To: <20260420-kunit_add_support-v7-4-e8bc6e0f70de@redhat.com>
Le 20/04/2026 à 8:28 PM, Albert Esteve a écrit :
> From: Guenter Roeck <linux@roeck-us.net>
>
> 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 <lkft@linaro.org>
> Acked-by: Dan Carpenter <dan.carpenter@linaro.org>
> Acked-by: Maíra Canal <mcanal@igalia.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: David Airlie <airlied@gmail.com>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
> Signed-off-by: Albert Esteve <aesteve@redhat.com>
> ---
Acked-by: David Gow <david@davidgow.net>
Some of the suggestions in the thread around __cleanup() et al. sound
good to me, too. I suspect that it should work given the
kunit_add_action() / resource system use anyway, so even if an assertion
fires, things should be cleaned up properly.
Cheers,
-- David
> drivers/gpu/drm/tests/drm_rect_test.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/drivers/gpu/drm/tests/drm_rect_test.c b/drivers/gpu/drm/tests/drm_rect_test.c
> index 17e1f34b76101..1dd7d819165e7 100644
> --- a/drivers/gpu/drm/tests/drm_rect_test.c
> +++ b/drivers/gpu/drm/tests/drm_rect_test.c
> @@ -409,8 +409,15 @@ static void drm_test_rect_calc_hscale(struct kunit *test)
> const struct drm_rect_scale_case *params = test->param_value;
> int scaling_factor;
>
> + /*
> + * 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_START_SUPPRESSED_WARNING(test);
> scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst,
> params->min_range, params->max_range);
> + KUNIT_END_SUPPRESSED_WARNING(test);
>
> KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor);
> }
> @@ -420,8 +427,15 @@ static void drm_test_rect_calc_vscale(struct kunit *test)
> const struct drm_rect_scale_case *params = test->param_value;
> int scaling_factor;
>
> + /*
> + * 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_START_SUPPRESSED_WARNING(test);
> scaling_factor = drm_rect_calc_vscale(¶ms->src, ¶ms->dst,
> params->min_range, params->max_range);
> + KUNIT_END_SUPPRESSED_WARNING(test);
>
> KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor);
> }
>
^ permalink raw reply
* Re: [PATCH v7 3/5] kunit: Add backtrace suppression self-tests
From: David Gow @ 2026-04-22 12:20 UTC (permalink / raw)
To: Albert Esteve, Arnd Bergmann, Brendan Higgins, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton
Cc: linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-doc, peterz, Guenter Roeck,
Linux Kernel Functional Testing, Dan Carpenter,
Alessandro Carminati, Kees Cook
In-Reply-To: <20260420-kunit_add_support-v7-3-e8bc6e0f70de@redhat.com>
Le 20/04/2026 à 8:28 PM, Albert Esteve a écrit :
> From: Guenter Roeck <linux@roeck-us.net>
>
> Add unit tests to verify that warning backtrace suppression works,
> covering WARN() and WARN_ON() with direct calls, indirect calls
> through helper functions, and multiple warnings in a single window.
>
> 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 <lkft@linaro.org>
> Acked-by: Dan Carpenter <dan.carpenter@linaro.org>
> Reviewed-by: Kees Cook <keescook@chromium.org>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
> Signed-off-by: Albert Esteve <aesteve@redhat.com>
> ---
Thanks very much for including tests!
Maybe it'd be nice to test that the suppression is disabled after
KUNIT_END_SUPPRESSED_WARNING(). Of course, then triggering an actual
stacktrace would be a pain, but maybe we could check that
__kunit_is_suppressed_warning() returns false? If you wanted to be
really fancy, you could test that it returns false on another kthread
even while the suppression is active, too, but I won't hold you to it.
Equally, you could try setting up a fake test context and ensuring the
cleanup is called correctly, but I think that's mostly covered by the
existing KUnit resource tests.
Otherwise, looking good. A couple of other minor suggestions below,
which may require some reworking of the __kunit_suppress scope, but all
optional suggestions.
Reviewed-by: David Gow <david@davidgow.net>
> lib/kunit/Makefile | 3 ++
> lib/kunit/backtrace-suppression-test.c | 90 ++++++++++++++++++++++++++++++++++
> 2 files changed, 93 insertions(+)
>
> diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile
> index fe177ff3ebdef..b2f2b8ada7b71 100644
> --- a/lib/kunit/Makefile
> +++ b/lib/kunit/Makefile
> @@ -23,6 +23,9 @@ obj-$(if $(CONFIG_KUNIT),y) += hooks.o \
>
> obj-$(CONFIG_KUNIT_TEST) += kunit-test.o
> obj-$(CONFIG_KUNIT_TEST) += platform-test.o
> +ifeq ($(CONFIG_KUNIT_SUPPRESS_BACKTRACE),y)
> +obj-$(CONFIG_KUNIT_TEST) += backtrace-suppression-test.o
> +endif
>
> # 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-suppression-test.c
> new file mode 100644
> index 0000000000000..2ba5dcb5fef35
> --- /dev/null
> +++ b/lib/kunit/backtrace-suppression-test.c
> @@ -0,0 +1,90 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * KUnit test for suppressing warning tracebacks.
> + *
> + * Copyright (C) 2024, Guenter Roeck
> + * Author: Guenter Roeck <linux@roeck-us.net>
> + */
> +
> +#include <kunit/test.h>
> +#include <linux/bug.h>
> +
> +static void backtrace_suppression_test_warn_direct(struct kunit *test)
> +{
> + KUNIT_START_SUPPRESSED_WARNING(test);
> + WARN(1, "This backtrace should be suppressed");
> + KUNIT_END_SUPPRESSED_WARNING(test);
> +
> + KUNIT_EXPECT_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), 1);
> +}
> +
> +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_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), 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_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), 2);
Would it make sense to test KUNIT_SUPPRESSED_WARNING_COUNT() more
thoroughly here by checking that it's 0 before any warnings, and
checking that it's 1 in-between the two warnings?
Of course, the first case doesn't work due to __kunit_suppress not being
defined, but if the implementation changes to support this, let's add it
to the test, too.
> +}
> +
> +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_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), 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_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), 1);
> +}
> +
> +static struct kunit_case backtrace_suppression_test_cases[] = {
> + 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),
> + {}
> +};
> +
> +static struct kunit_suite backtrace_suppression_test_suite = {
> + .name = "backtrace-suppression-test",
> + .test_cases = backtrace_suppression_test_cases,
> +};
> +kunit_test_suites(&backtrace_suppression_test_suite);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("KUnit test to verify warning backtrace suppression");
>
^ permalink raw reply
* Re: [PATCH v7 2/5] bug/kunit: Reduce runtime impact of warning backtrace suppression
From: David Gow @ 2026-04-22 12:19 UTC (permalink / raw)
To: Albert Esteve, Arnd Bergmann, Brendan Higgins, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton
Cc: linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-doc, peterz, Alessandro Carminati
In-Reply-To: <20260420-kunit_add_support-v7-2-e8bc6e0f70de@redhat.com>
Le 20/04/2026 à 8:28 PM, Albert Esteve a écrit :
> From: Alessandro Carminati <acarmina@redhat.com>
>
> 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@redhat.com>
> Signed-off-by: Albert Esteve <aesteve@redhat.com>
> ---
I'm not sure how much of an improvement this is.
It might be worth putting things behind the kunit_running static branch.
You could even add a new kunit_has_suppressed_warnings static branch,
though I doubt anyone's too worried about the runtime performance of
WARN() during testing, but with no suppressions, so it's likely not
worth it.
Have a look at, e.g., kunit_fail_current_test() in
include/kunit/test-bug.h, which uses the existing hooks implementation
and static branch to reduce the overhead as much as I'd expect we need.
That'd also potentially let you move the backtrace suppression code into
the kunit.ko module, so you're not even paying more than ~a pointer's
worth of memory if no tests are even loaded.
Cheers,
-- David
^ permalink raw reply
* Re: [PATCH v7 1/5] bug/kunit: Core support for suppressing warning backtraces
From: David Gow @ 2026-04-22 12:19 UTC (permalink / raw)
To: Albert Esteve, Arnd Bergmann, Brendan Higgins, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton
Cc: linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-doc, peterz, Alessandro Carminati, Guenter Roeck,
Kees Cook
In-Reply-To: <20260420-kunit_add_support-v7-1-e8bc6e0f70de@redhat.com>
Thanks very much for keeping this series alive! I'm very much in favour
of it, and I think the overall design is good. Lots of more detailed
nitpicks below, though.
Le 20/04/2026 à 8:28 PM, Albert Esteve a écrit :
> From: Alessandro Carminati <acarmina@redhat.com>
>
> 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 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.
It sounds from the description here that suppressing "specific
backtraces" means that we're matching on the _contents_ of the stack
trace. This sort-of does that implicitly by checking they're in the same
kthread, but I think the fact that it's matching based on kthread should
be explicit in the commit message, like it is in the documentation.
>
> Implementation details:
> Suppression is checked at two points in the warning path:
> - In warn_slowpath_fmt(), the check runs before any output, fully
> suppressing both message and backtrace.
> - In __report_bug(), the check runs before __warn() is called,
> suppressing the backtrace and stack dump. Note that on this path,
> the WARN() format message may still appear in the kernel log since
> __warn_printk() runs before the trap that enters __report_bug().
Would it make sense to output a 'backtrace suppressed due to running
test' message in this latter case, so we don't just end up with the
WARN() format message by itself? (My gut feeling is 'no, it isn't worth
it', but it's food for thought.)
>
> A helper function, `__kunit_is_suppressed_warning()`, walks an
> RCU-protected list of active suppressions, matching by current task.
> The suppression state is tied to the KUnit test lifecycle via
> kunit_add_action(), ensuring automatic cleanup at test exit.
>
> The list of suppressed warnings is protected with RCU to allow
> concurrent read access without locks.
>
> The implementation is deliberately simple and avoids architecture-specific
> optimizations to preserve portability.
>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
> Reviewed-by: Kees Cook <kees@kernel.org>
> Signed-off-by: Albert Esteve <aesteve@redhat.com>
> ---
> include/kunit/bug.h | 56 +++++++++++++++++++++++++++++++++++
> include/kunit/test.h | 1 +
> kernel/panic.c | 8 ++++-
> lib/bug.c | 8 +++++
> lib/kunit/Kconfig | 9 ++++++
> lib/kunit/Makefile | 6 ++--
> lib/kunit/bug.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 7 files changed, 169 insertions(+), 3 deletions(-)
>
> diff --git a/include/kunit/bug.h b/include/kunit/bug.h
> new file mode 100644
> index 0000000000000..e52c9d21d9fe6
> --- /dev/null
> +++ b/include/kunit/bug.h
It's a bit confusing to name this bug.h when we have the (admittedly
terribly-named) test-bug.h header already. I'm pretty tempted to rename
the latter to something like 'hooks.h', as that's really what it's for,
and having a separate bug.h would be an incentive to do so, though, sit
it's not a big problem.
I do think that it'd be reasonable to include the backtrace suppression
tuff in the same file, though, if you'd rather. The
__kunit_is_suppressed_warning() stuff in particular fits the category of
"code called to change behaviour based on whether or not a test is
running", which is generally what the hooks are for. (And, if you'd
rather, there's a bunch of existing hooks and hook infrastructure you
could use.)
> @@ -0,0 +1,56 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * KUnit helpers for backtrace suppression
> + *
> + * Copyright (C) 2025 Alessandro Carminati <acarmina@redhat.com>
> + * Copyright (C) 2024 Guenter Roeck <linux@roeck-us.net>
> + */
> +
> +#ifndef _KUNIT_BUG_H
> +#define _KUNIT_BUG_H
> +
> +#ifndef __ASSEMBLY__
> +
> +#include <linux/kconfig.h>
> +
> +struct kunit;
> +
> +#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
> +
> +#include <linux/types.h>
> +
> +struct task_struct;
> +
> +struct __suppressed_warning {
> + struct list_head node;
> + struct task_struct *task;
> + int counter;
> +};
> +
> +struct __suppressed_warning *
> +__kunit_start_suppress_warning(struct kunit *test);
> +void __kunit_end_suppress_warning(struct kunit *test,
> + struct __suppressed_warning *warning);
> +int __kunit_suppressed_warning_count(struct __suppressed_warning *warning);
> +bool __kunit_is_suppressed_warning(void);
> +
> +#define KUNIT_START_SUPPRESSED_WARNING(test) \
> + struct __suppressed_warning *__kunit_suppress = \
> + __kunit_start_suppress_warning(test)
> +
> +#define KUNIT_END_SUPPRESSED_WARNING(test) \
> + __kunit_end_suppress_warning(test, __kunit_suppress)
> +
> +#define KUNIT_SUPPRESSED_WARNING_COUNT() \
> + __kunit_suppressed_warning_count(__kunit_suppress)
Using a local variable (__kunit_suppress) here means that all of the
above macros must live in the same function. This is probably okay for
most use-cases, but more complicated tests may have to structure things
carefully. It also prevents there from being multiple START/END pairs in
the same function, and the KUNIT_SUPPRESSED_WARNING_COUNT() macro from
appearing before _START().
It also makes it less obvious that this cleans up nicely if the test
exits uncleanly, as the variable will have gone out-of-scope. (But given
we're just storing a pointer to heap-allocated memory, and
kunit_add_action() is used, it should be okay.)
One other option would be to allocate the suppression as a named
resource, which could then be retrieved from anywhere within the test
with kunit_find_named_resource(). (Though handling nested suppressions
gets a little more complicated here.)
Or you could make the struct __suppressed_warning pointer returned
explicitly user-visible, and let the user pass it around (though that
seems more work).
> +
> +#else /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
> +
> +#define KUNIT_START_SUPPRESSED_WARNING(test)
> +#define KUNIT_END_SUPPRESSED_WARNING(test)
> +#define KUNIT_SUPPRESSED_WARNING_COUNT() 0
> +static inline bool __kunit_is_suppressed_warning(void) { return false; }
> +
> +#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
> +#endif /* __ASSEMBLY__ */
> +#endif /* _KUNIT_BUG_H */
> diff --git a/include/kunit/test.h b/include/kunit/test.h
> index 9cd1594ab697d..4ec07b3fa0204 100644
> --- a/include/kunit/test.h
> +++ b/include/kunit/test.h
> @@ -10,6 +10,7 @@
> #define _KUNIT_TEST_H
>
> #include <kunit/assert.h>
> +#include <kunit/bug.h>
> #include <kunit/try-catch.h>
>
> #include <linux/args.h>
> diff --git a/kernel/panic.c b/kernel/panic.c
> index c78600212b6c1..d7a7a679f56c4 100644
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -39,6 +39,7 @@
> #include <linux/sys_info.h>
> #include <trace/events/error_report.h>
> #include <asm/sections.h>
> +#include <kunit/bug.h>
>
> #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 = warn_rcu_enter();
> + bool rcu;
> struct warn_args args;
>
> + if (__kunit_is_suppressed_warning())
> + return;
> +
> + rcu = warn_rcu_enter();
> +
> pr_warn(CUT_HERE);
>
> if (!fmt) {
> diff --git a/lib/bug.c b/lib/bug.c
> index 623c467a8b76c..606205c8c302f 100644
> --- a/lib/bug.c
> +++ b/lib/bug.c
> @@ -48,6 +48,7 @@
> #include <linux/rculist.h>
> #include <linux/ftrace.h>
> #include <linux/context_tracking.h>
> +#include <kunit/bug.h>
>
> extern struct bug_entry __start___bug_table[], __stop___bug_table[];
>
> @@ -223,6 +224,13 @@ static enum bug_trap_type __report_bug(struct bug_entry *bug, unsigned long buga
> no_cut = bug->flags & BUGFLAG_NO_CUT_HERE;
> has_args = bug->flags & BUGFLAG_ARGS;
>
> + /*
> + * Before the once logic so suppressed warnings do not consume
> + * the single-fire budget of WARN_ON_ONCE().
> + */
> + if (warning && __kunit_is_suppressed_warning())
> + return BUG_TRAP_TYPE_WARN;
> +
While any competant optimiser should get rid of this entirely, it might
be clearer to anyone reading it that this disappears if we just put it
behind an #ifdef?
> if (warning && once) {
> if (done)
> return BUG_TRAP_TYPE_WARN;
> diff --git a/lib/kunit/Kconfig b/lib/kunit/Kconfig
> index 498cc51e493dc..57527418fcf09 100644
> --- a/lib/kunit/Kconfig
> +++ b/lib/kunit/Kconfig
> @@ -15,6 +15,15 @@ menuconfig KUNIT
>
> if KUNIT
>
> +config KUNIT_SUPPRESS_BACKTRACE
> + bool "KUnit - Enable backtrace suppression"
> + default y
> + help
> + Enable backtrace suppression for KUnit. If enabled, backtraces
> + generated intentionally by KUnit tests are suppressed. Disable
> + to reduce kernel image size if image size is more important than
> + suppression of backtraces generated by KUnit tests.
> +
> config KUNIT_DEBUGFS
> bool "KUnit - Enable /sys/kernel/debug/kunit debugfs representation" if !KUNIT_ALL_TESTS
> default KUNIT_ALL_TESTS
> diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile
> index 656f1fa35abcc..fe177ff3ebdef 100644
> --- a/lib/kunit/Makefile
> +++ b/lib/kunit/Makefile
> @@ -16,8 +16,10 @@ ifeq ($(CONFIG_KUNIT_DEBUGFS),y)
> kunit-objs += debugfs.o
> endif
>
> -# KUnit 'hooks' are built-in even when KUnit is built as a module.
> -obj-$(if $(CONFIG_KUNIT),y) += hooks.o
> +# KUnit 'hooks' and bug handling are built-in even when KUnit is built
> +# as a module.
> +obj-$(if $(CONFIG_KUNIT),y) += hooks.o \
> + bug.o
Is there any reason we couldn't implement this on top of the hooks
mechanism? Then we could include the bug suppression code in the
kunit.ko module (albeit, with fewer possibilities for the compiler to
optimise things, as they'd have to go through an indirect pointer).
>
> obj-$(CONFIG_KUNIT_TEST) += kunit-test.o
> obj-$(CONFIG_KUNIT_TEST) += platform-test.o
> diff --git a/lib/kunit/bug.c b/lib/kunit/bug.c
> new file mode 100644
> index 0000000000000..356c8a5928828
> --- /dev/null
> +++ b/lib/kunit/bug.c
> @@ -0,0 +1,84 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * KUnit helpers for backtrace suppression
> + *
> + * Copyright (C) 2025 Alessandro Carminati <acarmina@redhat.com>
> + * Copyright (C) 2024 Guenter Roeck <linux@roeck-us.net>
> + */
> +
> +#include <kunit/bug.h>
> +#include <kunit/resource.h>
> +#include <linux/export.h>
> +#include <linux/rculist.h>
> +#include <linux/sched.h>
> +
> +#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
> +
> +static LIST_HEAD(suppressed_warnings);
> +
> +static void __kunit_suppress_warning_remove(struct __suppressed_warning *warning)
> +{
> + list_del_rcu(&warning->node);
> + synchronize_rcu(); /* Wait for readers to finish */
> +}
> +
> +KUNIT_DEFINE_ACTION_WRAPPER(__kunit_suppress_warning_cleanup,
> + __kunit_suppress_warning_remove,
> + struct __suppressed_warning *);
> +
> +struct __suppressed_warning *
> +__kunit_start_suppress_warning(struct kunit *test)
> +{
> + struct __suppressed_warning *warning;
> + int ret;
> +
> + warning = kunit_kzalloc(test, sizeof(*warning), GFP_KERNEL);
> + if (!warning)
> + return NULL;
> +
> + warning->task = current;
> + list_add_rcu(&warning->node, &suppressed_warnings);
> +
> + ret = kunit_add_action_or_reset(test,
> + __kunit_suppress_warning_cleanup,
> + warning);
> + if (ret)
> + return NULL;
> +
> + return warning;
> +}
> +EXPORT_SYMBOL_GPL(__kunit_start_suppress_warning);
> +
> +void __kunit_end_suppress_warning(struct kunit *test,
> + struct __suppressed_warning *warning)
> +{
> + if (!warning)
> + return;
> + kunit_release_action(test, __kunit_suppress_warning_cleanup, warning);
> +}
> +EXPORT_SYMBOL_GPL(__kunit_end_suppress_warning);
> +
> +int __kunit_suppressed_warning_count(struct __suppressed_warning *warning)
> +{
> + return warning ? warning->counter : 0;
> +}
> +EXPORT_SYMBOL_GPL(__kunit_suppressed_warning_count);
> +
> +bool __kunit_is_suppressed_warning(void)
> +{
> + struct __suppressed_warning *warning;
> +
> + rcu_read_lock();
> + list_for_each_entry_rcu(warning, &suppressed_warnings, node) {
> + if (warning->task == current) {
> + warning->counter++;
> + rcu_read_unlock();
> + return true;
> + }
> + }
> + rcu_read_unlock();
> +
> + return false;
> +}
Note to self: this is _not_ exported, as bug.c is being built-in
regardless of whether or not KUnit is a module. If we used the hook
system, it could live in kunit.ko, and would be manually exported by
kunit_install_hooks()
> +
> +#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
>
Thanks again,
-- David
^ permalink raw reply
* Re: [PATCH v2 3/3] Documentation: deprecated.rst: kmalloc-family: mark argument as optional
From: Geert Uytterhoeven @ 2026-04-22 12:15 UTC (permalink / raw)
To: Manuel Ebner
Cc: Jonathan Corbet, Shuah Khan, linux-doc, Kees Cook, linux-kernel,
workflows
In-Reply-To: <a5522bdaf37c7f1d2fdf03e1755061a4d803efb2.camel@mailbox.org>
Hi Manuel,
On Wed, 22 Apr 2026 at 14:10, Manuel Ebner <manuelebner@mailbox.org> wrote:
> On Wed, 2026-04-22 at 09:14 +0200, Geert Uytterhoeven wrote:
> > On Tue, 21 Apr 2026 at 20:09, Manuel Ebner <manuelebner@mailbox.org> wrote:
> > > put the optional argument (gfp) in square brackets
> > >
> > > eg. ptr = kmalloc_obj(*ptr, gfp);
> > > -> ptr = kmalloc_obj(*ptr, [gfp]);
> >
> > Shouldn't that be "[, gfp]", e.g.
> >
> > kmalloc_obj(*ptr [, gfp]);
>
> I think technically it should be
>
> kmalloc_obj(*ptr[, gfp]);
>
> but that's difficult to grasp, so i went for my notation. Yours
> is a good tradeoff. I'll think about it and choose the right one.
A third option is
kmalloc_obj(*ptr [, gfp] );
or even:
kmalloc_obj(*ptr [ , gfp ] );
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v2 3/3] Documentation: deprecated.rst: kmalloc-family: mark argument as optional
From: Manuel Ebner @ 2026-04-22 12:09 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Jonathan Corbet, Shuah Khan, linux-doc, Kees Cook, linux-kernel,
workflows
In-Reply-To: <CAMuHMdV70GhNsxPiuhY92seZRMkr6jk9eFCke7shc08GYerLpg@mail.gmail.com>
On Wed, 2026-04-22 at 09:14 +0200, Geert Uytterhoeven wrote:
> Hi Manuel,
>
> Thanks for your patch!
That's good to read.
> On Tue, 21 Apr 2026 at 20:09, Manuel Ebner <manuelebner@mailbox.org> wrote:
> > put the optional argument (gfp) in square brackets
> >
> > eg. ptr = kmalloc_obj(*ptr, gfp);
> > -> ptr = kmalloc_obj(*ptr, [gfp]);
>
> Shouldn't that be "[, gfp]", e.g.
>
> kmalloc_obj(*ptr [, gfp]);
I think technically it should be
kmalloc_obj(*ptr[, gfp]);
but that's difficult to grasp, so i went for my notation. Yours
is a good tradeoff. I'll think about it and choose the right one.
>
> everywhere?
>
> > Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
>
> Gr{oetje,eeting}s,
>
> Geert
^ permalink raw reply
* Re: [PATCH v2 3/3] Documentation: deprecated.rst: kmalloc-family: mark argument as optional
From: Geert Uytterhoeven @ 2026-04-22 7:14 UTC (permalink / raw)
To: Manuel Ebner
Cc: Jonathan Corbet, Shuah Khan, linux-doc, Kees Cook, linux-kernel,
workflows
In-Reply-To: <20260421180902.225560-2-manuelebner@mailbox.org>
Hi Manuel,
Thanks for your patch!
On Tue, 21 Apr 2026 at 20:09, Manuel Ebner <manuelebner@mailbox.org> wrote:
> put the optional argument (gfp) in square brackets
>
> eg. ptr = kmalloc_obj(*ptr, gfp);
> -> ptr = kmalloc_obj(*ptr, [gfp]);
Shouldn't that be "[, gfp]", e.g.
kmalloc_obj(*ptr [, gfp]);
everywhere?
> Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v2 1/3] Documentation: adopt new coding style of type-aware kmalloc-family
From: Manuel Ebner @ 2026-04-21 19:50 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Jonathan Corbet, Shuah Khan, linux-doc, Kees Cook, linux-kernel,
workflows, linux-sound, linux-media, linux-mm
In-Reply-To: <aefPCV4ZvrnrCmoH@casper.infradead.org>
On Tue, 2026-04-21 at 20:24 +0100, Matthew Wilcox wrote:
> On Tue, Apr 21, 2026 at 08:01:58PM +0200, Manuel Ebner wrote:
> > +++ b/Documentation/core-api/memory-allocation.rst
> > @@ -135,7 +135,7 @@ Selecting memory allocator
> > The most straightforward way to allocate memory is to use a function
> > from the kmalloc() family. And, to be on the safe side it's best to use
> > routines that set memory to zero, like kzalloc(). If you need to
> > -allocate memory for an array, there are kmalloc_array() and kcalloc()
> > +allocate memory for an array, there are kmalloc_objs() and kzalloc_objs()
> > helpers. The helpers struct_size(), array_size() and array3_size() can
> > be used to safely calculate object sizes without overflowing.
>
> This seems to have been done without any thought. kmalloc_array() still
> exists and has over 500 callers. It should not be de-documented.
you are right
> > @@ -151,7 +151,7 @@ sizes, the alignment is guaranteed to be at least the
> > largest power-of-two
> > divisor of the size.
> >
> > Chunks allocated with kmalloc() can be resized with krealloc(). Similarly
> > -to kmalloc_array(): a helper for resizing arrays is provided in the form of
> > +to kmalloc_objs(): a helper for resizing arrays is provided in the form of
> > krealloc_array().
>
> Think about why this is wrong too.
i see now.
> And you should have cc'd linux-mm on this.
will add in [v3]
thanks,
manuel
^ permalink raw reply
* Re: [PATCH v2 1/3] Documentation: adopt new coding style of type-aware kmalloc-family
From: Matthew Wilcox @ 2026-04-21 19:24 UTC (permalink / raw)
To: Manuel Ebner
Cc: Jonathan Corbet, Shuah Khan, linux-doc, Kees Cook, linux-kernel,
workflows, linux-sound, linux-media
In-Reply-To: <20260421180200.225244-2-manuelebner@mailbox.org>
On Tue, Apr 21, 2026 at 08:01:58PM +0200, Manuel Ebner wrote:
> +++ b/Documentation/core-api/memory-allocation.rst
> @@ -135,7 +135,7 @@ Selecting memory allocator
> The most straightforward way to allocate memory is to use a function
> from the kmalloc() family. And, to be on the safe side it's best to use
> routines that set memory to zero, like kzalloc(). If you need to
> -allocate memory for an array, there are kmalloc_array() and kcalloc()
> +allocate memory for an array, there are kmalloc_objs() and kzalloc_objs()
> helpers. The helpers struct_size(), array_size() and array3_size() can
> be used to safely calculate object sizes without overflowing.
This seems to have been done without any thought. kmalloc_array() still
exists and has over 500 callers. It should not be de-documented.
> @@ -151,7 +151,7 @@ sizes, the alignment is guaranteed to be at least the largest power-of-two
> divisor of the size.
>
> Chunks allocated with kmalloc() can be resized with krealloc(). Similarly
> -to kmalloc_array(): a helper for resizing arrays is provided in the form of
> +to kmalloc_objs(): a helper for resizing arrays is provided in the form of
> krealloc_array().
Think about why this is wrong too.
And you should have cc'd linux-mm on this.
^ permalink raw reply
* [PATCH v2 3/3] Documentation: deprecated.rst: kmalloc-family: mark argument as optional
From: Manuel Ebner @ 2026-04-21 18:09 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, linux-doc, Kees Cook, linux-kernel
Cc: workflows, Manuel Ebner
In-Reply-To: <20260421175516.224960-2-manuelebner@mailbox.org>
put the optional argument (gfp) in square brackets
eg. ptr = kmalloc_obj(*ptr, gfp);
-> ptr = kmalloc_obj(*ptr, [gfp]);
Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
---
Documentation/process/deprecated.rst | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/Documentation/process/deprecated.rst b/Documentation/process/deprecated.rst
index fed56864d036..b431993fd08e 100644
--- a/Documentation/process/deprecated.rst
+++ b/Documentation/process/deprecated.rst
@@ -392,12 +392,12 @@ allocations. For example, these open coded assignments::
become, respectively::
- ptr = kmalloc_obj(*ptr, gfp);
- ptr = kzalloc_obj(*ptr, gfp);
- ptr = kmalloc_objs(*ptr, count, gfp);
- ptr = kzalloc_objs(*ptr, count, gfp);
- ptr = kmalloc_flex(*ptr, flex_member, count, gfp);
- __auto_type ptr = kmalloc_obj(struct foo, gfp);
+ ptr = kmalloc_obj(*ptr, [gfp]);
+ ptr = kzalloc_obj(*ptr, [gfp]);
+ ptr = kmalloc_objs(*ptr, count, [gfp]);
+ ptr = kzalloc_objs(*ptr, count, [gfp]);
+ ptr = kmalloc_flex(*ptr, flex_member, count, [gfp]);
+ __auto_type ptr = kmalloc_obj(struct foo, [gfp]);
If `ptr->flex_member` is annotated with __counted_by(), the allocation
will automatically fail if `count` is larger than the maximum
--
2.53.0
^ permalink raw reply related
* [PATCH v2 1/3] Documentation: adopt new coding style of type-aware kmalloc-family
From: Manuel Ebner @ 2026-04-21 18:01 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, linux-doc
Cc: Kees Cook, linux-kernel, workflows, linux-sound, linux-media,
Manuel Ebner
In-Reply-To: <20260421175516.224960-2-manuelebner@mailbox.org>
Update the documentation to reflect new type-aware kmalloc-family as
suggested in commit 2932ba8d9c99 ("slab: Introduce kmalloc_obj() and family")
ptr = kmalloc(sizeof(*ptr), gfp);
-> ptr = kmalloc_obj(*ptr);
ptr = kmalloc(sizeof(struct some_obj_name), gfp);
-> ptr = kmalloc_obj(*ptr);
ptr = kzalloc(sizeof(*ptr), gfp);
-> ptr = kzalloc_obj(*ptr);
ptr = kmalloc_array(count, sizeof(*ptr), gfp);
-> ptr = kmalloc_objs(*ptr, count);
ptr = kcalloc(count, sizeof(*ptr), gfp);
-> ptr = kzalloc_objs(*ptr, count);
Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
---
Documentation/core-api/kref.rst | 4 ++--
Documentation/core-api/list.rst | 4 ++--
Documentation/core-api/memory-allocation.rst | 4 ++--
Documentation/driver-api/mailbox.rst | 4 ++--
Documentation/driver-api/media/v4l2-fh.rst | 2 +-
Documentation/kernel-hacking/locking.rst | 4 ++--
Documentation/locking/locktypes.rst | 4 ++--
Documentation/process/coding-style.rst | 8 ++++----
.../sound/kernel-api/writing-an-alsa-driver.rst | 12 ++++++------
Documentation/spi/spi-summary.rst | 4 ++--
.../translations/it_IT/kernel-hacking/locking.rst | 4 ++--
.../translations/it_IT/locking/locktypes.rst | 4 ++--
.../translations/it_IT/process/coding-style.rst | 2 +-
.../translations/sp_SP/process/coding-style.rst | 2 +-
Documentation/translations/zh_CN/core-api/kref.rst | 4 ++--
.../translations/zh_CN/process/coding-style.rst | 2 +-
.../zh_CN/video4linux/v4l2-framework.txt | 2 +-
.../translations/zh_TW/process/coding-style.rst | 2 +-
18 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/Documentation/core-api/kref.rst b/Documentation/core-api/kref.rst
index 8db9ff03d952..1c14c036699d 100644
--- a/Documentation/core-api/kref.rst
+++ b/Documentation/core-api/kref.rst
@@ -40,7 +40,7 @@ kref_init as so::
struct my_data *data;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kmalloc_obj(*data);
if (!data)
return -ENOMEM;
kref_init(&data->refcount);
@@ -100,7 +100,7 @@ thread to process::
int rv = 0;
struct my_data *data;
struct task_struct *task;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kmalloc_obj(*data);
if (!data)
return -ENOMEM;
kref_init(&data->refcount);
diff --git a/Documentation/core-api/list.rst b/Documentation/core-api/list.rst
index 241464ca0549..86cd0a1b77ea 100644
--- a/Documentation/core-api/list.rst
+++ b/Documentation/core-api/list.rst
@@ -112,7 +112,7 @@ list:
/* State 1 */
- grock = kzalloc(sizeof(*grock), GFP_KERNEL);
+ grock = kzalloc_obj(*grock);
if (!grock)
return -ENOMEM;
grock->name = "Grock";
@@ -123,7 +123,7 @@ list:
/* State 2 */
- dimitri = kzalloc(sizeof(*dimitri), GFP_KERNEL);
+ dimitri = kzalloc_obj(*dimitri);
if (!dimitri)
return -ENOMEM;
dimitri->name = "Dimitri";
diff --git a/Documentation/core-api/memory-allocation.rst b/Documentation/core-api/memory-allocation.rst
index 0f19dd524323..8379775f17d3 100644
--- a/Documentation/core-api/memory-allocation.rst
+++ b/Documentation/core-api/memory-allocation.rst
@@ -135,7 +135,7 @@ Selecting memory allocator
The most straightforward way to allocate memory is to use a function
from the kmalloc() family. And, to be on the safe side it's best to use
routines that set memory to zero, like kzalloc(). If you need to
-allocate memory for an array, there are kmalloc_array() and kcalloc()
+allocate memory for an array, there are kmalloc_objs() and kzalloc_objs()
helpers. The helpers struct_size(), array_size() and array3_size() can
be used to safely calculate object sizes without overflowing.
@@ -151,7 +151,7 @@ sizes, the alignment is guaranteed to be at least the largest power-of-two
divisor of the size.
Chunks allocated with kmalloc() can be resized with krealloc(). Similarly
-to kmalloc_array(): a helper for resizing arrays is provided in the form of
+to kmalloc_objs(): a helper for resizing arrays is provided in the form of
krealloc_array().
For large allocations you can use vmalloc() and vzalloc(), or directly
diff --git a/Documentation/driver-api/mailbox.rst b/Documentation/driver-api/mailbox.rst
index 463dd032b96c..4bcd73a99115 100644
--- a/Documentation/driver-api/mailbox.rst
+++ b/Documentation/driver-api/mailbox.rst
@@ -87,8 +87,8 @@ a message and a callback function to the API and return immediately).
struct async_pkt ap;
struct sync_pkt sp;
- dc_sync = kzalloc(sizeof(*dc_sync), GFP_KERNEL);
- dc_async = kzalloc(sizeof(*dc_async), GFP_KERNEL);
+ dc_sync = kzalloc_obj(*dc_sync);
+ dc_async = kzalloc_obj(*dc_async);
/* Populate non-blocking mode client */
dc_async->cl.dev = &pdev->dev;
diff --git a/Documentation/driver-api/media/v4l2-fh.rst b/Documentation/driver-api/media/v4l2-fh.rst
index a934caa483a4..38319130ebf5 100644
--- a/Documentation/driver-api/media/v4l2-fh.rst
+++ b/Documentation/driver-api/media/v4l2-fh.rst
@@ -42,7 +42,7 @@ Example:
...
- my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
+ my_fh = kzalloc_obj(*my_fh);
...
diff --git a/Documentation/kernel-hacking/locking.rst b/Documentation/kernel-hacking/locking.rst
index dff0646a717b..d02e62367c4f 100644
--- a/Documentation/kernel-hacking/locking.rst
+++ b/Documentation/kernel-hacking/locking.rst
@@ -442,7 +442,7 @@ to protect the cache and all the objects within it. Here's the code::
{
struct object *obj;
- if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL)
+ if ((obj = kmalloc_obj(*obj)) == NULL)
return -ENOMEM;
strscpy(obj->name, name, sizeof(obj->name));
@@ -517,7 +517,7 @@ which are taken away, and the ``+`` are lines which are added.
struct object *obj;
+ unsigned long flags;
- if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL)
+ if ((obj = kmalloc_obj(*obj)) == NULL)
return -ENOMEM;
@@ -63,30 +64,33 @@
obj->id = id;
diff --git a/Documentation/locking/locktypes.rst b/Documentation/locking/locktypes.rst
index 37b6a5670c2f..ac1ad722a9e7 100644
--- a/Documentation/locking/locktypes.rst
+++ b/Documentation/locking/locktypes.rst
@@ -498,7 +498,7 @@ allocating memory. Thus, on a non-PREEMPT_RT kernel the following code
works perfectly::
raw_spin_lock(&lock);
- p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ p = kmalloc_obj(*p, GFP_ATOMIC);
But this code fails on PREEMPT_RT kernels because the memory allocator is
fully preemptible and therefore cannot be invoked from truly atomic
@@ -507,7 +507,7 @@ while holding normal non-raw spinlocks because they do not disable
preemption on PREEMPT_RT kernels::
spin_lock(&lock);
- p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ p = kmalloc_obj(*p, GFP_ATOMIC);
bit spinlocks
diff --git a/Documentation/process/coding-style.rst b/Documentation/process/coding-style.rst
index 35b381230f6e..a3bf75dc7c88 100644
--- a/Documentation/process/coding-style.rst
+++ b/Documentation/process/coding-style.rst
@@ -936,7 +936,7 @@ used.
---------------------
The kernel provides the following general purpose memory allocators:
-kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc(), and
+kmalloc(), kzalloc(), kmalloc_objs(), kzalloc_objs(), vmalloc(), and
vzalloc(). Please refer to the API documentation for further information
about them. :ref:`Documentation/core-api/memory-allocation.rst
<memory_allocation>`
@@ -945,7 +945,7 @@ The preferred form for passing a size of a struct is the following:
.. code-block:: c
- p = kmalloc(sizeof(*p), ...);
+ p = kmalloc_obj(*p, ...);
The alternative form where struct name is spelled out hurts readability and
introduces an opportunity for a bug when the pointer variable type is changed
@@ -959,13 +959,13 @@ The preferred form for allocating an array is the following:
.. code-block:: c
- p = kmalloc_array(n, sizeof(...), ...);
+ p = kmalloc_objs(*ptr, n, ...);
The preferred form for allocating a zeroed array is the following:
.. code-block:: c
- p = kcalloc(n, sizeof(...), ...);
+ p = kzalloc_objs(*ptr, n, ...);
Both forms check for overflow on the allocation size n * sizeof(...),
and return NULL if that occurred.
diff --git a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst
index 895752cbcedd..12433612aa9c 100644
--- a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst
+++ b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst
@@ -266,7 +266,7 @@ to details explained in the following section.
....
/* allocate a chip-specific data with zero filled */
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc_obj(*chip);
if (chip == NULL)
return -ENOMEM;
@@ -628,7 +628,7 @@ After allocating a card instance via :c:func:`snd_card_new()`
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
.....
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc_obj(*chip);
The chip record should have the field to hold the card pointer at least,
@@ -747,7 +747,7 @@ destructor and PCI entries. Example code is shown first, below::
return -ENXIO;
}
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc_obj(*chip);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
@@ -1737,7 +1737,7 @@ callback::
{
struct my_pcm_data *data;
....
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kmalloc_obj(*data);
substream->runtime->private_data = data;
....
}
@@ -3301,7 +3301,7 @@ You can then pass any pointer value to the ``private_data``. If you
assign private data, you should define a destructor, too. The
destructor function is set in the ``private_free`` field::
- struct mydata *p = kmalloc(sizeof(*p), GFP_KERNEL);
+ struct mydata *p = kmalloc_obj(*p);
hw->private_data = p;
hw->private_free = mydata_free;
@@ -3833,7 +3833,7 @@ chip data individually::
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
....
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc_obj(*chip);
....
card->private_data = chip;
....
diff --git a/Documentation/spi/spi-summary.rst b/Documentation/spi/spi-summary.rst
index 6e21e6f86912..7ad6af76c247 100644
--- a/Documentation/spi/spi-summary.rst
+++ b/Documentation/spi/spi-summary.rst
@@ -249,7 +249,7 @@ And SOC-specific utility code might look something like::
{
struct mysoc_spi_data *pdata2;
- pdata2 = kmalloc(sizeof *pdata2, GFP_KERNEL);
+ pdata2 = kmalloc_obj(*pdata2);
*pdata2 = pdata;
...
if (n == 2) {
@@ -373,7 +373,7 @@ a bus (appearing under /sys/class/spi_master).
return -ENODEV;
/* get memory for driver's per-chip state */
- chip = kzalloc(sizeof *chip, GFP_KERNEL);
+ chip = kzalloc(*chip);
if (!chip)
return -ENOMEM;
spi_set_drvdata(spi, chip);
diff --git a/Documentation/translations/it_IT/kernel-hacking/locking.rst b/Documentation/translations/it_IT/kernel-hacking/locking.rst
index 4c21cf60f775..acca89a3743a 100644
--- a/Documentation/translations/it_IT/kernel-hacking/locking.rst
+++ b/Documentation/translations/it_IT/kernel-hacking/locking.rst
@@ -462,7 +462,7 @@ e tutti gli oggetti che contiene. Ecco il codice::
{
struct object *obj;
- if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL)
+ if ((obj = kmalloc_obj(*obj)) == NULL)
return -ENOMEM;
strscpy(obj->name, name, sizeof(obj->name));
@@ -537,7 +537,7 @@ sono quelle rimosse, mentre quelle ``+`` sono quelle aggiunte.
struct object *obj;
+ unsigned long flags;
- if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL)
+ if ((obj = kmalloc_obj(*obj)) == NULL)
return -ENOMEM;
@@ -63,30 +64,33 @@
obj->id = id;
diff --git a/Documentation/translations/it_IT/locking/locktypes.rst b/Documentation/translations/it_IT/locking/locktypes.rst
index 1c7056283b9d..d5fa36aa05cc 100644
--- a/Documentation/translations/it_IT/locking/locktypes.rst
+++ b/Documentation/translations/it_IT/locking/locktypes.rst
@@ -488,7 +488,7 @@ o rwlock_t. Per esempio, la sezione critica non deve fare allocazioni di
memoria. Su un kernel non-PREEMPT_RT il seguente codice funziona perfettamente::
raw_spin_lock(&lock);
- p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ p = kmalloc_obj(*p, GFP_ATOMIC);
Ma lo stesso codice non funziona su un kernel PREEMPT_RT perché l'allocatore di
memoria può essere oggetto di prelazione e quindi non può essere chiamato in un
@@ -497,7 +497,7 @@ trattiene un blocco *non-raw* perché non disabilitano la prelazione sui kernel
PREEMPT_RT::
spin_lock(&lock);
- p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ p = kmalloc_obj(*p, GFP_ATOMIC);
bit spinlocks
diff --git a/Documentation/translations/it_IT/process/coding-style.rst b/Documentation/translations/it_IT/process/coding-style.rst
index c0dc786b8474..2a499412a2e3 100644
--- a/Documentation/translations/it_IT/process/coding-style.rst
+++ b/Documentation/translations/it_IT/process/coding-style.rst
@@ -943,7 +943,7 @@ Il modo preferito per passare la dimensione di una struttura è il seguente:
.. code-block:: c
- p = kmalloc(sizeof(*p), ...);
+ p = kmalloc_obj(*p, ...);
La forma alternativa, dove il nome della struttura viene scritto interamente,
peggiora la leggibilità e introduce possibili bachi quando il tipo di
diff --git a/Documentation/translations/sp_SP/process/coding-style.rst b/Documentation/translations/sp_SP/process/coding-style.rst
index 7d63aa8426e6..44c93d5f6beb 100644
--- a/Documentation/translations/sp_SP/process/coding-style.rst
+++ b/Documentation/translations/sp_SP/process/coding-style.rst
@@ -955,7 +955,7 @@ La forma preferida para pasar el tamaño de una estructura es la siguiente:
.. code-block:: c
- p = kmalloc(sizeof(*p), ...);
+ p = kmalloc_obj(*p, ...);
La forma alternativa donde se deletrea el nombre de la estructura perjudica
la legibilidad, y presenta una oportunidad para un error cuando se cambia
diff --git a/Documentation/translations/zh_CN/core-api/kref.rst b/Documentation/translations/zh_CN/core-api/kref.rst
index b9902af310c5..fcff01e99852 100644
--- a/Documentation/translations/zh_CN/core-api/kref.rst
+++ b/Documentation/translations/zh_CN/core-api/kref.rst
@@ -52,7 +52,7 @@ kref可以出现在数据结构体中的任何地方。
struct my_data *data;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kmalloc_obj(*data);
if (!data)
return -ENOMEM;
kref_init(&data->refcount);
@@ -106,7 +106,7 @@ Kref规则
int rv = 0;
struct my_data *data;
struct task_struct *task;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kmalloc_obj(*data);
if (!data)
return -ENOMEM;
kref_init(&data->refcount);
diff --git a/Documentation/translations/zh_CN/process/coding-style.rst b/Documentation/translations/zh_CN/process/coding-style.rst
index 5a342a024c01..55d5da974d89 100644
--- a/Documentation/translations/zh_CN/process/coding-style.rst
+++ b/Documentation/translations/zh_CN/process/coding-style.rst
@@ -813,7 +813,7 @@ Documentation/translations/zh_CN/core-api/memory-allocation.rst 。
.. code-block:: c
- p = kmalloc(sizeof(*p), ...);
+ p = kmalloc_obj(*p, ...);
另外一种传递方式中,sizeof 的操作数是结构体的名字,这样会降低可读性,并且可能
会引入 bug。有可能指针变量类型被改变时,而对应的传递给内存分配函数的 sizeof
diff --git a/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt b/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt
index f0be21a60a0f..ba43c5c4797c 100644
--- a/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt
+++ b/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt
@@ -799,7 +799,7 @@ int my_open(struct file *file)
...
- my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
+ my_fh = kzalloc_obj(*my_fh);
...
diff --git a/Documentation/translations/zh_TW/process/coding-style.rst b/Documentation/translations/zh_TW/process/coding-style.rst
index e2ba97b3d8bb..63c78982a1af 100644
--- a/Documentation/translations/zh_TW/process/coding-style.rst
+++ b/Documentation/translations/zh_TW/process/coding-style.rst
@@ -827,7 +827,7 @@ Documentation/translations/zh_CN/core-api/memory-allocation.rst 。
.. code-block:: c
- p = kmalloc(sizeof(*p), ...);
+ p = kmalloc_obj(*p, ...);
另外一種傳遞方式中,sizeof 的操作數是結構體的名字,這樣會降低可讀性,並且可能
會引入 bug。有可能指針變量類型被改變時,而對應的傳遞給內存分配函數的 sizeof
--
2.53.0
^ permalink raw reply related
* [PATCH v2 0/3] Documentation: adopt new coding style of type-aware kmalloc-family
From: Manuel Ebner @ 2026-04-21 17:55 UTC (permalink / raw)
To: Jonathan Corbet, Shuah Khan, linux-doc, Kees Cook
Cc: linux-kernel, workflows, linux-sound, rcu, linux-media,
Manuel Ebner
Update the documentation to reflect new type-aware kmalloc-family as
suggested in commit 2932ba8d9c99 ("slab: Introduce kmalloc_obj() and family")
I have also thought about adding a few cases to checkpatch.pl, but this
will take me some time, and i don't know if i can do it.
[v1] -> [v2]:
put RCU/* in a seperate patch [Patch 2/3]
Omit optional argument (GFP_KERNEL) as suggested by https://lwn.net/Articles/1062856/
deprecated.rst: change the argument gfp to optional [Patch 3/3]
Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
^ permalink raw reply
* Re: [PATCH] Documentation: adopt new coding style of type-aware kmalloc-family
From: Kees Cook @ 2026-04-21 17:25 UTC (permalink / raw)
To: Jonathan Corbet
Cc: Manuel Ebner, Shuah Khan, linux-doc, lrcu, linux-kernel,
workflows, linux-sound, rcu, linux-media
In-Reply-To: <87se8rw8df.fsf@trenco.lwn.net>
On Sun, Apr 19, 2026 at 04:29:48AM -0600, Jonathan Corbet wrote:
> Manuel Ebner <manuelebner@mailbox.org> writes:
>
> > Update the documentation to reflect new type-aware kmalloc-family as
> > suggested in commit 2932ba8d9c99 ("slab: Introduce kmalloc_obj() and family")
> >
> > ptr = kmalloc(sizeof(*ptr), gfp);
> > -> ptr = kmalloc_obj(*ptr, gfp);
> > ptr = kmalloc(sizeof(struct some_obj_name), gfp);
> > -> ptr = kmalloc_obj(*ptr, gfp);
> > ptr = kzalloc(sizeof(*ptr), gfp);
> > -> ptr = kzalloc_obj(*ptr, gfp);
> > ptr = kmalloc_array(count, sizeof(*ptr), gfp);
> > -> ptr = kmalloc_objs(*ptr, count, gfp);
> > ptr = kcalloc(count, sizeof(*ptr), gfp);
> > -> ptr = kzalloc_objs(*ptr, count, gfp);
> >
> > Signed-off-by: Manuel Ebner <manuelebner@mailbox.org>
>
> Just to be sure, did you write this patch yourself, or did you use some
> sort of coding assistant?
>
> Adding Kees, who did this work and might have something to add here.
>
> > ---
> > .../RCU/Design/Requirements/Requirements.rst | 6 +++---
> > Documentation/RCU/listRCU.rst | 2 +-
> > Documentation/RCU/whatisRCU.rst | 4 ++--
>
> This patch will surely need to be split up; the RCU folks, for example,
> will want to evaluate the change separately.
>
> > Documentation/core-api/kref.rst | 4 ++--
> > Documentation/core-api/list.rst | 4 ++--
> > Documentation/core-api/memory-allocation.rst | 4 ++--
> > Documentation/driver-api/mailbox.rst | 4 ++--
> > Documentation/driver-api/media/v4l2-fh.rst | 2 +-
> > Documentation/kernel-hacking/locking.rst | 4 ++--
> > Documentation/locking/locktypes.rst | 4 ++--
> > Documentation/process/coding-style.rst | 8 ++++----
> > .../sound/kernel-api/writing-an-alsa-driver.rst | 12 ++++++------
> > Documentation/spi/spi-summary.rst | 4 ++--
> > .../translations/it_IT/kernel-hacking/locking.rst | 4 ++--
> > .../translations/it_IT/locking/locktypes.rst | 4 ++--
> > .../translations/it_IT/process/coding-style.rst | 2 +-
> > .../translations/sp_SP/process/coding-style.rst | 2 +-
> > Documentation/translations/zh_CN/core-api/kref.rst | 4 ++--
> > .../translations/zh_CN/process/coding-style.rst | 2 +-
> > .../zh_CN/video4linux/v4l2-framework.txt | 2 +-
> > .../translations/zh_TW/process/coding-style.rst | 2 +-
> > 21 files changed, 42 insertions(+), 42 deletions(-)
> >
> > diff --git a/Documentation/RCU/Design/Requirements/Requirements.rst b/Documentation/RCU/Design/Requirements/Requirements.rst
> > index b5cdbba3ec2e..faca5a9c8c12 100644
> > --- a/Documentation/RCU/Design/Requirements/Requirements.rst
> > +++ b/Documentation/RCU/Design/Requirements/Requirements.rst
> > @@ -206,7 +206,7 @@ non-\ ``NULL``, locklessly accessing the ``->a`` and ``->b`` fields.
> >
> > 1 bool add_gp_buggy(int a, int b)
> > 2 {
> > - 3 p = kmalloc(sizeof(*p), GFP_KERNEL);
> > + 3 p = kmalloc_obj(*p, GFP_KERNEL);
>
> So you have not gone with the "implicit GFP_KERNEL" approach that Linus
> added. Given that, I assume, he wanted that to be the normal style, we
> should probably go with it.
Thank you for updating the documentation! Yes, please drop the "default"
GFP_KERNEL args in all these places. (Keep the non-GFP_KERNEL args; I
see at least GFP_ATOMIC in the docs.)
--
Kees Cook
^ permalink raw reply
* Re: [PATCH] Documentation: coding-assistants: add optional Acted-By: trailer
From: Konstantin Ryabitsev @ 2026-04-21 15:14 UTC (permalink / raw)
To: Blake Morrison
Cc: Jonathan Corbet, Shuah Khan, workflows, linux-doc, linux-kernel
In-Reply-To: <20260420142741.3187814-1-blake@truealter.com>
On Mon, Apr 20, 2026 at 02:27:46PM +0000, Blake Morrison wrote:
> The existing policy correctly separates AI tool attribution
> (Assisted-by:) from legal accountability (Signed-off-by:). In practice,
> contributors increasingly work across pseudonymous and legal-name
> contexts, and a third slot -- identifying the human sovereign identity
> under which the work was performed -- lets downstream tooling (CI,
> provenance trackers, identity systems) bind a commit to a stable handle
> without disturbing the DCO.
>
> Add Acted-By: as an optional, informational companion trailer. It does
> not replace Signed-off-by:, does not change DCO requirements, and does
> not mandate any format; the out-of-tree
> draft-morrison-identity-attributed-commits defines one such scheme, but
> contributors are free to use any handle form they prefer.
This is fairly orthogonal to what LF is already attempting to do with OpenVTC
(https://github.com/OpenVTC). I'm giving this a NACK for now, not because I'm
trying to stifle this work, but because it's going at it from the wrong angle.
The "Acted-by" trailer is clearly intended to be a field for a cryptographic
hash, not for a name/email combo.
As such, it will most likely never be accepted by the kernel community for the
same reason the community rejected the Change-ID trailer -- it's an obscure
string of characters that requires specialized tooling to parse.
Reading the IETF proposal, this is just one of the trailers proposed, as the
following are also mentioned in the draft:
1. Acted-By:
2. Executed-By:
3. Drafted-With:
4. Identity-Signature:
5. Identity-Key-Id:
6. Identity-Anchor:
I see that they need to be "optionally provided" but I can guarantee you that
a maintainer that sees a patch submission with a slew of trailers like that
will reject it (and you will get an earful from Linus).
I recommend that instead of starting by introducing a new trailer on the kernel
list, you send your overall scheme proposal to the git list instead. Some of
the claims in the draft are questionable (e.g. that tree hashes survive
rebase or cherry-pick operations), and are specifically suspect within the
context of the kernel's patch-based workflow. A tree-hash for a patch created
by the submitter will almost certainly become invalid when the maintainer runs
"git am" on their series, so the proposed scheme will never really work for
the kernel, because the vast majority of cryptographic hashes will never
validate.
So, NACK for now, and I do recommend you start on the git list instead.
-K
^ permalink raw reply
* Re: [PATCH v7 4/5] drm: Suppress intentional warning backtraces in scaling unit tests
From: Jani Nikula @ 2026-04-21 11:50 UTC (permalink / raw)
To: Albert Esteve, Peter Zijlstra
Cc: Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton,
linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-doc, Guenter Roeck,
Linux Kernel Functional Testing, Dan Carpenter, Maíra Canal,
Alessandro Carminati, Simona Vetter
In-Reply-To: <CADSE00JJq6fsYbkFN5hBD=-ZWsFG9p4_C55fp3MupMJQj0QCUQ@mail.gmail.com>
On Tue, 21 Apr 2026, Albert Esteve <aesteve@redhat.com> wrote:
> On Mon, Apr 20, 2026 at 4:47 PM Peter Zijlstra <peterz@infradead.org> wrote:
>>
>> On Mon, Apr 20, 2026 at 02:28:06PM +0200, Albert Esteve wrote:
>> > From: Guenter Roeck <linux@roeck-us.net>
>> >
>> > 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 <lkft@linaro.org>
>> > Acked-by: Dan Carpenter <dan.carpenter@linaro.org>
>> > Acked-by: Maíra Canal <mcanal@igalia.com>
>> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> > Cc: David Airlie <airlied@gmail.com>
>> > Cc: Daniel Vetter <daniel@ffwll.ch>
>> > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
>> > Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
>> > Signed-off-by: Albert Esteve <aesteve@redhat.com>
>> > ---
>> > drivers/gpu/drm/tests/drm_rect_test.c | 14 ++++++++++++++
>> > 1 file changed, 14 insertions(+)
>> >
>> > diff --git a/drivers/gpu/drm/tests/drm_rect_test.c b/drivers/gpu/drm/tests/drm_rect_test.c
>> > index 17e1f34b76101..1dd7d819165e7 100644
>> > --- a/drivers/gpu/drm/tests/drm_rect_test.c
>> > +++ b/drivers/gpu/drm/tests/drm_rect_test.c
>> > @@ -409,8 +409,15 @@ static void drm_test_rect_calc_hscale(struct kunit *test)
>> > const struct drm_rect_scale_case *params = test->param_value;
>> > int scaling_factor;
>> >
>> > + /*
>> > + * 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_START_SUPPRESSED_WARNING(test);
>> > scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst,
>> > params->min_range, params->max_range);
>> > + KUNIT_END_SUPPRESSED_WARNING(test);
>>
>> Would not something like:
>>
>> scoped_kunit_suppress() {
>> scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst,
>> params->min_range, params->max_range);
>> }
>>
>> be better?
>
> Since KUnit already has a few macros in its API it didn't occur to me.
> Good idea, I like it. And I guess the scope approach matches well with
> your __cleanup comment in the first patch. If no one opposes, I will
> work toward that pattern for the next version.
There's a catch with kunit and __cleanup and thus (scoped) guards. Kunit
runs in ktreads, asserts lead to kthread_exit() and the __cleanup won't
be called.
Warning suppression being part of kunit infrastructure, asserts can and
should end the suppression too. But setting the example (scoped) guards
are safe in kunit tests in general feels like a trap waiting to happen.
BR,
Jani.
>
>>
>> Also, how can you stand all this screaming in the code?
>>
>
> Again, KUnit already contains many macros, so this use didn't register
> as such. Now I will not be able to unsee it.
>
>
--
Jani Nikula, Intel
^ permalink raw reply
* Re: [PATCH v7 4/5] drm: Suppress intentional warning backtraces in scaling unit tests
From: Albert Esteve @ 2026-04-21 8:49 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton,
linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-doc, Guenter Roeck,
Linux Kernel Functional Testing, Dan Carpenter, Maíra Canal,
Alessandro Carminati, Simona Vetter
In-Reply-To: <20260420144702.GM3102624@noisy.programming.kicks-ass.net>
On Mon, Apr 20, 2026 at 4:47 PM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Mon, Apr 20, 2026 at 02:28:06PM +0200, Albert Esteve wrote:
> > From: Guenter Roeck <linux@roeck-us.net>
> >
> > 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 <lkft@linaro.org>
> > Acked-by: Dan Carpenter <dan.carpenter@linaro.org>
> > Acked-by: Maíra Canal <mcanal@igalia.com>
> > Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Cc: David Airlie <airlied@gmail.com>
> > Cc: Daniel Vetter <daniel@ffwll.ch>
> > Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> > Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
> > Signed-off-by: Albert Esteve <aesteve@redhat.com>
> > ---
> > drivers/gpu/drm/tests/drm_rect_test.c | 14 ++++++++++++++
> > 1 file changed, 14 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/tests/drm_rect_test.c b/drivers/gpu/drm/tests/drm_rect_test.c
> > index 17e1f34b76101..1dd7d819165e7 100644
> > --- a/drivers/gpu/drm/tests/drm_rect_test.c
> > +++ b/drivers/gpu/drm/tests/drm_rect_test.c
> > @@ -409,8 +409,15 @@ static void drm_test_rect_calc_hscale(struct kunit *test)
> > const struct drm_rect_scale_case *params = test->param_value;
> > int scaling_factor;
> >
> > + /*
> > + * 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_START_SUPPRESSED_WARNING(test);
> > scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst,
> > params->min_range, params->max_range);
> > + KUNIT_END_SUPPRESSED_WARNING(test);
>
> Would not something like:
>
> scoped_kunit_suppress() {
> scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst,
> params->min_range, params->max_range);
> }
>
> be better?
Since KUnit already has a few macros in its API it didn't occur to me.
Good idea, I like it. And I guess the scope approach matches well with
your __cleanup comment in the first patch. If no one opposes, I will
work toward that pattern for the next version.
>
> Also, how can you stand all this screaming in the code?
>
Again, KUnit already contains many macros, so this use didn't register
as such. Now I will not be able to unsee it.
^ permalink raw reply
* Re: [PATCH v7 2/5] bug/kunit: Reduce runtime impact of warning backtrace suppression
From: Albert Esteve @ 2026-04-21 8:41 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton,
linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-doc, Alessandro Carminati
In-Reply-To: <20260420144453.GK3102624@noisy.programming.kicks-ass.net>
On Mon, Apr 20, 2026 at 4:45 PM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Mon, Apr 20, 2026 at 02:28:04PM +0200, Albert Esteve wrote:
> > From: Alessandro Carminati <acarmina@redhat.com>
> >
> > 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@redhat.com>
> > Signed-off-by: Albert Esteve <aesteve@redhat.com>
> > ---
> > 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) {
> >
>
> So the thing you're skipping is:
>
> rcu_read_lock();
> list_for_each_entry_rcu() {
> }
> rcu_read_unlock();
>
> Which is really cheap. Did you actually have performance numbers for
> this?
No, I do not have performance numbers. I kept the counter and the
separate patch for consistency with the previous version of the
series. But you have a good point, the skipped part is really cheap.
>
> A possibly better option is to add a static_branch() that could elide
> any and all memory access.
>
Previous version had static_branch and I removed it because I
understood from the discussion that the gains would not be significant
as performance gains are irrelevant in warn slowpath. But I think it
would make sense for a disabled feature. I will rework this for the
next version, remove the counter and use static_branch as suggested.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox