* [RFC PATCH v2.1 00/28] mm/damon: introduce data attributes monitoring
From: SeongJae Park @ 2026-05-14 14:08 UTC (permalink / raw)
Cc: SeongJae Park, Liam R. Howlett, Andrew Morton, David Hildenbrand,
Jonathan Corbet, Lorenzo Stoakes, Masami Hiramatsu,
Mathieu Desnoyers, Michal Hocko, Mike Rapoport, Shuah Khan,
Shuah Khan, Steven Rostedt, Suren Baghdasaryan, Vlastimil Babka,
damon, linux-doc, linux-kernel, linux-kselftest, linux-mm,
linux-trace-kernel
TL; DR
======
Extend DAMON for monitoring general data attributes other than accesses.
The short term motivation is lightweight page type (e.g., belonging
cgroup) aware monitoring. In long term, this will help extending DAMON
for multiple access events capture primitives (e.g., page faults and
PMU) and eventually pivotting DAMON to a "Data Attributes Monitoring and
Operations eNgine" in long term.
Background: High Cost of Page Level Properties Monitoring
=========================================================
DAMON is initially introduced as a Data Access MONitor. It has been
extended for not only access monitoring but also data access-aware
system operations (DAMOS). But still the monitoring part is only for
data accesses.
Data access patterns is good information, but some users need more
holistic views. Particularly, users want to show the access pattern
information together with the types of the memory. For example, users
who work for making huge pages efficiently want to know how much of
DAMON-found hot/cold regions are backed by huge pages. Users who run
multiple workloads with different cgroups want to know how much of
DAMON-found hot/cold regions belong to specific cgroups.
For the user demand, we developed a DAMOS extension for page level
properties based monitoring [1], which has landed on 6.14. Using the
feature, users can inform the page level data properties that they are
interested in, in a flexible format that uses DAMOS filters. Then,
DAMON applies the filters to each folio of the entire DAMON region and
lets users know how many bytes of memory in each DAMON region passed the
given filters.
This gives page level detailed and deterministic information to users.
But, because the operation is done at page level, the overhead is
proportional to the memory size. It was useful for test or debugging
purposes on a small number of machines. But it was obviously too heavy
to be enabled always on all machines running the real user workloads.
For real world workloads, it was recommended to use the feature with
user-space controlled sampling approaches. For example, users could do
the page level monitoring only once per hour, on randomly selected one
percent of machines of their fleet. If the runtime and the size of the
fleet is long and big enough, it should provide statistically meaningful
data.
But users are too busy to implement such controls on their own.
Data Attributes Monitoring
==========================
Extend DAMON to monitor not only data accesses, but also general data
attributes. Do the extension while keeping the main promise of DAMON,
the bounded and best-effort minimum overhead.
Allow users to specify what data attributes in addition to the data
access they want to monitor. Users can install one 'data probe' per
data attribute of their interest for this purpose. The 'data probe'
should be able to be applied to any memory, and determine if the given
memory has the appropriate data attribute. E.g., if memory of physical
address 42 belongs to cgroup A. Each 'data probe' is configured with
filters that are very similar to the DAMOS filters.
When DAMON checks if each sampling address memory of each region is
accessed since the last check, it applies data probes if registered.
Same to the number of access check-positive samples accounting
(nr_accesses), it accounts the number of each data probe-positive
samples in another per-region counters array, namely 'probe_hits'. When
DAMON resets nr_accesses every aggregation interval, it resets
'probe_hits' together.
Users can read 'probe_hits' just before the values are reset. In this
way, users can know how many hot/cold memory regions have data
attributes of their interest. E.g., 30 percent of this system's hot
memory is belonging to cgroup A, and 80 percent of the cgroup
A-belonging hot memory is backed by huge pages.
Patches Sequence
================
First eight patches implement the core feature, interface and the
working support. Patch 1 introduces data probe data structure, namely
damon_probe. Patch 2 extends damon_ctx for installing data probes.
Patch 3 introduces another data structure for filters of each data
probe, namely damon_filter. Patch 4 updates damon_ctx commit function
to handle the probes. Patch 5 extends damon_region for the per-region
per-probe positive samples counter, namely probe_hits. Patch 6 extends
damon_operations for applying probes on the underlying DAMON operations
implementation. Patch 7 updates kdamond_fn() to invoke the probes
applying callback. Patch 8 finally implements the probes support on
paddr ops.
Ten changes for user interface (patches 9-18) come next. Patches 9-13
implements sysfs directories and files for setting data probes, namely
probes directory, probe directory, filters directory, filter directory
and filter directory internal files, respectively. Patch 14 connects
the user inputs that are made via the sysfs files to DAMON core.
Following three patches (patches 15-17) implement sysfs directories and
files for showing the probe_hits to users, namely probes directory,
probe directory and hits files, respectively. Patch 18 introduces a new
tracepoint for showing the probe_hits via tracefs.
Patch 19 adds a selftest for the sysfs files.
Patches 20 and 21 documents the design and usage of the new feature,
respectively.
Seven additional patches (patches 22-28) for monitoring belonging memory
cgroup follow. Depending on the feedback, this part might be separated
to another series in future. Patch 22 defines the DAMON filter type for
the new attribute, namely DAMON_FILTER_TYPE_MEMCG. Patch 23 add the
support on paddr ops. Patch 24 updates the sysfs interface for setup of
the target memcg. Patch 25 move code for easy reuse of the filter
target memcg setup. Patch 26 connects the user input to the core layer.
Finally, patches 27 and 28 update the design and usage documents for the
memcg attribute monitoring support.
Discussions
===========
This allows the page properties monitoring with overhead that is low
enough to be enabled always on real world workloads. Because the
sampling time for access check is reused for data attributes check, the
upper-bounded and best-effort minimum overhead of DAMON is kept.
Because the sampling memory for access check is reused for data
attributes check, additional overhead is minimum.
Still DAMOS-based page level properties monitoring should be useful,
because it provides a deterministic page level information. When in
doubt of the sampling based information, running DAMOS-based one
together and comparing the results would be useful, for debugging and
tuning.
Plan for Dropping RFC tag
=========================
I'm considering renaming the tracepoint for exposing probe_hits
(damon_aggregated_v2).
Making changes for feedback from myself, humans and Sashiko should be
the major remaining work.
I'm currently hoping to drop the RFC tag by 7.2-rc1.
Future Works: Mid Term
========================
This version of implementation is limiting the maximum number of data
probes to four. I will try to find a way to remove the limit in future.
I personally think it should be enough for common use cases, though, and
therefore not giving high priority at the moment.
Future Works: Long Term
=======================
There are user requests for extending DAMON with detailed access
information, for example, per-CPUs/threads/read/writes monitoring. For
that, I was working [2] on extending DAMON to use page fault events as
another access check primitives, and making the infrastructure flexible
for future use of yet another access check primitive. Actually there is
another ongoing work [3] for extending DAMON with PMU events. The
motivation of the work is reducing the overhead, though.
In my work [2], I was introducing a new interface for access sampling
primitives control. Now I think this data probe interface can be used
for that, too. That is, data access becomes just one type of data
attribute. Also, pg_idle-confirmed access, page fault-confirmed access,
and PMU event-confirmed access will be different types of data
attributes.
The regions adjustment mechanism is currently working based on the
access information. That's because DAMON is designed for data access
monitoring. That is, data access information is the primary interest,
and therefore DAMON adjusts regions in a way that can best-present the
information.
Once data access becomes just one of data attributes, there is no reason
to think data access that special. There might be some users not
interested in access at all but want to know the location of memory of
specific type. Data probes interface will allow doing that. Further,
we could extend the interface to let users set any data attribute as the
'primary' attribute. Then, DAMON will split and merge regions in a way
that can best-present the 'primary' attributes.
DAMOS will also be extended, to specify targets based on not only the
data access pattern, but all user-registered data attributes. From this
stage, we may be able to call DAMON as a "Data Attributes Monitoring and
Operations eNgine".
[1] https://lore.kernel.org/20250106193401.109161-1-sj@kernel.org
[2] https://lore.kernel.org/20251208062943.68824-1-sj@kernel.org/
[3] https://lore.kernel.org/20260423004211.7037-1-akinobu.mita@gmail.com
Changes from RFC v2
- rfc v2: https://lore.kernel.org/20260512143645.113201-1-sj@kernel.org
- Optimize nr_probes calculation for probe_hits tracepoint.
- Use TRACE_EVENT_CONDITION() for probe_hits tracepoint.
- Rebase to latest mm-new.
Changes from RFC
- rfc: https://lore.kernel.org/all/20260426205222.93895-1-sj@kernel.org/
- Support memcg DAMON filter.
- Use per-probe probe_hits sysfs file.
- Use dynamic_array for probe_hits tracing.
- Fix filter matching field.
- Fix folio leaking in damon_pa_filter_pass().
- Move nr_regions of damon_aggregated_v2 tracepoint after end.
- Rename DAMON_TEST_TYPE_ANON to DAMON_FILTER_TYPE_ANON.
SeongJae Park (28):
mm/damon/core: introduce struct damon_probe
mm/damon/core: embed damon_probe objects in damon_ctx
mm/damon/core: introduce damon_filter
mm/damon/core: commit probes
mm/damon/core: introduce damon_region->probe_hits
mm/damon/core: introduce damon_ops->apply_probes
mm/damon/core: do data attributes monitoring
mm/damon/paddr: support data attributes monitoring
mm/damon/sysfs: implement probes dir
mm/damon/sysfs: implement probe dir
mm/damon/sysfs: implement filters directory
mm/damon/sysfs: implement filter dir
mm/damon/sysfs: implement filter dir files
mm/damon/sysfs: setup probes on DAMON core API parameters
mm/damon/sysfs-schemes: implement tried_regions/<r>/probes/
mm/damon/sysfs-schemes: implement probe dir
mm/damon/sysfs-schemes: implement probe/hits file
mm/damon: trace probe_hits
selftests/damon/sysfs.sh: test probes dir
Docs/mm/damon/design: document data attributes monitoring
Docs/admin-guide/mm/damon/usage: document data attributes monitoring
mm/damon/core: introduce DAMON_FILTER_TYPE_MEMCG
mm/damon/paddr: support DAMON_FILTER_TYPE_MEMCG
mm/damon/sysfs: add filters/<F>/path file
mm/damon/sysfs-schemes: move memcg_path_to_id() to sysfs-common
mm/damon/sysfs: setup damon_filter->memcg_id from path
Docs/mm/damon/design: update for memcg damon filter
Docs/admin-guide/mm/damon/usage: update for memcg damon filter
Documentation/admin-guide/mm/damon/usage.rst | 48 +-
Documentation/mm/damon/design.rst | 39 ++
include/linux/damon.h | 67 +++
include/trace/events/damon.h | 38 ++
mm/damon/core.c | 197 +++++++
mm/damon/paddr.c | 76 +++
mm/damon/sysfs-common.c | 41 ++
mm/damon/sysfs-common.h | 2 +
mm/damon/sysfs-schemes.c | 222 ++++++--
mm/damon/sysfs.c | 557 +++++++++++++++++++
tools/testing/selftests/damon/sysfs.sh | 48 ++
11 files changed, 1284 insertions(+), 51 deletions(-)
base-commit: 678b6bc7ce120b8c51d4e05fcb8eb0a92f9be3f6
--
2.47.3
^ permalink raw reply
* Re: [PATCH] driver core: Add cmdline option to force probe type
From: Greg KH @ 2026-05-14 13:50 UTC (permalink / raw)
To: Jianlin Lv
Cc: corbet, skhan, rafael, dakr, jianlv, linux-kernel, linux-doc,
driver-core
In-Reply-To: <CAFA-uR93Wf2ALpYnnU79kruv7XO=uFePqioaEXNNEfrUtRw2xQ@mail.gmail.com>
On Thu, May 14, 2026 at 09:35:08PM +0800, Jianlin Lv wrote:
> On Thu, May 14, 2026 at 6:16 PM Greg KH <gregkh@linuxfoundation.org> wrote:
> >
> > On Thu, May 14, 2026 at 05:49:55PM +0800, Jianlin Lv wrote:
> > > From: Jianlin Lv <iecedge@gmail.com>
> > >
> > > Device drivers that use asynchronous probing can cause non-deterministic
> > > device ordering and naming across reboots. A typical example is storage
> > > drivers (like sd/nvme): asynchronous probing can lead to inconsistent disk
> > > logical names after reboot. In scenarios where disk naming consistency is
> > > critical, the probe type should be set to synchronous.
> > >
> > > This patch introduces a driver_probe kernel parameter that overrides any
> > > driver's hard-coded probe type settings and allows runtime control without
> > > requiring kernel recompilation:
> > >
> > > driver_probe=PROBE_TYPE_SYNC,nvme,sd # Force specific drivers sync
> > > driver_probe=PROBE_TYPE_ASYNC,*,usb # Force all async except usb
> > > driver_probe=PROBE_TYPE_SYNC,* # Force all drivers synchronous
> > >
> > > The implementation replaces the limited driver_async_probe parameter with
> > > a more flexible interface that can force either synchronous or asynchronous
> > > probing as needed.
> > >
> > > Signed-off-by: Jianlin Lv <iecedge@gmail.com>
> > > ---
> > > .../admin-guide/kernel-parameters.txt | 27 +++++--
> > > drivers/base/dd.c | 71 ++++++++++++++-----
> > > 2 files changed, 74 insertions(+), 24 deletions(-)
> > >
> > > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> > > index 4d0f545fb3ec..b43a8bd20356 100644
> > > --- a/Documentation/admin-guide/kernel-parameters.txt
> > > +++ b/Documentation/admin-guide/kernel-parameters.txt
> > > @@ -1377,12 +1377,27 @@ Kernel parameters
> > > it becomes active and is searched during signature
> > > verification.
> > >
> > > - driver_async_probe= [KNL]
> > > - List of driver names to be probed asynchronously. *
> > > - matches with all driver names. If * is specified, the
> > > - rest of the listed driver names are those that will NOT
> > > - match the *.
> > > - Format: <driver_name1>,<driver_name2>...
> >
> > You can not remove an existing user/kernel api, sorry, that is not
> > allowed as you just broke all systems that were relying on this :(
> >
> Could you provide more suggestions on how to improve this patch?
Not really, sorry, I don't think this is a change that should be done at
all. disk naming is a long-solved issue, to think that you can fix that
by doing sync/async device probing is not understanding both the issues
involved, and how we solved it already :)
Hint, never count on block device, or any device, names to be the same
across reboots. That has NEVER been guaranteed on systems built in the
past 20+ years.
Please, just use the existing solutions, no new command line option
should ever be needed here.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH] driver core: Add cmdline option to force probe type
From: Jianlin Lv @ 2026-05-14 13:35 UTC (permalink / raw)
To: Greg KH
Cc: corbet, skhan, rafael, dakr, jianlv, linux-kernel, linux-doc,
driver-core
In-Reply-To: <2026051443-exuberant-important-534f@gregkh>
On Thu, May 14, 2026 at 6:16 PM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Thu, May 14, 2026 at 05:49:55PM +0800, Jianlin Lv wrote:
> > From: Jianlin Lv <iecedge@gmail.com>
> >
> > Device drivers that use asynchronous probing can cause non-deterministic
> > device ordering and naming across reboots. A typical example is storage
> > drivers (like sd/nvme): asynchronous probing can lead to inconsistent disk
> > logical names after reboot. In scenarios where disk naming consistency is
> > critical, the probe type should be set to synchronous.
> >
> > This patch introduces a driver_probe kernel parameter that overrides any
> > driver's hard-coded probe type settings and allows runtime control without
> > requiring kernel recompilation:
> >
> > driver_probe=PROBE_TYPE_SYNC,nvme,sd # Force specific drivers sync
> > driver_probe=PROBE_TYPE_ASYNC,*,usb # Force all async except usb
> > driver_probe=PROBE_TYPE_SYNC,* # Force all drivers synchronous
> >
> > The implementation replaces the limited driver_async_probe parameter with
> > a more flexible interface that can force either synchronous or asynchronous
> > probing as needed.
> >
> > Signed-off-by: Jianlin Lv <iecedge@gmail.com>
> > ---
> > .../admin-guide/kernel-parameters.txt | 27 +++++--
> > drivers/base/dd.c | 71 ++++++++++++++-----
> > 2 files changed, 74 insertions(+), 24 deletions(-)
> >
> > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> > index 4d0f545fb3ec..b43a8bd20356 100644
> > --- a/Documentation/admin-guide/kernel-parameters.txt
> > +++ b/Documentation/admin-guide/kernel-parameters.txt
> > @@ -1377,12 +1377,27 @@ Kernel parameters
> > it becomes active and is searched during signature
> > verification.
> >
> > - driver_async_probe= [KNL]
> > - List of driver names to be probed asynchronously. *
> > - matches with all driver names. If * is specified, the
> > - rest of the listed driver names are those that will NOT
> > - match the *.
> > - Format: <driver_name1>,<driver_name2>...
>
> You can not remove an existing user/kernel api, sorry, that is not
> allowed as you just broke all systems that were relying on this :(
>
Could you provide more suggestions on how to improve this patch?
If extend driver_async_probe to implement a 'force synchronous probe'
feature, that doesn’t really match the name driver_async_probe and
may feel ambiguous.
If add a new 'driver_probe' parameter while keeping driver_async_probe,
then their functionality would partially overlap.
Regards,
Jianlin
> thanks,
>
> greg k-h
^ permalink raw reply
* Re: [PATCH v7 2/6] mm/memory-failure: surface unhandlable kernel pages as -ENOTRECOVERABLE
From: Lance Yang @ 2026-05-14 13:28 UTC (permalink / raw)
To: leitao
Cc: linmiaohe, akpm, david, ljs, vbabka, rppt, surenb, mhocko, shuah,
nao.horiguchi, rostedt, mhiramat, mathieu.desnoyers, corbet,
skhan, liam, linux-mm, linux-kernel, linux-doc, linux-kselftest,
linux-trace-kernel, kernel-team, Lance Yang
In-Reply-To: <20260513-ecc_panic-v7-2-be2e578e61da@debian.org>
On Wed, May 13, 2026 at 08:39:33AM -0700, Breno Leitao wrote:
>get_any_page() collapses three different failure modes into a single
>-EIO return:
>
> * the put_page race in the !count_increased path;
> * the HWPoisonHandlable() rejection that bounces out of
> __get_hwpoison_page() with -EBUSY and exhausts shake_page() retries;
> * the HWPoisonHandlable() rejection that goes through the
> count_increased / put_page / shake_page retry loop.
>
>The first is transient (the page is racing with the allocator). The
>second can be either transient (a userspace folio briefly off LRU
>during migration/compaction) or stable (slab/vmalloc/page-table/
>kernel-stack pages). The third describes a stable kernel-owned page
>that the count_increased=true caller already held a reference on.
>
>Distinguish them on the return path: keep -EIO for both the put_page
>race and the -EBUSY-after-retries branch (shake_page() cannot drag a
>folio back from active migration, so we cannot prove the page is
>permanently kernel-owned from there), keep -EBUSY for the allocation
>race (unchanged), and return -ENOTRECOVERABLE only from the
>count_increased-true HWPoisonHandlable() rejection that exhausts its
>retries -- the caller's reference is structural evidence that the
>page is owned by the kernel.
>
>Extend the unhandlable-page pr_err() to fire for either errno and
>update the get_hwpoison_page() kerneldoc.
>
>memory_failure() still folds every negative return into
>MF_MSG_GET_HWPOISON via its existing "else if (res < 0)" branch, so
>this patch is a no-op for users of memory_failure() and only changes
>the errno that soft_offline_page() can propagate to its callers. A
>follow-up wires the new return code through memory_failure() and
>reports MF_MSG_KERNEL for the unrecoverable cases.
>
>Suggested-by: David Hildenbrand <david@kernel.org>
>Signed-off-by: Breno Leitao <leitao@debian.org>
>---
> mm/memory-failure.c | 18 +++++++++++++++---
> 1 file changed, 15 insertions(+), 3 deletions(-)
>
>diff --git a/mm/memory-failure.c b/mm/memory-failure.c
>index 49bcfbd04d213..bae883df3ccb2 100644
>--- a/mm/memory-failure.c
>+++ b/mm/memory-failure.c
>@@ -1408,6 +1408,15 @@ static int get_any_page(struct page *p, unsigned long flags)
> shake_page(p);
> goto try_again;
> }
>+ /*
>+ * Return -EIO rather than -ENOTRECOVERABLE: this
>+ * branch is also reached for pages that are merely
>+ * off-LRU transiently (e.g. a folio in the middle
>+ * of migration or compaction), which shake_page()
>+ * cannot drag back. The caller cannot prove the
>+ * page is permanently kernel-owned from here, so
>+ * keep it on the recoverable errno.
>+ */
> ret = -EIO;
> goto out;
> }
>@@ -1427,10 +1436,10 @@ static int get_any_page(struct page *p, unsigned long flags)
> goto try_again;
> }
> put_page(p);
>- ret = -EIO;
>+ ret = -ENOTRECOVERABLE;
> }
> out:
>- if (ret == -EIO)
>+ if (ret == -EIO || ret == -ENOTRECOVERABLE)
> pr_err("%#lx: unhandlable page.\n", page_to_pfn(p));
>
> return ret;
>@@ -1487,7 +1496,10 @@ static int __get_unpoison_page(struct page *page)
> * -EIO for pages on which we can not handle memory errors,
> * -EBUSY when get_hwpoison_page() has raced with page lifecycle
> * operations like allocation and free,
>- * -EHWPOISON when the page is hwpoisoned and taken off from buddy.
>+ * -EHWPOISON when the page is hwpoisoned and taken off from buddy,
>+ * -ENOTRECOVERABLE for stable kernel-owned pages the handler
>+ * cannot recover (PG_reserved, slab, vmalloc, page tables,
>+ * kernel stacks, and similar non-LRU/non-buddy pages).
Did you test this patch series? I don't see how we ever get to
-ENOTRECOVERABLE there ...
Even with MF_COUNT_INCREASED, the first pass does:
if (flags & MF_COUNT_INCREASED)
count_increased = true;
[...]
if (PageHuge(p) || HWPoisonHandlable(p, flags)) {
ret = 1;
} else {
if (pass++ < GET_PAGE_MAX_RETRY_NUM) { <-
put_page(p);
shake_page(p);
count_increased = false;
goto try_again; <-
}
put_page(p);
ret = -ENOTRECOVERABLE;
}
Then we come back with count_increased=false:
try_again:
if (!count_increased) {
ret = __get_hwpoison_page(p, flags); <-
if (!ret) {
[...]
} else if (ret == -EBUSY) { <-
[...]
ret = -EIO;
goto out; <-
}
}
For slab/vmalloc/page-table pages, __get_hwpoison_page() returns -EBUSY:
if (!HWPoisonHandlable(&folio->page, flags))
return -EBUSY;
so they still seem to end up as -EIO ... Am I missing something?
> */
> static int get_hwpoison_page(struct page *p, unsigned long flags)
> {
>
>--
>2.53.0-Meta
>
>
^ permalink raw reply
* Re: [PATCH v3 2/3] Documentation: security-bugs: explain what is and is not a security bug
From: Willy Tarreau @ 2026-05-14 13:13 UTC (permalink / raw)
To: Jonathan Corbet
Cc: Greg KH, Leon Romanovsky, skhan, security, workflows, linux-doc,
linux-kernel
In-Reply-To: <87wlx6uqob.fsf@trenco.lwn.net>
On Thu, May 14, 2026 at 06:22:12AM -0600, Jonathan Corbet wrote:
> Willy Tarreau <w@1wt.eu> writes:
>
> >> (While I was there, I noticed that threat-model.rst has no SPDX line;
> >> what's your preference there?)
> >
> > I didn't notice any was needed, I tried to get inspiration from other
> > files for the format (I'm still not familiar with the rst format
> > though this time I could successfully install the tools).
>
> In theory every file in the kernel tree is supposed to have one; many
> documentation files lag a bit behind on that front, but we try...
OK thanks for the background.
> > Same for
> > the label at the top BTW, I just did what I found somewhere else,
> > probably security-bugs.rst which is similar (no SPDX line and has a
> > label). So regarding SPDX, I do not have any preference. If one is
> > needed, let's pick what's used by default, I do not care, as long
> > as it allows the doc to be published.
>
> The top-of-file label got started somewhere and has been cargo-culted
> extensively since then; it has proved hard to eradicate.
I'm not surprised, everyone likely does like me: look at another file
to see what it should look like, and does it again. Apparently in
security-bugs it was added 10 years ago by this:
609d99a3b72e3 ("Documentation/HOWTO: add cross-references to other documents")
> As for SPDX, the most common is the basic:
>
> .. SPDX-License-Identifier: GPL-2.0
This works for me for the new file. For existing security-bugs, why
not do the same at the same time ? Before SPDX tags it has been covered
by GPL-2.0 as well via the COPYING file, and further contributions did
not change its license. And in the worst case a total of 10 people
touched the 3 names of that file over its Git history, I doubt there
would be too much resistance against an update.
Willy
^ permalink raw reply
* RE: [PATCH v10 3/6] iio: adc: ad4691: add triggered buffer support
From: Sabau, Radu bogdan @ 2026-05-14 12:43 UTC (permalink / raw)
To: Jonathan Cameron, Radu Sabau via B4 Relay
Cc: Lars-Peter Clausen, Hennerich, Michael, David Lechner, Sa, Nuno,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Uwe Kleine-König, Liam Girdwood, Mark Brown, Linus Walleij,
Bartosz Golaszewski, Philipp Zabel, Jonathan Corbet, Shuah Khan,
linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-pwm@vger.kernel.org,
linux-gpio@vger.kernel.org, linux-doc@vger.kernel.org
In-Reply-To: <20260512164514.38bbfd4c@jic23-huawei>
> -----Original Message-----
> From: Jonathan Cameron <jic23@kernel.org>
> Sent: Tuesday, May 12, 2026 6:45 PM
> To: Radu Sabau via B4 Relay <devnull+radu.sabau.
...
> > The CNV Burst Mode sampling frequency (PWM period) is exposed as a
> > buffer-level attribute via IIO_DEVICE_ATTR.
> >
> > Signed-off-by: Radu Sabau <radu.sabau@analog.com>
>
> Sashiko pointed out you have a buffer that is big endian but
> chan_spec doesn't reflect that. That should have generated obvious
> garbage output (unless you are actually testing on a be machine!)
>
I thought I had IIO_BE in chan_spec,, my bad. I either forgot to copy the last
kernel image upon testing (though I don't know why I would remove that line)
or I did something wrong upon rebasing on the patches.
> Various other things came up, some of which I thought were in previous
> reviews - but maybe I'm confusing drivers.
>
> Thanks
>
> Jonathan
>
> > @@ -204,7 +230,14 @@ static const struct ad4691_chip_info
> ad4694_chip_info = {
> > struct ad4691_state {
> > const struct ad4691_chip_info *info;
> > struct regmap *regmap;
> > + struct spi_device *spi;
...
> > + /*
> > + * Append a 4-byte state-reset transfer [addr_hi, addr_lo,
> > + * STATE_RESET_ALL, OSC_EN=1]. CS is asserted throughout, so
> > + * ADDR_DESCENDING writes byte[3]=1 to OSC_EN_REG (0x180) as a
> > + * deliberate side-write, keeping the oscillator enabled.
> > + */
> > + put_unaligned_be16(AD4691_STATE_RESET_REG, st->scan_tx_reset);
> > + st->scan_tx_reset[2] = AD4691_STATE_RESET_ALL;
> > + st->scan_tx_reset[3] = 1;
> > + st->scan_xfers[2 * k].tx_buf = st->scan_tx_reset;
> > + st->scan_xfers[2 * k].len = sizeof(st->scan_tx_reset);
> > + st->scan_xfers[2 * k].cs_change = 1;
>
> Our old friend - cs_change = 1 is very rarely the right thing to do on a
> final message. I thought this came up in an earlier version.
>
I thought I had this removed, it must have been lost.
> > + spi_message_add_tail(&st->scan_xfers[2 * k], &st->scan_msg);
> > +
> > + ret = spi_optimize_message(st->spi, &st->scan_msg);
> > + if (ret)
> > + return ret;
> > +
> > + ret = regmap_write(st->regmap, AD4691_STD_SEQ_CONFIG,
> > + bitmap_read(indio_dev->active_scan_mask, 0,
> > + iio_get_masklength(indio_dev)));
...
> > +static irqreturn_t ad4691_trigger_handler(int irq, void *p)
> > +{
> > + struct iio_poll_func *pf = p;
> > + struct iio_dev *indio_dev = pf->indio_dev;
> > + struct ad4691_state *st = iio_priv(indio_dev);
> > +
> > + ad4691_read_scan(indio_dev, pf->timestamp);
> > + if (!st->manual_mode)
> > + enable_irq(st->irq);
>
> Maybe it was a different driver but I thought I commented on this before.
> There are a bunch of races if you reenable this here - needs to be
> in the trigger reenable callback.
> (Sashiko is pointing this out as well with more detail on what those
> races are) The short story is that you can race and have a trigger between
> the enable and the notify_done which will be dropped on the floor meaning
> we never get in here again - IIRC there is (rather convoluted) code to handle
> that
> corner case in via the reenable callback and a work item.
>
I also thought I had this covered, it appears it is not...
> > + iio_trigger_notify_done(indio_dev->trig);
> > + return IRQ_HANDLED;
> > +}
> > +
> > static const struct iio_info ad4691_info = {
> > .read_raw = &ad4691_read_raw,
> > .write_raw = &ad4691_write_raw,
> > .read_avail = &ad4691_read_avail,
> > .debugfs_reg_access = &ad4691_reg_access,
> > + .validate_trigger = iio_validate_own_trigger,
>
...
> > static int ad4691_probe(struct spi_device *spi)
> > {
> > struct device *dev = &spi->dev;
> > @@ -663,6 +1200,7 @@ static int ad4691_probe(struct spi_device *spi)
> > return -ENOMEM;
> >
> > st = iio_priv(indio_dev);
> > + st->spi = spi;
> > st->info = spi_get_device_match_data(spi);
> > if (!st->info)
> > return -ENODEV;
> > @@ -692,8 +1230,9 @@ static int ad4691_probe(struct spi_device *spi)
> > indio_dev->info = &ad4691_info;
> > indio_dev->modes = INDIO_DIRECT_MODE;
> >
> > - indio_dev->channels = st->info->sw_info->channels;
> > - indio_dev->num_channels = st->info->sw_info->num_channels;
>
> You've lost me here. Where are these now set?
>
At this point I am starting to think that whatever I have sent is different from
whatever I tested. It seems like changes I have running on the kernel image
do not appear here. I am pretty sure I have done something wrong while
rebasing, I am very sorry for that. I'll try and send a better/cleaner version
next time.
> > + ret = ad4691_setup_triggered_buffer(indio_dev, st);
> > + if (ret)
> > + return ret;
> >
> > return devm_iio_device_register(dev, indio_dev);
> > }
> >
^ permalink raw reply
* Re: [PATCH v4] docs: reporting-issues: replace "these advices" with "all of this advice"
From: WangYuli @ 2026-05-14 12:30 UTC (permalink / raw)
To: Jonathan Corbet, Chen-Shi-Hong, linux; +Cc: skhan, linux-doc, linux-kernel
In-Reply-To: <87zf22uquc.fsf@trenco.lwn.net>
Hi jon,
On 2026/5/14 20:18, Jonathan Corbet wrote:
> Please, no. If you start churning the code in that way you will
> certainly get pushback. Typo fixes are a fine way to learn the process,
> but I really hope that contributors will move on quickly to more
> substantial work.
You're right. I take back my suggestion.
Thanks,
---
WangYuli
^ permalink raw reply
* Re: [RFC net-next 0/4] devlink: Add boot-time defaults
From: Mark Bloch @ 2026-05-14 12:34 UTC (permalink / raw)
To: Jiri Pirko
Cc: Parav Pandit, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
Andrew Lunn, David S. Miller, Jonathan Corbet, Shuah Khan,
Simon Horman, Saeed Mahameed, Leon Romanovsky, Tariq Toukan,
Andrew Morton, Borislav Petkov (AMD), Randy Dunlap, Dave Hansen,
Christian Brauner, Petr Mladek, Peter Zijlstra (Intel),
Thomas Gleixner, Pawan Gupta, Dapeng Mi, Kees Cook, Marco Elver,
Eric Biggers, NBU-Contact-Li Rongqing (EXTERNAL),
Paul E. McKenney, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
linux-rdma@vger.kernel.org
In-Reply-To: <agRcYDkjsQuS7ArD@FV6GYCPJ69>
On 13/05/2026 14:11, Jiri Pirko wrote:
> Wed, May 13, 2026 at 07:53:05AM CEST, mbloch@nvidia.com wrote:
>>
>>
>> On 12/05/2026 21:35, Jiri Pirko wrote:
>>> Tue, May 12, 2026 at 05:25:21PM CEST, parav@nvidia.com wrote:
>>>>
>>>>
>>>>> From: Jiri Pirko <jiri@resnulli.us>
>>>>> Sent: 12 May 2026 07:37 PM
>>>>>
>>>>> Tue, May 12, 2026 at 03:48:32PM CEST, parav@nvidia.com wrote:
>>>>>>
>>>>>>> From: Jiri Pirko <jiri@resnulli.us>
>>>>>>> Sent: 12 May 2026 02:16 PM
>>>>>>>
>>>>>>> Mon, May 11, 2026 at 08:21:37PM +0200, parav@nvidia.com wrote:
>>>>>>>>
>>>>>>>>> From: Mark Bloch <mbloch@nvidia.com>
>>>>>>>>> Sent: 10 May 2026 06:02 PM
>>>>>>>>>
>>>>>>>>
>>>>>>>> [..]
>>>>>>>>
>>>>>>>>>> I look at it from the perspective that from some CX generation,
>>>>>>>>>> switchdev mode should be default. So that is a device-based decision.
>>>>>>>>>> I believe as such it can optionally be permanenty configured (nv config)
>>>>>>>>>> on older device. Why not?
>>>>>>>>>
>>>>>>>> Because sometimes switchdev_inactive is needed and sometimes not.
>>>>>>>> Such knob is not device decision.
>>>>>>>
>>>>>>> That is what I would call corner case. In that, user can use userspace
>>>>>>> configuration to change the mode in runtime.
>>>>>>>
>>>>>> Corner vs common depends on users one talks to. :)
>>>>>> If fw has switchdev(active) as default, and then
>>>>>> And user needs to run switchdev_inactive, it will actually break their switching applications.
>>>>>
>>>>> Can you describe the actutal breakage please?
>>>>>
>>>> Driver default was switchdev so all the traffic is forwarded to the switch,
>>>> and user didn't have chance to setup the fdb rules.
>>>> So packets are dropped but user didn't expect the traffic to be forwarded.
>>>
>>> User may switch mode to switchdev_inactive early on, before any of the
>>> representors are created. What's the issue then?
>>
>> That is the ordering problem I am trying to solve.
>>
>> On a DPU, the host PF cannot finish loading until the ECPF moves the eswitch to
>> switchdev/switchdev_inactive. So we need to do that transition during ECPF
>> driver init, as early as possible. Waiting for userspace means the host PF stays
>> blocked until userspace is up and has the right logic.
>>
>> That is not always true in practice, the driver may be built in, loaded from an
>> initramfs, or the initramfs may simply not contain the devlink policy we need.
>>
>> Also, after talking with Parav, my understanding is that we need to support both
>> switchdev and switchdev_inactive, since different customers want different boot
>> behavior. Once we do the transition, the host PF can load and may start sending
>> packets. At that point the initial mode already matters: in switchdev_inactive
>> packets are dropped until userspace programs the pipeline; in switchdev they may
>> reach the FDB before the pipeline is ready.
>>
>> So I do not think an early userspace transition is equivalent here. The initial
>> mode needs to be known by the kernel before userspace runs, which is why I am
>> proposing the devlink= command line default.
>
> Okay fair enough. Could you please at least make sure this is mode only
> config and noone would ever think about abusing this for any other
> configuration? Perhaps call it "devlink_eswitch_mode=" to remove
> the "devlink=" namespace flexibility?
Sure, something along these lines:
devlink_eswitch_mode=[*]:switchdev
devlink_eswitch_mode=[pci/0000:08:00.0,pci/0000:09:00.1]:switchdev_inactive
The proper (not RFC) series will have 3 patches:
- devlink: add the command-line default eswitch mode handling
- mlx5: cleanup/prep patch
- mlx5: use the devlink API to apply the early eswitch mode
Since the mlx5 changes are part of the series, I suspect this will need to
go through Tariq. The patches are ready, but are currently in
our submission queue.
Mark
^ permalink raw reply
* Re: [PATCH v3 2/3] Documentation: security-bugs: explain what is and is not a security bug
From: Jonathan Corbet @ 2026-05-14 12:22 UTC (permalink / raw)
To: Willy Tarreau
Cc: Greg KH, Leon Romanovsky, skhan, security, workflows, linux-doc,
linux-kernel
In-Reply-To: <agVQWKR63Nqs8rp-@1wt.eu>
Willy Tarreau <w@1wt.eu> writes:
>> (While I was there, I noticed that threat-model.rst has no SPDX line;
>> what's your preference there?)
>
> I didn't notice any was needed, I tried to get inspiration from other
> files for the format (I'm still not familiar with the rst format
> though this time I could successfully install the tools).
In theory every file in the kernel tree is supposed to have one; many
documentation files lag a bit behind on that front, but we try...
> Same for
> the label at the top BTW, I just did what I found somewhere else,
> probably security-bugs.rst which is similar (no SPDX line and has a
> label). So regarding SPDX, I do not have any preference. If one is
> needed, let's pick what's used by default, I do not care, as long
> as it allows the doc to be published.
The top-of-file label got started somewhere and has been cargo-culted
extensively since then; it has proved hard to eradicate.
As for SPDX, the most common is the basic:
.. SPDX-License-Identifier: GPL-2.0
Thanks,
jon
^ permalink raw reply
* Re: [PATCH v4] docs: reporting-issues: replace "these advices" with "all of this advice"
From: Jonathan Corbet @ 2026-05-14 12:18 UTC (permalink / raw)
To: WangYuli, Chen-Shi-Hong, linux; +Cc: skhan, linux-doc, linux-kernel
In-Reply-To: <e2cced37-58ea-4678-a586-97f9a6db7e9d@aosc.io>
WangYuli <wangyuli@aosc.io> writes:
> I searched the kernel tree for the misspelling "advices" (the word
> "advice" is uncountable) and found the following occurrences:
>
> "
>
> >rg-i "advices"
>
> tools/perf/trace/beauty/mmap.c
> 68: static DEFINE_STRARRAY(madvise_advices, "MADV_");
> 70: if (behavior < strarray__madvise_advices.nr_entries &&
> strarray__madvise_advices.entries[behavior] != NULL)
> 71: return scnprintf(bf, size, "MADV_%s",
> strarray__madvise_advices.entries[behavior]);
Please, no. If you start churning the code in that way you will
certainly get pushback. Typo fixes are a fine way to learn the process,
but I really hope that contributors will move on quickly to more
substantial work.
Thanks,
jon
^ permalink raw reply
* Re: [PATCH v2] Documentation: iio: fix typo in triggered-buffers example
From: Joshua Crofts @ 2026-05-14 12:13 UTC (permalink / raw)
To: Stepan Ionichev
Cc: corbet, jic23, dlechner, nuno.sa, andy, skhan, gregkh, hcazarim,
linux-doc, linux-iio, linux-kernel
In-Reply-To: <20260514085157.20327-1-sozdayvek@gmail.com>
On Thu, 14 May 2026 at 10:53, Stepan Ionichev <sozdayvek@gmail.com> wrote:
>
> In the "IIO triggered buffer setup" example, iio_triggered_buffer_setup()
> is called with "sensor_iio_polfunc" (single 'l') while the function is
> defined and later referenced as "sensor_iio_pollfunc" (double 'l'). Fix
> the misspelling so the example is consistent.
>
> Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com>
> ---
Looks fine to me.
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
--
Kind regards
CJD
^ permalink raw reply
* Re: (subset) [PATCH v2] Documentation: leds: leds-class: Document keyboard backlight LED class naming
From: Lee Jones @ 2026-05-14 12:04 UTC (permalink / raw)
To: Lee Jones, Pavel Machek, Jonathan Corbet, Shuah Khan,
Hans de Goede
Cc: Rishit Bansal, Carlos Ferreira, Edip Hazuri, Mustafa Ekşi,
Xavier Bestel, linux-doc, linux-leds, Kate Hsuan
In-Reply-To: <20260504145434.12746-1-johannes.goede@oss.qualcomm.com>
On Mon, 04 May 2026 16:54:34 +0200, Hans de Goede wrote:
> Document the existing practice of always using 'kbd_backlight' for
> the function part of LED class device names for LED class devices which
> control single-zone keyboard backlights.
>
> Also extend this existing practice with a new naming scheme for keyboards
> with zoned backlight control. There are several drivers in the works (see
> the Link:tags below) which offer backlight control for keyboards where
> the keyboard backlight is divided in a limited number of zones, e.g.
> "main", "cursor" and "numpad" zones.
>
> [...]
Applied, thanks!
[1/1] Documentation: leds: leds-class: Document keyboard backlight LED class naming
commit: cd628658d428e8a5074b9608771be45d86770bb6
--
Lee Jones [李琼斯]
^ permalink raw reply
* Re: [PATCH v3 1/2] dt-bindings: trivial-devices: Add Murata D1U74T PSU
From: Krzysztof Kozlowski @ 2026-05-14 11:43 UTC (permalink / raw)
To: Abdurrahman Hussain
Cc: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jonathan Corbet, Shuah Khan, linux-hwmon, devicetree,
linux-kernel, linux-doc
In-Reply-To: <20260513-d1u74t-v3-1-27bcd6852c45@nexthop.ai>
On Wed, May 13, 2026 at 03:33:02AM -0700, Abdurrahman Hussain wrote:
> The Murata D1U74T-W is a PMBus-compliant AC/DC power supply unit. The
> binding only declares the compatible string and i2c reg, with no
Describe the hardware, not binding. What does the hardware have?
Supplies? Pins? Clocks? Interrupts?
> additional properties (no regulators, no supplies), so add it to
> trivial-devices.yaml rather than carrying a standalone binding file.
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v11 4/4] kunit: Add documentation for warning backtrace suppression API
From: Albert Esteve @ 2026-05-14 11:06 UTC (permalink / raw)
To: Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti
Cc: linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-riscv, linux-doc, peterz, Guenter Roeck,
Linux Kernel Functional Testing, Alessandro Carminati,
Albert Esteve, Dan Carpenter, Kees Cook
In-Reply-To: <20260514-kunit_add_support-v11-0-b36a530a6d8f@redhat.com>
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>
Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
Reviewed-by: David Gow <david@davidgow.net>
Signed-off-by: Albert Esteve <aesteve@redhat.com>
---
Documentation/dev-tools/kunit/usage.rst | 46 ++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/Documentation/dev-tools/kunit/usage.rst b/Documentation/dev-tools/kunit/usage.rst
index ebd06f5ea4550..1c78dfff94e8a 100644
--- a/Documentation/dev-tools/kunit/usage.rst
+++ b/Documentation/dev-tools/kunit/usage.rst
@@ -157,6 +157,50 @@ 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 a 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.
+
+Backtraces can be suppressed with **task-scoped suppression**: while
+suppression is active on the current task, the backtrace and stack dump from
+``WARN*()``, ``WARN_ON*()``, and related macros on that task are suppressed.
+Two API forms are available.
+
+- Scoped suppression is the simplest form. Wrap the code that triggers
+ warnings in a ``kunit_warning_suppress()`` block:
+
+.. code-block:: c
+
+ static void some_test(struct kunit *test)
+ {
+ kunit_warning_suppress(test) {
+ trigger_backtrace();
+ KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1);
+ }
+ }
+
+.. note::
+ The warning count must be checked inside the block; the suppression handle
+ is not accessible after the block exits.
+
+- Direct functions return an explicit handle pointer. Use them when the handle
+ needs to be retained or passed across helper functions:
+
+.. code-block:: c
+
+ static void some_test(struct kunit *test)
+ {
+ struct kunit_suppressed_warning *w;
+
+ w = kunit_start_suppress_warning(test);
+ trigger_backtrace();
+ kunit_end_suppress_warning(test, w);
+
+ KUNIT_EXPECT_EQ(test, kunit_suppressed_warning_count(w), 1);
+ }
Test Suites
~~~~~~~~~~~
@@ -1211,4 +1255,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
+ }
--
2.53.0
^ permalink raw reply related
* [PATCH v11 3/4] drm: Suppress intentional warning backtraces in scaling unit tests
From: Albert Esteve @ 2026-05-14 11:06 UTC (permalink / raw)
To: Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti
Cc: linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-riscv, linux-doc, peterz, Guenter Roeck,
Linux Kernel Functional Testing, Maíra Canal,
Alessandro Carminati, Albert Esteve, Dan Carpenter, Simona Vetter
In-Reply-To: <20260514-kunit_add_support-v11-0-b36a530a6d8f@redhat.com>
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. Additionally, the
suppression API allows to actually ensure a warning was triggered,
without parsing any kernel logs and keeping them clean.
The suppression check requires CONFIG_BUG enabled.
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>
Acked-by: David Gow <david@davidgow.net>
Signed-off-by: Albert Esteve <aesteve@redhat.com>
---
drivers/gpu/drm/tests/drm_rect_test.c | 46 ++++++++++++++++++++++++++++++-----
1 file changed, 40 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/tests/drm_rect_test.c b/drivers/gpu/drm/tests/drm_rect_test.c
index 17e1f34b76101..3402f993d7d33 100644
--- a/drivers/gpu/drm/tests/drm_rect_test.c
+++ b/drivers/gpu/drm/tests/drm_rect_test.c
@@ -10,6 +10,7 @@
#include <drm/drm_rect.h>
#include <drm/drm_mode.h>
+#include <linux/limits.h>
#include <linux/string_helpers.h>
#include <linux/errno.h>
@@ -407,10 +408,27 @@ KUNIT_ARRAY_PARAM(drm_rect_scale, drm_rect_scale_cases, drm_rect_scale_case_desc
static void drm_test_rect_calc_hscale(struct kunit *test)
{
const struct drm_rect_scale_case *params = test->param_value;
- int scaling_factor;
+ int expected_warnings = params->expected_scaling_factor == -EINVAL;
+ int scaling_factor = INT_MIN;
- scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst,
- params->min_range, params->max_range);
+ /*
+ * Without CONFIG_BUG, WARN_ON() is a no-op and the suppressed warning
+ * count stays zero, failing the assertion.
+ */
+ if (expected_warnings && !IS_ENABLED(CONFIG_BUG))
+ kunit_skip(test, "requires CONFIG_BUG");
+
+ /*
+ * drm_rect_calc_hscale() generates a warning backtrace whenever bad
+ * parameters are passed to it. This affects unit tests with -EINVAL
+ * error code in expected_scaling_factor.
+ */
+ kunit_warning_suppress(test) {
+ scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst,
+ params->min_range,
+ params->max_range);
+ KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, expected_warnings);
+ }
KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor);
}
@@ -418,10 +436,26 @@ static void drm_test_rect_calc_hscale(struct kunit *test)
static void drm_test_rect_calc_vscale(struct kunit *test)
{
const struct drm_rect_scale_case *params = test->param_value;
- int scaling_factor;
+ int expected_warnings = params->expected_scaling_factor == -EINVAL;
+ int scaling_factor = INT_MIN;
- scaling_factor = drm_rect_calc_vscale(¶ms->src, ¶ms->dst,
- params->min_range, params->max_range);
+ /*
+ * Without CONFIG_BUG, WARN_ON() is a no-op and the suppressed warning
+ * count stays zero, failing the assertion.
+ */
+ if (expected_warnings && !IS_ENABLED(CONFIG_BUG))
+ kunit_skip(test, "requires CONFIG_BUG");
+
+ /*
+ * drm_rect_calc_vscale() generates a warning backtrace whenever bad
+ * parameters are passed to it. This affects unit tests with -EINVAL
+ * error code in expected_scaling_factor.
+ */
+ kunit_warning_suppress(test) {
+ scaling_factor = drm_rect_calc_vscale(¶ms->src, ¶ms->dst,
+ params->min_range, params->max_range);
+ KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, expected_warnings);
+ }
KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor);
}
--
2.53.0
^ permalink raw reply related
* [PATCH v11 2/4] kunit: Add backtrace suppression self-tests
From: Albert Esteve @ 2026-05-14 11:06 UTC (permalink / raw)
To: Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti
Cc: linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-riscv, linux-doc, peterz, Guenter Roeck,
Linux Kernel Functional Testing, Alessandro Carminati,
Albert Esteve, Dan Carpenter, Kees Cook
In-Reply-To: <20260514-kunit_add_support-v11-0-b36a530a6d8f@redhat.com>
From: Guenter Roeck <linux@roeck-us.net>
Add unit tests to verify that warning backtrace suppression works.
Tests cover both API forms:
- Scoped: kunit_warning_suppress() with in-block count verification
and post-block inactivity check.
- Direct functions: kunit_start/end_suppress_warning() with
sequential independent suppression blocks and per-block counts.
Furthermore, tests verify incremental warning counting, that
kunit_has_active_suppress_warning() transitions correctly around
suppression boundaries, and that suppression active in the test
kthread does not leak to a separate kthread.
If backtrace suppression does _not_ work, the unit tests will likely
trigger unsuppressed backtraces, which should actually help to get
the affected architectures / platforms fixed.
Tested-by: Linux Kernel Functional Testing <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>
Reviewed-by: David Gow <david@davidgow.net>
Signed-off-by: Albert Esteve <aesteve@redhat.com>
---
lib/kunit/Makefile | 1 +
lib/kunit/backtrace-suppression-test.c | 198 +++++++++++++++++++++++++++++++++
2 files changed, 199 insertions(+)
diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile
index 4592f9d0aa8dd..2e8a6b71a2ab0 100644
--- a/lib/kunit/Makefile
+++ b/lib/kunit/Makefile
@@ -22,6 +22,7 @@ obj-$(if $(CONFIG_KUNIT),y) += hooks.o
obj-$(CONFIG_KUNIT_TEST) += kunit-test.o
obj-$(CONFIG_KUNIT_TEST) += platform-test.o
+obj-$(CONFIG_KUNIT_TEST) += backtrace-suppression-test.o
# 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..7a2a59c6a780d
--- /dev/null
+++ b/lib/kunit/backtrace-suppression-test.c
@@ -0,0 +1,198 @@
+// 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>
+#include <linux/completion.h>
+#include <linux/kthread.h>
+
+static void backtrace_suppression_test_warn_direct(struct kunit *test)
+{
+ if (!IS_ENABLED(CONFIG_BUG))
+ kunit_skip(test, "requires CONFIG_BUG");
+
+ kunit_warning_suppress(test) {
+ WARN(1, "This backtrace should be suppressed");
+ /*
+ * Count must be checked inside the scope; the handle
+ * is not accessible after the block exits.
+ */
+ KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1);
+ }
+ KUNIT_EXPECT_FALSE(test, kunit_has_active_suppress_warning());
+}
+
+static noinline void trigger_backtrace_warn(void)
+{
+ WARN(1, "This backtrace should be suppressed");
+}
+
+static void backtrace_suppression_test_warn_indirect(struct kunit *test)
+{
+ if (!IS_ENABLED(CONFIG_BUG))
+ kunit_skip(test, "requires CONFIG_BUG");
+
+ kunit_warning_suppress(test) {
+ trigger_backtrace_warn();
+ KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1);
+ }
+}
+
+static void backtrace_suppression_test_warn_multi(struct kunit *test)
+{
+ if (!IS_ENABLED(CONFIG_BUG))
+ kunit_skip(test, "requires CONFIG_BUG");
+
+ kunit_warning_suppress(test) {
+ WARN(1, "This backtrace should be suppressed");
+ trigger_backtrace_warn();
+ KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 2);
+ }
+}
+
+static void backtrace_suppression_test_warn_on_direct(struct kunit *test)
+{
+ if (!IS_ENABLED(CONFIG_BUG))
+ kunit_skip(test, "requires CONFIG_BUG");
+ if (!IS_ENABLED(CONFIG_DEBUG_BUGVERBOSE) && !IS_ENABLED(CONFIG_KALLSYMS))
+ kunit_skip(test, "requires CONFIG_DEBUG_BUGVERBOSE or CONFIG_KALLSYMS");
+
+ kunit_warning_suppress(test) {
+ WARN_ON(1);
+ KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1);
+ }
+}
+
+static noinline void trigger_backtrace_warn_on(void)
+{
+ WARN_ON(1);
+}
+
+static void backtrace_suppression_test_warn_on_indirect(struct kunit *test)
+{
+ if (!IS_ENABLED(CONFIG_BUG))
+ kunit_skip(test, "requires CONFIG_BUG");
+ if (!IS_ENABLED(CONFIG_DEBUG_BUGVERBOSE))
+ kunit_skip(test, "requires CONFIG_DEBUG_BUGVERBOSE");
+
+ kunit_warning_suppress(test) {
+ trigger_backtrace_warn_on();
+ KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1);
+ }
+}
+
+static void backtrace_suppression_test_count(struct kunit *test)
+{
+ if (!IS_ENABLED(CONFIG_BUG))
+ kunit_skip(test, "requires CONFIG_BUG");
+
+ kunit_warning_suppress(test) {
+ KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 0);
+
+ WARN(1, "suppressed");
+ KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1);
+
+ WARN(1, "suppressed again");
+ KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 2);
+ }
+}
+
+static void backtrace_suppression_test_active_state(struct kunit *test)
+{
+ KUNIT_EXPECT_FALSE(test, kunit_has_active_suppress_warning());
+
+ kunit_warning_suppress(test) {
+ KUNIT_EXPECT_TRUE(test, kunit_has_active_suppress_warning());
+ }
+
+ KUNIT_EXPECT_FALSE(test, kunit_has_active_suppress_warning());
+
+ kunit_warning_suppress(test) {
+ KUNIT_EXPECT_TRUE(test, kunit_has_active_suppress_warning());
+ }
+
+ KUNIT_EXPECT_FALSE(test, kunit_has_active_suppress_warning());
+}
+
+static void backtrace_suppression_test_multi_scope(struct kunit *test)
+{
+ struct kunit_suppressed_warning *sw1, *sw2;
+
+ if (!IS_ENABLED(CONFIG_BUG))
+ kunit_skip(test, "requires CONFIG_BUG");
+ if (!IS_ENABLED(CONFIG_DEBUG_BUGVERBOSE))
+ kunit_skip(test, "requires CONFIG_DEBUG_BUGVERBOSE");
+
+ sw1 = kunit_start_suppress_warning(test);
+ trigger_backtrace_warn_on();
+ WARN(1, "suppressed by sw1");
+ kunit_end_suppress_warning(test, sw1);
+
+ sw2 = kunit_start_suppress_warning(test);
+ WARN(1, "suppressed by sw2");
+ kunit_end_suppress_warning(test, sw2);
+
+ KUNIT_EXPECT_EQ(test, kunit_suppressed_warning_count(sw1), 2);
+ KUNIT_EXPECT_EQ(test, kunit_suppressed_warning_count(sw2), 1);
+}
+
+struct cross_kthread_data {
+ bool was_active;
+ struct completion done;
+};
+
+static int cross_kthread_fn(void *data)
+{
+ struct cross_kthread_data *d = data;
+
+ d->was_active = kunit_has_active_suppress_warning();
+ complete(&d->done);
+ while (!kthread_should_stop())
+ schedule();
+ return 0;
+}
+
+static void backtrace_suppression_test_cross_kthread(struct kunit *test)
+{
+ struct cross_kthread_data data;
+ struct task_struct *task;
+
+ data.was_active = false;
+ init_completion(&data.done);
+
+ kunit_warning_suppress(test) {
+ task = kthread_run(cross_kthread_fn, &data, "kunit-cross-test");
+ KUNIT_ASSERT_FALSE(test, IS_ERR(task));
+ wait_for_completion(&data.done);
+ kthread_stop(task);
+ }
+
+ KUNIT_EXPECT_FALSE(test, data.was_active);
+}
+
+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),
+ KUNIT_CASE(backtrace_suppression_test_count),
+ KUNIT_CASE(backtrace_suppression_test_active_state),
+ KUNIT_CASE(backtrace_suppression_test_multi_scope),
+ KUNIT_CASE(backtrace_suppression_test_cross_kthread),
+ {}
+};
+
+static struct kunit_suite backtrace_suppression_test_suite = {
+ .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");
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v7 4/6] mm/memory-failure: short-circuit PG_reserved before get_hwpoison_page()
From: Breno Leitao @ 2026-05-14 11:06 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: Miaohe Lin, Andrew Morton, Lorenzo Stoakes, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Shuah Khan,
Naoya Horiguchi, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Jonathan Corbet, Shuah Khan, Liam R. Howlett,
linux-mm, linux-kernel, linux-doc, linux-kselftest,
linux-trace-kernel, kernel-team, Lance Yang
In-Reply-To: <511dc52e-f2af-43c8-a9cf-19321b091dbe@kernel.org>
On Wed, May 13, 2026 at 09:49:28PM +0200, David Hildenbrand (Arm) wrote:
> On 5/13/26 17:39, Breno Leitao wrote:
> > The previous patch already classifies PG_reserved pages as
> > MF_MSG_KERNEL through the long path: get_hwpoison_page() calls
> > __get_hwpoison_page() which fails HWPoisonHandlable(), get_any_page()
> > exhausts its shake_page() retry budget, and the resulting
> > -ENOTRECOVERABLE is mapped to MF_MSG_KERNEL by the switch. The
> > outcome is correct but the work in between is wasted: shake_page()
> > cannot turn a reserved page into a handlable one.
>
> If really required, can we just move the check right there, into get_any_page() etc?
Sure, we might move it to get_any_page(). I took this current approach
based on the following facts:
1) Lance suggested it, and it sounded a good idea.
https://lore.kernel.org/all/20260512124837.38883-1-lance.yang@linux.dev/
2) There is a _similar_ check close to this one in memory_failure(),
just before this one:
if (TestSetPageHWPoison(p)) {
....
action_result()
goto unlock_mutex;
}
and now
if (PageReserved(p)) {
...
action_result()
goto unlock_mutes;
}
3) I wanted to give get it as real layering point, not handwaving.
That said, I will short-circuit reserved pages inside get_any_page(), in
an updated version.
Again, thanks for the review and direction!
--breno
^ permalink raw reply
* [PATCH v11 1/4] bug/kunit: Core support for suppressing warning backtraces
From: Albert Esteve @ 2026-05-14 11:06 UTC (permalink / raw)
To: Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti
Cc: linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-riscv, linux-doc, peterz, Alessandro Carminati,
Guenter Roeck, Kees Cook, Albert Esteve
In-Reply-To: <20260514-kunit_add_support-v11-0-b36a530a6d8f@redhat.com>
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 suppress warning backtraces
originating from the current kthread while executing test code. Since
each KUnit test runs in its own kthread, this effectively scopes
suppression to the test that enabled it. Limit changes to generic code
to the absolute minimum.
Implementation details:
Suppression is integrated into the existing KUnit hooks infrastructure
in test-bug.h, reusing the kunit_running static branch for zero
overhead when no tests are running.
Suppression is checked at three points in the warning path:
- In warn_slowpath_fmt(), the check runs before any output, fully
suppressing both message and backtrace. This covers architectures
without __WARN_FLAGS.
- In __warn_printk(), the check suppresses the warning message text.
This covers architectures that define __WARN_FLAGS but not their own
__WARN_printf (arm64, loongarch, parisc, powerpc, riscv, sh), where
the message is printed before the trap enters __report_bug().
- In __report_bug(), the check runs before __warn() is called,
suppressing the backtrace and stack dump.
To avoid double-counting on architectures where both __warn_printk()
and __report_bug() run for the same warning, kunit_is_suppressed_warning()
takes a bool parameter: true to increment the suppression counter
(used in warn_slowpath_fmt and __report_bug), false to check only
(used in __warn_printk).
The suppression state is dynamically allocated via kunit_kzalloc() and
tied to the KUnit test lifecycle via kunit_add_action(), ensuring
automatic cleanup at test exit. Writer-side access to the global
suppression list is serialized with a spinlock; readers use RCU.
Two API forms are provided:
- kunit_warning_suppress(test) { ... }: scoped, uses __cleanup for
automatic teardown on scope exit, kunit_add_action() as safety net
for abnormal exits (e.g. kthread_exit from failed assertions).
Suppression handle is only accessible inside the block.
- kunit_start/end_suppress_warning(test): direct functions returning
an explicit handle, for retaining the handle within the test,
or for cross-function usage.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Alessandro Carminati <acarmina@redhat.com>
Reviewed-by: Kees Cook <kees@kernel.org>
Reviewed-by: David Gow <david@davidgow.net>
Signed-off-by: Albert Esteve <aesteve@redhat.com>
---
include/kunit/test-bug.h | 26 ++++++++++
include/kunit/test.h | 98 ++++++++++++++++++++++++++++++++++++++
kernel/panic.c | 11 +++++
lib/bug.c | 14 +++++-
lib/kunit/Makefile | 3 +-
lib/kunit/bug.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++
lib/kunit/hooks-impl.h | 2 +
7 files changed, 271 insertions(+), 3 deletions(-)
diff --git a/include/kunit/test-bug.h b/include/kunit/test-bug.h
index 47aa8f21ccce8..99869029fc686 100644
--- a/include/kunit/test-bug.h
+++ b/include/kunit/test-bug.h
@@ -10,6 +10,7 @@
#define _KUNIT_TEST_BUG_H
#include <linux/stddef.h> /* for NULL */
+#include <linux/types.h> /* for bool */
#if IS_ENABLED(CONFIG_KUNIT)
@@ -23,6 +24,7 @@ DECLARE_STATIC_KEY_FALSE(kunit_running);
extern struct kunit_hooks_table {
__printf(3, 4) void (*fail_current_test)(const char*, int, const char*, ...);
void *(*get_static_stub_address)(struct kunit *test, void *real_fn_addr);
+ bool (*is_suppressed_warning)(bool count);
} kunit_hooks;
/**
@@ -60,9 +62,33 @@ static inline struct kunit *kunit_get_current_test(void)
} \
} while (0)
+/**
+ * kunit_is_suppressed_warning() - Check if warnings are being suppressed
+ * by the current KUnit test.
+ * @count: if true, increment the suppression counter on match.
+ *
+ * Returns true if the current task has active warning suppression.
+ * Uses the kunit_running static branch for zero overhead when no tests run.
+ *
+ * A single WARN*() may traverse multiple call sites in the warning path
+ * (e.g., __warn_printk() and __report_bug()). Pass @count = true at the
+ * primary suppression point to count each warning exactly once, and
+ * @count = false at secondary points to suppress output without
+ * inflating the count.
+ */
+static inline bool kunit_is_suppressed_warning(bool count)
+{
+ if (!static_branch_unlikely(&kunit_running))
+ return false;
+
+ return kunit_hooks.is_suppressed_warning &&
+ kunit_hooks.is_suppressed_warning(count);
+}
+
#else
static inline struct kunit *kunit_get_current_test(void) { return NULL; }
+static inline bool kunit_is_suppressed_warning(bool count) { return false; }
#define kunit_fail_current_test(fmt, ...) do {} while (0)
diff --git a/include/kunit/test.h b/include/kunit/test.h
index 9cd1594ab697d..be71612f61655 100644
--- a/include/kunit/test.h
+++ b/include/kunit/test.h
@@ -1795,4 +1795,102 @@ do { \
// include resource.h themselves if they need it.
#include <kunit/resource.h>
+/*
+ * Warning backtrace suppression API.
+ *
+ * Suppresses WARN*() backtraces on the current task while active. Two forms
+ * are provided:
+ *
+ * - Scoped: kunit_warning_suppress(test) { ... }
+ * Suppression is active for the duration of the block. On normal exit,
+ * the for-loop increment deactivates suppression. On early exit (break,
+ * return, goto), the __cleanup attribute fires. On kthread_exit() (e.g.,
+ * a failed KUnit assertion), kunit_add_action() cleans up at test
+ * teardown. The suppression handle is only accessible inside the block,
+ * so warning counts must be checked before the block exits.
+ *
+ * - Direct: kunit_start_suppress_warning() / kunit_end_suppress_warning()
+ * The underlying functions, returning an explicit handle pointer. Use
+ * when the handle needs to be retained (e.g., for post-suppression
+ * count checks) or passed across helper functions.
+ */
+struct kunit_suppressed_warning;
+
+struct kunit_suppressed_warning *
+kunit_start_suppress_warning(struct kunit *test);
+void kunit_end_suppress_warning(struct kunit *test,
+ struct kunit_suppressed_warning *w);
+int kunit_suppressed_warning_count(struct kunit_suppressed_warning *w);
+void __kunit_suppress_auto_cleanup(struct kunit_suppressed_warning **wp);
+bool kunit_has_active_suppress_warning(void);
+
+/**
+ * kunit_warning_suppress() - Suppress WARN*() backtraces for the duration
+ * of a block.
+ * @test: The test context object.
+ *
+ * Scoped form of the suppression API. Suppression starts when the block is
+ * entered and ends automatically when the block exits through any path. See
+ * the section comment above for the cleanup guarantees on each exit path.
+ * Fails the test if suppression is already active; nesting is not supported.
+ *
+ * The warning count can be checked inside the block via
+ * KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(). The handle is not accessible
+ * after the block exits.
+ *
+ * Example::
+ *
+ * kunit_warning_suppress(test) {
+ * trigger_warning();
+ * KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1);
+ * }
+ */
+#define kunit_warning_suppress(test) \
+ for (struct kunit_suppressed_warning *__kunit_suppress \
+ __cleanup(__kunit_suppress_auto_cleanup) = \
+ kunit_start_suppress_warning(test); \
+ __kunit_suppress; \
+ kunit_end_suppress_warning(test, __kunit_suppress), \
+ __kunit_suppress = NULL)
+
+/**
+ * KUNIT_SUPPRESSED_WARNING_COUNT() - Returns the suppressed warning count.
+ *
+ * Returns the number of WARN*() calls suppressed since the current
+ * suppression block started, or 0 if the handle is NULL. Usable inside a
+ * kunit_warning_suppress() block.
+ */
+#define KUNIT_SUPPRESSED_WARNING_COUNT() \
+ kunit_suppressed_warning_count(__kunit_suppress)
+
+/**
+ * KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT() - Sets an expectation that the
+ * suppressed warning count equals
+ * @expected.
+ * @test: The test context object.
+ * @expected: an expression that evaluates to the expected warning count.
+ *
+ * Sets an expectation that the number of suppressed WARN*() calls equals
+ * @expected. This is semantically equivalent to
+ * KUNIT_EXPECT_EQ(@test, KUNIT_SUPPRESSED_WARNING_COUNT(), @expected).
+ * See KUNIT_EXPECT_EQ() for more information.
+ */
+#define KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, expected) \
+ KUNIT_EXPECT_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), expected)
+
+/**
+ * KUNIT_ASSERT_SUPPRESSED_WARNING_COUNT() - Sets an assertion that the
+ * suppressed warning count equals
+ * @expected.
+ * @test: The test context object.
+ * @expected: an expression that evaluates to the expected warning count.
+ *
+ * Sets an assertion that the number of suppressed WARN*() calls equals
+ * @expected. This is the same as KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(),
+ * except it causes an assertion failure (see KUNIT_ASSERT_TRUE()) when the
+ * assertion is not met.
+ */
+#define KUNIT_ASSERT_SUPPRESSED_WARNING_COUNT(test, expected) \
+ KUNIT_ASSERT_EQ(test, KUNIT_SUPPRESSED_WARNING_COUNT(), expected)
+
#endif /* _KUNIT_TEST_H */
diff --git a/kernel/panic.c b/kernel/panic.c
index 20feada5319d4..213725b612aa1 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/test-bug.h>
#define PANIC_TIMER_STEP 100
#define PANIC_BLINK_SPD 18
@@ -1124,6 +1125,11 @@ void warn_slowpath_fmt(const char *file, int line, unsigned taint,
bool rcu = warn_rcu_enter();
struct warn_args args;
+ if (kunit_is_suppressed_warning(true)) {
+ warn_rcu_exit(rcu);
+ return;
+ }
+
pr_warn(CUT_HERE);
if (!fmt) {
@@ -1146,6 +1152,11 @@ void __warn_printk(const char *fmt, ...)
bool rcu = warn_rcu_enter();
va_list args;
+ if (kunit_is_suppressed_warning(false)) {
+ warn_rcu_exit(rcu);
+ return;
+ }
+
pr_warn(CUT_HERE);
va_start(args, fmt);
diff --git a/lib/bug.c b/lib/bug.c
index 224f4cfa4aa31..d99e369bc1103 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/test-bug.h>
extern struct bug_entry __start___bug_table[], __stop___bug_table[];
@@ -209,8 +210,6 @@ static enum bug_trap_type __report_bug(struct bug_entry *bug, unsigned long buga
return BUG_TRAP_TYPE_NONE;
}
- disable_trace_on_warning();
-
bug_get_file_line(bug, &file, &line);
fmt = bug_get_format(bug);
@@ -220,6 +219,17 @@ 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;
+#ifdef CONFIG_KUNIT
+ /*
+ * Before the once logic so suppressed warnings do not consume
+ * the single-fire budget of WARN_ON_ONCE().
+ */
+ if (warning && kunit_is_suppressed_warning(true))
+ return BUG_TRAP_TYPE_WARN;
+#endif
+
+ disable_trace_on_warning();
+
if (warning && once) {
if (done)
return BUG_TRAP_TYPE_WARN;
diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile
index 656f1fa35abcc..4592f9d0aa8dd 100644
--- a/lib/kunit/Makefile
+++ b/lib/kunit/Makefile
@@ -10,7 +10,8 @@ kunit-objs += test.o \
executor.o \
attributes.o \
device.o \
- platform.o
+ platform.o \
+ bug.o
ifeq ($(CONFIG_KUNIT_DEBUGFS),y)
kunit-objs += debugfs.o
diff --git a/lib/kunit/bug.c b/lib/kunit/bug.c
new file mode 100644
index 0000000000000..8579235c9ca68
--- /dev/null
+++ b/lib/kunit/bug.c
@@ -0,0 +1,120 @@
+// 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/resource.h>
+#include <linux/export.h>
+#include <linux/rculist.h>
+#include <linux/sched.h>
+#include <linux/sched/task.h>
+#include <linux/spinlock.h>
+
+#include "hooks-impl.h"
+
+struct kunit_suppressed_warning {
+ struct list_head node;
+ struct task_struct *task;
+ struct kunit *test;
+ atomic_t counter;
+};
+
+static LIST_HEAD(suppressed_warnings);
+static DEFINE_SPINLOCK(suppressed_warnings_lock);
+
+static void kunit_suppress_warning_remove(struct kunit_suppressed_warning *w)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&suppressed_warnings_lock, flags);
+ list_del_rcu(&w->node);
+ spin_unlock_irqrestore(&suppressed_warnings_lock, flags);
+ put_task_struct(w->task);
+}
+
+KUNIT_DEFINE_ACTION_WRAPPER(kunit_suppress_warning_cleanup,
+ kunit_suppress_warning_remove,
+ struct kunit_suppressed_warning *);
+
+bool kunit_has_active_suppress_warning(void)
+{
+ return __kunit_is_suppressed_warning_impl(false);
+}
+EXPORT_SYMBOL_GPL(kunit_has_active_suppress_warning);
+
+struct kunit_suppressed_warning *
+kunit_start_suppress_warning(struct kunit *test)
+{
+ struct kunit_suppressed_warning *w;
+ unsigned long flags;
+ int ret;
+
+ if (kunit_has_active_suppress_warning()) {
+ KUNIT_FAIL(test, "Another suppression block is already active");
+ return NULL;
+ }
+
+ w = kunit_kzalloc(test, sizeof(*w), GFP_KERNEL);
+ if (!w) {
+ KUNIT_FAIL(test, "Failed to allocate suppression handle.");
+ return NULL;
+ }
+
+ w->task = get_task_struct(current);
+ w->test = test;
+
+ spin_lock_irqsave(&suppressed_warnings_lock, flags);
+ list_add_rcu(&w->node, &suppressed_warnings);
+ spin_unlock_irqrestore(&suppressed_warnings_lock, flags);
+
+ ret = kunit_add_action_or_reset(test,
+ kunit_suppress_warning_cleanup, w);
+ if (ret) {
+ KUNIT_FAIL(test, "Failed to add suppression cleanup action.");
+ return NULL;
+ }
+
+ return w;
+}
+EXPORT_SYMBOL_GPL(kunit_start_suppress_warning);
+
+void kunit_end_suppress_warning(struct kunit *test,
+ struct kunit_suppressed_warning *w)
+{
+ if (!w)
+ return;
+ kunit_release_action(test, kunit_suppress_warning_cleanup, w);
+}
+EXPORT_SYMBOL_GPL(kunit_end_suppress_warning);
+
+void __kunit_suppress_auto_cleanup(struct kunit_suppressed_warning **wp)
+{
+ if (*wp)
+ kunit_end_suppress_warning((*wp)->test, *wp);
+}
+EXPORT_SYMBOL_GPL(__kunit_suppress_auto_cleanup);
+
+int kunit_suppressed_warning_count(struct kunit_suppressed_warning *w)
+{
+ return w ? atomic_read(&w->counter) : 0;
+}
+EXPORT_SYMBOL_GPL(kunit_suppressed_warning_count);
+
+bool __kunit_is_suppressed_warning_impl(bool count)
+{
+ struct kunit_suppressed_warning *w;
+
+ guard(rcu)();
+ list_for_each_entry_rcu(w, &suppressed_warnings, node) {
+ if (w->task == current) {
+ if (count)
+ atomic_inc(&w->counter);
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/lib/kunit/hooks-impl.h b/lib/kunit/hooks-impl.h
index 4e71b2d0143ba..d8720f2616925 100644
--- a/lib/kunit/hooks-impl.h
+++ b/lib/kunit/hooks-impl.h
@@ -19,6 +19,7 @@ void __printf(3, 4) __kunit_fail_current_test_impl(const char *file,
int line,
const char *fmt, ...);
void *__kunit_get_static_stub_address_impl(struct kunit *test, void *real_fn_addr);
+bool __kunit_is_suppressed_warning_impl(bool count);
/* Code to set all of the function pointers. */
static inline void kunit_install_hooks(void)
@@ -26,6 +27,7 @@ static inline void kunit_install_hooks(void)
/* Install the KUnit hook functions. */
kunit_hooks.fail_current_test = __kunit_fail_current_test_impl;
kunit_hooks.get_static_stub_address = __kunit_get_static_stub_address_impl;
+ kunit_hooks.is_suppressed_warning = __kunit_is_suppressed_warning_impl;
}
#endif /* _KUNIT_HOOKS_IMPL_H */
--
2.53.0
^ permalink raw reply related
* [PATCH v11 0/4] kunit: Add support for suppressing warning backtraces
From: Albert Esteve @ 2026-05-14 11:06 UTC (permalink / raw)
To: Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Jonathan Corbet, Shuah Khan, Andrew Morton,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti
Cc: linux-kernel, linux-arch, linux-kselftest, kunit-dev, dri-devel,
workflows, linux-riscv, linux-doc, peterz, Alessandro Carminati,
Guenter Roeck, Kees Cook, Albert Esteve,
Linux Kernel Functional Testing, Maíra Canal, Dan Carpenter,
Kees Cook, Simona Vetter
Some unit tests intentionally trigger warning backtraces by passing bad
parameters to kernel API functions. Such unit tests typically check the
return value from such calls, not the existence of the warning backtrace.
Such intentionally generated warning backtraces are neither desirable
nor useful for a number of reasons:
- They can result in overlooked real problems.
- A warning that suddenly starts to show up in unit tests needs to be
investigated and has to be marked to be ignored, for example by
adjusting filter scripts. Such filters are ad hoc because there is
no real standard format for warnings. On top of that, such filter
scripts would require constant maintenance.
One option to address the problem would be to add messages such as
"expected warning backtraces start/end here" to the kernel log.
However, that would again require filter scripts, might result in
missing real problematic warning backtraces triggered while the test
is running, and the irrelevant backtrace(s) would still clog the
kernel log.
Solve the problem by providing a means to suppress warning backtraces
originating from the current kthread while executing test code.
Since each KUnit test runs in its own kthread, this effectively scopes
suppression to the test that enabled it, without requiring any
architecture-specific code.
Overview:
Patch#1 Introduces the suppression infrastructure integrated into
KUnit's hook mechanism.
Patch#2 Adds selftests to validate the functionality.
Patch#3 Demonstrates real-world usage in the DRM subsystem.
Patch#4 Documents the new API and usage guidelines.
Design Notes:
Suppression is integrated into the existing KUnit hooks infrastructure,
reusing the kunit_running static branch for zero overhead
when no tests are running. The implementation lives entirely in the
kunit module; only a static-inline wrapper and a function pointer
slot are added to built-in code.
Suppression is checked at three points in the warning path:
- In `warn_slowpath_fmt()` (kernel/panic.c), for architectures without
__WARN_FLAGS. The check runs before any output, fully suppressing
both message and backtrace.
- In `__warn_printk()` (kernel/panic.c), for architectures that define
__WARN_FLAGS but not their own __WARN_printf (arm64, loongarch,
parisc, powerpc, riscv, sh). The check suppresses the warning message
text that is printed before the trap enters __report_bug().
- In `__report_bug()` (lib/bug.c), for architectures that define
__WARN_FLAGS. The check runs before `__warn()` is called, suppressing
the backtrace and stack dump.
To avoid double-counting on architectures where both `__warn_printk()`
and `__report_bug()` run for the same warning, the hook takes a bool
parameter: true to increment the suppression counter, false to suppress
without counting.
The suppression state is dynamically allocated via kunit_kzalloc() and
tied to the KUnit test lifecycle via `kunit_add_action()`, ensuring
automatic cleanup at test exit. Writer-side access to the global
suppression list is serialized with a spinlock; readers use RCU.
Two API forms are provided:
- kunit_warning_suppress(test) { ... }: scoped blocks with automatic
cleanup. The suppression handle is not accessible outside the block,
so warning counts (if needed) must be checked inside. Multiple
suppression blocks are allowed.
- kunit_start/end_suppress_warning(test): direct functions that return
an explicit handle. Use when the handle needs to be retained, or passed
across helpers. Multiple suppression blocks are allowed.
This series is based on the RFC patch and subsequent discussion at
https://patchwork.kernel.org/project/linux-kselftest/patch/02546e59-1afe-4b08-ba81-d94f3b691c9a@moroto.mountain/
and offers a more comprehensive solution of the problem discussed there.
Changes since RFC:
- Introduced CONFIG_KUNIT_SUPPRESS_BACKTRACE
- Minor cleanups and bug fixes
- Added support for all affected architectures
- Added support for counting suppressed warnings
- Added unit tests using those counters
- Added patch to suppress warning backtraces in dev_addr_lists tests
Changes since v1:
- Rebased to v6.9-rc1
- Added Tested-by:, Acked-by:, and Reviewed-by: tags
[I retained those tags since there have been no functional changes]
- Introduced KUNIT_SUPPRESS_BACKTRACE configuration option, enabled by
default.
Changes since v2:
- Rebased to v6.9-rc2
- Added comments to drm warning suppression explaining why it is needed.
- Added patch to move conditional code in arch/sh/include/asm/bug.h
to avoid kerneldoc warning
- Added architecture maintainers to Cc: for architecture specific patches
- No functional changes
Changes since v3:
- Rebased to v6.14-rc6
- Dropped net: "kunit: Suppress lock warning noise at end of dev_addr_lists tests"
since 3db3b62955cd6d73afde05a17d7e8e106695c3b9
- Added __kunit_ and KUNIT_ prefixes.
- Tested on interessed architectures.
Changes since v4:
- Rebased to v6.15-rc7
- Dropped all code in __report_bug()
- Moved all checks in WARN*() macros.
- Dropped all architecture specific code.
- Made __kunit_is_suppressed_warning nice to noinstr functions.
Changes since v5:
- Rebased to v7.0-rc3
- Added RCU protection for the suppressed warnings list.
- Added static key and branching optimization.
- Removed custom `strcmp` implementation and reworked
__kunit_is_suppressed_warning() entrypoint function.
Changes since v6:
- Moved suppression checks from WARN*() macros to warn_slowpath_fmt()
and __report_bug().
- Replaced stack-allocated suppression struct with kunit_kzalloc() heap
allocation tied to the KUnit test lifecycle.
- Changed suppression strategy from function-name matching to task-scoped:
all warnings on the current task are suppressed between START and END,
rather than only warnings originating from a specific named function.
- Simplified macro API: removed KUNIT_DECLARE_SUPPRESSED_WARNING(),
the START macro now takes (test) and handles allocation internally.
- Removed static key and branching optiomization, as by the time it
was executed, callers are already in warn slowpaths.
- Link to v6: https://lore.kernel.org/r/20260317-kunit_add_support-v6-0-dd22aeb3fe5d@redhat.com
Changes since v7:
- Integrated suppression into existing KUnit hooks infrastructure
- Removed CONFIG_KUNIT_SUPPRESS_BACKTRACE
- Added suppression check in __warn_printk()
- Added spinlock for writer-side RCU protection
- Replaced explicit rcu_read_lock/unlock with guard(rcu)()
- Added scoped API (kunit_warning_suppress) using __cleanup attribute
- Updated DRM patch to use scoped API
- Expanded self-tests: incremental counting, cross-kthread isolation
- Rewrote documentation covering all three API forms with examples
- Link to v7: https://lore.kernel.org/r/20260420-kunit_add_support-v7-0-e8bc6e0f70de@redhat.com
Changes since v8:
- Rebased to v7.1-rc2
- Remove KUNIT_START/END_SUPPRESSED_WARNING() macros
- Add KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT checks to drm tests
- Link to v8: https://lore.kernel.org/r/20260504-kunit_add_support-v8-0-3e5957cdd235@redhat.com
Changes since v9:
- Fix silent false-pass when kunit_start_suppress_warning() returns NULL
- Fix RCU lockdep splat for kunit_is_suppressed_warning() calls
- Move disable_trace_on_warning() in __report_bug()
- Make suppress counter atomic
- Mark helper warn functions in selftest as noinline
- Add kunit_skip() for CONFIG_BUG=n in selftests
- Fix potentially uninitialized data.was_active in kthread seltest
- Add kthread_stop() in kthread selftest early exit
- Initialize scaling_factor to INT_MIN in DRM scaling tests
- Add include for bool in test-bug.h to fix CONFIG_KUNIT=n case
- Link to v9: https://lore.kernel.org/r/20260508-kunit_add_support-v9-0-99df7aa880f6@redhat.com
Changes since v10:
- Remove synchronize_rcu() to avoid sleeping in atomic context
- Pin task_struct refcount to prevent ABA false-positive matches
- Loop in suppression selftest to prevent use-after-free on kthread exit
- Skip DRM rect tests on CONFIG_BUG=n
- Link to v10: https://lore.kernel.org/r/20260513-kunit_add_support-v10-0-e379d206c8cd@redhat.com
--
2.34.1
---
To: Brendan Higgins <brendan.higgins@linux.dev>
To: David Gow <david@davidgow.net>
To: Rae Moar <raemoar63@gmail.com>
To: Andrew Morton <akpm@linux-foundation.org>
To: Paul Walmsley <pjw@kernel.org>
To: Palmer Dabbelt <palmer@dabbelt.com>
To: Albert Ou <aou@eecs.berkeley.edu>
To: Alexandre Ghiti <alex@ghiti.fr>
To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
To: Maxime Ripard <mripard@kernel.org>
To: Thomas Zimmermann <tzimmermann@suse.de>
To: David Airlie <airlied@gmail.com>
To: Simona Vetter <simona@ffwll.ch>
To: Jonathan Corbet <corbet@lwn.net>
To: Shuah Khan <skhan@linuxfoundation.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-kselftest@vger.kernel.org
Cc: kunit-dev@googlegroups.com
Cc: linux-riscv@lists.infradead.org
Cc: dri-devel@lists.freedesktop.org
Cc: workflows@vger.kernel.org
Cc: linux-doc@vger.kernel.org
---
Alessandro Carminati (1):
bug/kunit: Core support for suppressing warning backtraces
Guenter Roeck (3):
kunit: Add backtrace suppression self-tests
drm: Suppress intentional warning backtraces in scaling unit tests
kunit: Add documentation for warning backtrace suppression API
Documentation/dev-tools/kunit/usage.rst | 46 +++++++-
drivers/gpu/drm/tests/drm_rect_test.c | 46 +++++++-
include/kunit/test-bug.h | 26 +++++
include/kunit/test.h | 98 ++++++++++++++++
kernel/panic.c | 11 ++
lib/bug.c | 14 ++-
lib/kunit/Makefile | 4 +-
lib/kunit/backtrace-suppression-test.c | 198 ++++++++++++++++++++++++++++++++
lib/kunit/bug.c | 120 +++++++++++++++++++
lib/kunit/hooks-impl.h | 2 +
10 files changed, 555 insertions(+), 10 deletions(-)
---
base-commit: 74fe02ce122a6103f207d29fafc8b3a53de6abaf
change-id: 20260312-kunit_add_support-2f35806b19dd
Best regards,
--
Albert Esteve <aesteve@redhat.com>
^ permalink raw reply
* Re: [PATCH v7 1/6] mm/memory-failure: drop dead error_states[] entry for reserved pages
From: Breno Leitao @ 2026-05-14 10:55 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: Miaohe Lin, Andrew Morton, Lorenzo Stoakes, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Shuah Khan,
Naoya Horiguchi, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Jonathan Corbet, Shuah Khan, Liam R. Howlett,
linux-mm, linux-kernel, linux-doc, linux-kselftest,
linux-trace-kernel, kernel-team
In-Reply-To: <5712adbc-b2fd-49fd-9827-cace47eff9ad@kernel.org>
On Wed, May 13, 2026 at 10:10:27PM +0200, David Hildenbrand (Arm) wrote:
> On 5/13/26 17:39, Breno Leitao wrote:
> > * memory_failure() reaches identify_page_state() only after
> > get_hwpoison_page() returned 1. get_any_page() reaches that
> > return only via __get_hwpoison_page(), which gates the refcount
> > on HWPoisonHandlable(). HWPoisonHandlable() rejects PG_reserved
> > pages, so they fail with -EBUSY/-EIO long before
> > identify_page_state() runs.
>
> You should clarify why they are rejected. There is no explicit check for
> PG_reserved in there!
True, I meant that PG_reserved pages do not fit any of the criterias of
HWPoisonHandlable().
I will rewrite it more explictly:
__get_hwpoison_page() only takes a refcount when the page is
HWPoisonHandlable()'d, and HWPoisonHandlable() is an allowlist for LRU /
free-buddy / (soft-offline) movable_ops pages.
is it any better?
> > * try_memory_failure_hugetlb() reaches identify_page_state() on
> > the MF_HUGETLB_IN_USED branch, but the page is necessarily a
> > hugetlb folio there. The first table entry that matches a
> > hugetlb folio is { head, head, MF_MSG_HUGE, me_huge_page }, so
> > they dispatch to me_huge_page() before the (now-removed)
> > reserved entry would have matched, regardless of whether
> > PG_reserved happens to be set on the head page.
>
> See hugetlb_folio_init_vmemmap(): we always clear PG_reserved for hugetlb folios
> allocated from memblock.
Thanks. I clearly see a call to __folio_clear_reserved(folio), so, huge pagetlb folios
are never reserved.
A better summary would be:
try_memory_failure_hugetlb() reaches identify_page_state() only via the
MF_HUGETLB_IN_USED branch, as hugetlb folios don't carry PG_reserved at
that point (hugetlb_folio_init_vmemmap() clears it during init).
> Yes, I think this should work.
>
> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Thanks for the review,
--breno
^ permalink raw reply
* Re: [PATCH] driver core: Add cmdline option to force probe type
From: Greg KH @ 2026-05-14 10:16 UTC (permalink / raw)
To: Jianlin Lv
Cc: corbet, skhan, rafael, dakr, jianlv, linux-kernel, linux-doc,
driver-core
In-Reply-To: <20260514094955.76305-1-jianlv@ebay.com>
On Thu, May 14, 2026 at 05:49:55PM +0800, Jianlin Lv wrote:
> From: Jianlin Lv <iecedge@gmail.com>
>
> Device drivers that use asynchronous probing can cause non-deterministic
> device ordering and naming across reboots. A typical example is storage
> drivers (like sd/nvme): asynchronous probing can lead to inconsistent disk
> logical names after reboot. In scenarios where disk naming consistency is
> critical, the probe type should be set to synchronous.
>
> This patch introduces a driver_probe kernel parameter that overrides any
> driver's hard-coded probe type settings and allows runtime control without
> requiring kernel recompilation:
>
> driver_probe=PROBE_TYPE_SYNC,nvme,sd # Force specific drivers sync
> driver_probe=PROBE_TYPE_ASYNC,*,usb # Force all async except usb
> driver_probe=PROBE_TYPE_SYNC,* # Force all drivers synchronous
>
> The implementation replaces the limited driver_async_probe parameter with
> a more flexible interface that can force either synchronous or asynchronous
> probing as needed.
>
> Signed-off-by: Jianlin Lv <iecedge@gmail.com>
> ---
> .../admin-guide/kernel-parameters.txt | 27 +++++--
> drivers/base/dd.c | 71 ++++++++++++++-----
> 2 files changed, 74 insertions(+), 24 deletions(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 4d0f545fb3ec..b43a8bd20356 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -1377,12 +1377,27 @@ Kernel parameters
> it becomes active and is searched during signature
> verification.
>
> - driver_async_probe= [KNL]
> - List of driver names to be probed asynchronously. *
> - matches with all driver names. If * is specified, the
> - rest of the listed driver names are those that will NOT
> - match the *.
> - Format: <driver_name1>,<driver_name2>...
You can not remove an existing user/kernel api, sorry, that is not
allowed as you just broke all systems that were relying on this :(
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH v4 1/3] slab: support for compiler-assisted type-based slab cache partitioning
From: Harry Yoo (Oracle) @ 2026-05-14 10:13 UTC (permalink / raw)
To: Vlastimil Babka (SUSE)
Cc: Marco Elver, Andrew Morton, Gustavo A. R. Silva, Liam R. Howlett,
Andrey Konovalov, Bill Wendling, David Hildenbrand,
David Rientjes, Dmitry Vyukov, Jann Horn, Justin Stitt, KP Singh,
Kees Cook, Lorenzo Stoakes, Matteo Rizzo, Michal Hocko,
Mike Rapoport, Nathan Chancellor, Nick Desaulniers,
Roman Gushchin, Suren Baghdasaryan, linux-hardening,
Nicolas Schier, Dennis Zhou, Tejun Heo, Christoph Lameter, Hao Li,
Liam R. Howlett, Alexander Potapenko, Miguel Ojeda, linux-kbuild,
linux-kernel, linux-mm, kasan-dev, llvm, GONG Ruiqi,
Jonathan Corbet, linux-doc@vger.kernel.org
In-Reply-To: <560a84ed-7daf-4a78-a314-b867c73bce22@kernel.org>
On Thu, May 14, 2026 at 11:01:26AM +0200, Vlastimil Babka (SUSE) wrote:
> Applied [1] to slab/for-next, thanks. That means including the kernel-doc
> workarounds in patch 3. I know Jon said someone might hate it, but maybe it
> will motivate them for creating a proper fix :) It seems better than leaving
> doc generation broken or not applying this series at all.
>
> https://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git/log/?h=slab/for-7.2/alloc_token
>
> I did the following fixup to remove passing an unnecessary NULL argument for
> __kmalloc_nolock() with buckets enabled. Made bloat-o-meter happier a bit.
[...]
Looks reasonable to me, thanks!
--
Cheers,
Harry / Hyeonggon
^ permalink raw reply
* Re: [PATCH v2 0/5] KVM: PPC: Handle CPU compatibility mode for nested guests
From: Amit Machhiwal @ 2026-05-14 10:04 UTC (permalink / raw)
To: Ritesh Harjani
Cc: Amit Machhiwal, linuxppc-dev, Madhavan Srinivasan, Vaibhav Jain,
Paolo Bonzini, Nicholas Piggin, Michael Ellerman,
Christophe Leroy (CS GROUP), Jonathan Corbet, Shuah Khan, kvm,
linux-kernel, linux-doc
In-Reply-To: <o6iir82o.ritesh.list@gmail.com>
Hi Ritesh,
Thanks for taking a look at this series. Please find my comment inline below:
On 2026/05/14 08:49 AM, Ritesh Harjani wrote:
>
> Hi Amit,
>
> Amit Machhiwal <amachhiw@linux.ibm.com> writes:
>
> > On POWER systems, newer processor generations can operate in compatibility
> > modes corresponding to earlier generations (e.g., a Power11 system running
> > in Power10 compatibility mode). In such cases, the effective CPU level
> > exposed to guests differs from the physical processor generation.
> >
> > This creates a problem for nested virtualization. When booting a nested KVM
> > guest (L2) inside a host KVM guest (L1) running in a compatibility mode,
> > userspace (e.g., QEMU) may derive the CPU model from the raw hardware PVR
> > and attempt to configure the nested guest accordingly. However, the L1
> > partition is constrained by the compatibility level negotiated with the
> > hypervisor (L0), and requests exceeding that level are rejected, leading to
> > guest boot failures such as:
> >
> > KVM-NESTEDv2: couldn't set guest wide elements
> >
> > This series addresses the issue in two steps:
> >
> > 1. Detect and reject invalid compatibility requests early in KVM to avoid
> > late failures.
> >
> > 2. Provide a mechanism for userspace to query the effective CPU
> > compatibility modes supported by the host, so it can select an
> > appropriate CPU model for nested guests.
> >
>
> Do we really need to add a uapi change for this? Tools like Qemu can
> read the device tree info of the host, isn't it?
While cpu-version is available in /proc/device-tree/cpus/<cpu#>/cpu-version on
both L1 booted on PowerNV and PowerVM LPARs, I believe the UAPI change is still
preferable for several reasons:
1. We would want to rely on the capabilities negotiated with pHYP (L0) in KVM on
PowerVM case instead of device tree property. Also, the cpu-version property
only depicts the current compat mode host (L1) is booted in but doesn't
really point to what all compat modes are supported for the nested guest
(L2).
2. procfs dependency: Not all systems run with procfs enabled (CONFIG_PROC_FS is
optional). For example, minimal configurations (like buildroot) might disable
it. The KVM ioctl works regardless of procfs availability since it accesses
kernel data structures directly.
3. Kernel validation: The kernel validates and normalizes the compatibility
information. For example, patch 1 adds validation logic that rejects invalid
compatibility requests early. The ioctl ensures userspace gets validated,
consistent data.
4. Abstraction & stability: While /proc/device-tree works today, it's an
implementation detail. The UAPI provides a stable interface that won't break
if the underlying mechanism changes.
5. Semantic clarity: KVM_PPC_GET_COMPAT_CAPS clearly expresses what
compatibility modes can I use for KVM guests vs. parsing device tree which
requires understanding the semantic meaning of cpu-version.
>
> > To achieve this, the series introduces a new KVM capability and ioctl
> > (KVM_CAP_PPC_COMPAT_CAPS / KVM_PPC_GET_COMPAT_CAPS) that expose the
> > compatibility modes supported by the host.
> >
> > The implementation supports both:
> >
> > - PowerVM (nested API v2), where compatibility information is obtained
> > via the H_GUEST_GET_CAPABILITIES hypercall.
> > - PowerNV (nested API v1), where compatibility is derived from the device
> > tree ("cpu-version") representing the effective processor compatibility
> > level.
>
> See there you go, for PowerNV if this info is provided in the device
> tree, then Qemu could as well just read that info, no?
>
> ... yup, kvmppc_read_int_dt() can do that I guess.
>
> So, my request is, can we look into this to see, if there is a possible
> alternative to this? maybe we already have a mechanism which Qemu could
> use to get this info already?
You're right that QEMU could read the device tree from procfs. We had discussed
this approach internally as well. However, we believe the UAPI approach offers
additional benefits and looks more robust and future proof as outlined above.
>
> btw - I haven't given a full read of the patch series, but reading the
> cover letter, I felt we should atleast add this info to the cover
> letter on, why a uapi change is really needed here, why can't the
> existing alternatives work for us.
I have described above why we did the UAPI change for the approach followed in
this series. Could you please suggest what else can be added?
Thanks,
Amit
> -ritesh
>
> >
> > This allows userspace (e.g., QEMU) to select a CPU model consistent with
> > the host compatibility mode, avoiding mismatches and enabling successful
> > nested guest boot.
> >
^ permalink raw reply
* [PATCH] driver core: Add cmdline option to force probe type
From: Jianlin Lv @ 2026-05-14 9:49 UTC (permalink / raw)
To: corbet, skhan, gregkh, rafael, dakr
Cc: iecedge, jianlv, linux-kernel, linux-doc, driver-core
From: Jianlin Lv <iecedge@gmail.com>
Device drivers that use asynchronous probing can cause non-deterministic
device ordering and naming across reboots. A typical example is storage
drivers (like sd/nvme): asynchronous probing can lead to inconsistent disk
logical names after reboot. In scenarios where disk naming consistency is
critical, the probe type should be set to synchronous.
This patch introduces a driver_probe kernel parameter that overrides any
driver's hard-coded probe type settings and allows runtime control without
requiring kernel recompilation:
driver_probe=PROBE_TYPE_SYNC,nvme,sd # Force specific drivers sync
driver_probe=PROBE_TYPE_ASYNC,*,usb # Force all async except usb
driver_probe=PROBE_TYPE_SYNC,* # Force all drivers synchronous
The implementation replaces the limited driver_async_probe parameter with
a more flexible interface that can force either synchronous or asynchronous
probing as needed.
Signed-off-by: Jianlin Lv <iecedge@gmail.com>
---
.../admin-guide/kernel-parameters.txt | 27 +++++--
drivers/base/dd.c | 71 ++++++++++++++-----
2 files changed, 74 insertions(+), 24 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 4d0f545fb3ec..b43a8bd20356 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1377,12 +1377,27 @@ Kernel parameters
it becomes active and is searched during signature
verification.
- driver_async_probe= [KNL]
- List of driver names to be probed asynchronously. *
- matches with all driver names. If * is specified, the
- rest of the listed driver names are those that will NOT
- match the *.
- Format: <driver_name1>,<driver_name2>...
+ driver_probe= [KNL]
+ Control device driver probe types. This parameter takes
+ precedence over driver hard-coded probe_type settings.
+ Format: <probe_type>,<driver_name1>,<driver_name2>,...
+
+ <probe_type>:
+ PROBE_TYPE_SYNC - Force synchronous probing
+ PROBE_TYPE_ASYNC - Force asynchronous probing
+
+ Driver name patterns:
+ driver1,driver2 - Apply to specific drivers only
+ *,driver1,driver2 - Apply to all drivers except listed ones
+ * (alone) - Apply to all drivers
+
+ Examples:
+ driver_probe=PROBE_TYPE_SYNC,nvme,sd
+ Force synchronous probe for nvme and sd drivers
+ driver_probe=PROBE_TYPE_SYNC,*,graphics,usb-storage
+ Force sync for all drivers except graphics and usb-storage
+ driver_probe=PROBE_TYPE_ASYNC,*
+ Force async probe for all drivers
drm.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>]
Broken monitors, graphic adapters, KVMs and EDIDless
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 1dc1e3528043..7d8e0c932e0b 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -59,9 +59,10 @@ static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
static bool initcalls_done;
/* Save the async probe drivers' name from kernel cmdline */
-#define ASYNC_DRV_NAMES_MAX_LEN 256
-static char async_probe_drv_names[ASYNC_DRV_NAMES_MAX_LEN];
-static bool async_probe_default;
+#define DRIVER_PROBE_NAMES_MAX_LEN 256
+static char driver_probe_names[DRIVER_PROBE_NAMES_MAX_LEN];
+static enum probe_type driver_probe_default = PROBE_DEFAULT_STRATEGY;
+static bool driver_probe_wildcard;
/*
* In some cases, like suspend to RAM or hibernation, It might be reasonable
@@ -914,30 +915,67 @@ static int driver_probe_device(const struct device_driver *drv, struct device *d
return ret;
}
-static inline bool cmdline_requested_async_probing(const char *drv_name)
+static int __init save_driver_probe_options(char *buf)
{
- bool async_drv;
+ if (strlen(buf) >= DRIVER_PROBE_NAMES_MAX_LEN)
+ pr_warn("Too long list of driver names for 'driver_probe'!\n");
+
+ strscpy(driver_probe_names, buf, DRIVER_PROBE_NAMES_MAX_LEN);
+
+ if (parse_option_str(driver_probe_names, "PROBE_TYPE_SYNC"))
+ driver_probe_default = PROBE_FORCE_SYNCHRONOUS;
+ else if (parse_option_str(driver_probe_names, "PROBE_TYPE_ASYNC"))
+ driver_probe_default = PROBE_PREFER_ASYNCHRONOUS;
+ else {
+ pr_warn("driver_probe: invalid type\n");
+ return 1;
+ }
- async_drv = parse_option_str(async_probe_drv_names, drv_name);
+ driver_probe_wildcard = parse_option_str(driver_probe_names, "*");
+ pr_info("driver_probe: %s mode, list=\"%s\"\n",
+ driver_probe_wildcard ? "wildcard" : "specific",
+ driver_probe_names);
- return (async_probe_default != async_drv);
+ return 1;
}
+__setup("driver_probe=", save_driver_probe_options);
-/* The option format is "driver_async_probe=drv_name1,drv_name2,..." */
-static int __init save_async_options(char *buf)
+static int driver_probe_type_override(const char *drv_name)
{
- if (strlen(buf) >= ASYNC_DRV_NAMES_MAX_LEN)
- pr_warn("Too long list of driver names for 'driver_async_probe'!\n");
+ bool driver_listed;
- strscpy(async_probe_drv_names, buf, ASYNC_DRV_NAMES_MAX_LEN);
- async_probe_default = parse_option_str(async_probe_drv_names, "*");
+ if (driver_probe_default == PROBE_DEFAULT_STRATEGY)
+ return -1;
- return 1;
+ driver_listed = parse_option_str(driver_probe_names, drv_name);
+
+ if (driver_probe_wildcard) {
+ /* Wildcard mode: apply default to all, exceptions get opposite */
+ if (driver_listed)
+ return (driver_probe_default == PROBE_PREFER_ASYNCHRONOUS) ? 0 : 1;
+ else
+ return (driver_probe_default == PROBE_PREFER_ASYNCHRONOUS) ? 1 : 0;
+ } else {
+ /* Specific mode: only listed drivers get the specified type */
+ if (driver_listed)
+ return (driver_probe_default == PROBE_PREFER_ASYNCHRONOUS) ? 1 : 0;
+ else
+ return -1; /* Not listed - no override */
+ }
}
-__setup("driver_async_probe=", save_async_options);
static bool driver_allows_async_probing(const struct device_driver *drv)
{
+ int probe_override;
+
+ /* Check driver_probe parameter first (highest priority) */
+ probe_override = driver_probe_type_override(drv->name);
+ if (probe_override >= 0) {
+ pr_info("driver_probe override: %s -> %s\n",
+ drv->name, probe_override ? "async" : "sync");
+ return probe_override;
+ }
+
switch (drv->probe_type) {
case PROBE_PREFER_ASYNCHRONOUS:
return true;
@@ -946,9 +984,6 @@ static bool driver_allows_async_probing(const struct device_driver *drv)
return false;
default:
- if (cmdline_requested_async_probing(drv->name))
- return true;
-
if (module_requested_async_probing(drv->owner))
return true;
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v7 1/6] mm/memory-failure: drop dead error_states[] entry for reserved pages
From: Lance Yang @ 2026-05-14 9:12 UTC (permalink / raw)
To: leitao
Cc: linmiaohe, akpm, david, ljs, vbabka, rppt, surenb, mhocko, shuah,
nao.horiguchi, rostedt, mhiramat, mathieu.desnoyers, corbet,
skhan, liam, linux-mm, linux-kernel, linux-doc, linux-kselftest,
linux-trace-kernel, kernel-team, Lance Yang
In-Reply-To: <20260513-ecc_panic-v7-1-be2e578e61da@debian.org>
On Wed, May 13, 2026 at 08:39:32AM -0700, Breno Leitao wrote:
>The first entry of error_states[],
>
> { reserved, reserved, MF_MSG_KERNEL, me_kernel },
>
>is unreachable. identify_page_state() has two callers, and neither
>one can dispatch a PG_reserved page to me_kernel():
>
> * memory_failure() reaches identify_page_state() only after
> get_hwpoison_page() returned 1. get_any_page() reaches that
> return only via __get_hwpoison_page(), which gates the refcount
> on HWPoisonHandlable(). HWPoisonHandlable() rejects PG_reserved
> pages, so they fail with -EBUSY/-EIO long before
> identify_page_state() runs.
HWPoisonHandlable() does not test PG_reserved directly; it only lets
LRU or free buddy pages through:
return PageLRU(page) || is_free_buddy_page(page);
So this really relies on PG_reserved not being combined with either of
those states. I would not expect that to happen, though.
>
> * try_memory_failure_hugetlb() reaches identify_page_state() on
> the MF_HUGETLB_IN_USED branch, but the page is necessarily a
> hugetlb folio there. The first table entry that matches a
> hugetlb folio is { head, head, MF_MSG_HUGE, me_huge_page }, so
> they dispatch to me_huge_page() before the (now-removed)
> reserved entry would have matched, regardless of whether
> PG_reserved happens to be set on the head page.
As David pointed out, hugetlb setup clears PG_reserved before setting
PG_head. See hugetlb_folio_init_vmemmap():
__folio_clear_reserved(folio);
__folio_set_head(folio);
>
>me_kernel() never executes and the entry exists only to be matched
>against by code that cannot see it.
identify_page_state() is reached only when get_hwpoison_page()
returns 1, but a PG_reserved page would not get that far, IIUC :)
>
>Drop the entry, the me_kernel() helper, and the now-unused
>"reserved" macro. Leave the MF_MSG_KERNEL enum value in place: it
>remains part of the tracepoint and pr_err() string tables, and
>follow-on work to classify unrecoverable kernel pages can reuse it
>without churning the user-visible enum.
>
>No functional change.
>
>Suggested-by: David Hildenbrand <david@kernel.org>
>Signed-off-by: Breno Leitao <leitao@debian.org>
>---
With David's comments addressed, feel free to add:
Reviewed-by: Lance Yang <lance.yang@linux.dev>
^ 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