Linux Documentation
 help / color / mirror / Atom feed
* [PATCH v2 00/33] rust: bump minimum Rust and `bindgen` versions
From: Miguel Ojeda @ 2026-04-05 23:52 UTC (permalink / raw)
  To: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc

As proposed in the past in e.g. LPC 2025 and the Maintainers Summit [1],
we are going to follow Debian Stable's Rust versions as our minimum
supported version.

Debian Trixie was released with a Rust 1.85.0 toolchain [2], which it
still uses to this day [3] (i.e. no update to Rust 1.85.1).

Debian Trixie was released with `bindgen` 0.71.1, which it also still
uses to this day [4].

Debian Trixie's release happened on 2025-08-09 [5], which means that a
fair amount of time has passed since its release for kernel developers
to upgrade.

Thus bump the minimum to the new versions, i.e.

  - Rust: 1.78.0 -> 1.85.0
  - bindgen: 0.65.1 -> 0.71.1

There are a few main parts to the series, in this order:

  - A few cleanups that can be performed before the bumps.
  - The Rust bump (and its cleanups).
  - The `bindgen` bump (and its cleanups).
  - Documentation updates.
  - The `cfi_encoding` patch, added here, which needs the bump.
  - The per-version flags support and a Clippy cleanup on top.

Link: https://lwn.net/Articles/1050174/ [1]
Link: https://www.debian.org/releases/trixie/release-notes/whats-new.en.html#desktops-and-well-known-packages [2]
Link: https://packages.debian.org/trixie/rustc [3]
Link: https://packages.debian.org/trixie/bindgen [4]
Link: https://www.debian.org/releases/trixie/ [5]
---
v1: https://lore.kernel.org/rust-for-linux/20260401114540.30108-1-ojeda@kernel.org/
v2:
  - Added patch to globally allow `incompatible_msrv` and removed the
    last instance.

  - Replaced `--remap-path-prefix` patches with one that drops the
    workaround entirely (and place it as the first one) and summarizes
    the discussion.

    I also noticed that `--remap-path-prefix` for `rustdoc` is still
    unstable (unlike `rustc`'s one), so I added it to our list as usual
    (https://github.com/Rust-for-Linux/linux/issues/2). There does not
    seem to be a tracking issue, so I asked upstream about it.

    We will need these two lines as the resolution for the conflict:

        $(RUSTDOC) $(filter-out $(skip_flags) --remap-path-scope=%,$(if $(rustdoc_host),$(rust_common_flags),$(rust_flags))) \

        $(RUSTDOC) --test $(filter-out --remap-path-scope=%,$(rust_flags)) \

  - Reworked the `extract_if` patch to use it (unstably). The feature
    last major change happened in Rust 1.85.0, so that is fine.

  - Moved `$(HOSTRUSTFLAGS)` below so that per-version flags (like
    lints) can be overridden too. Please see the details in the commit
    and my reply to v1.

  - Added `feature(extract_if)` and `feature(non_null_convenience)`
    items to https://github.com/Rust-for-Linux/linux/issues/1223.

    Then reworded the commits accordingly to include the references
    to tracking issues and PRs.

  - Other rewords, e.g. the "beyond" typo.

  - Rebased on top of `rust-next`.

  - Picked up tags.

Alice Ryhl (1):
  rust: declare cfi_encoding for lru_status

Miguel Ojeda (32):
  rust: kbuild: remove `--remap-path-prefix` workarounds
  rust: kbuild: remove "`try` keyword" workaround for `bindgen` < 0.59.2
  rust: kbuild: remove unneeded old `allow`s for generated layout tests
  gpu: nova-core: bindings: remove unneeded `cfg_attr`
  rust: bump Rust minimum supported version to 1.85.0 (Debian Trixie)
  rust: bump Clippy's MSRV and clean `incompatible_msrv` allows
  rust: allow globally `clippy::incompatible_msrv`
  rust: simplify `RUSTC_VERSION` Kconfig conditions
  rust: remove `RUSTC_HAS_SLICE_AS_FLATTENED` and simplify code
  rust: remove `RUSTC_HAS_COERCE_POINTEE` and simplify code
  rust: kbuild: remove skipping of `-Wrustdoc::unescaped_backticks`
  rust: kbuild: remove `feature(...)`s that are now stable
  rust: transmute: simplify code with Rust 1.80.0 `split_at_*checked()`
  rust: alloc: simplify with `NonNull::add()` now that it is stable
  rust: macros: simplify code using `feature(extract_if)`
  rust: block: update `const_refs_to_static` MSRV TODO comment
  rust: bump `bindgen` minimum supported version to 0.71.1 (Debian
    Trixie)
  rust: rust_is_available: remove warning for `bindgen` 0.66.[01]
  rust: rust_is_available: remove warning for `bindgen` < 0.69.5 &&
    libclang >= 19.1
  rust: kbuild: update `bindgen --rust-target` version and replace
    comment
  rust: kbuild: remove "dummy parameter" workaround for `bindgen` <
    0.71.1
  docs: rust: quick-start: openSUSE provides `rust-src` package nowadays
  docs: rust: quick-start: update Ubuntu versioned packages
  docs: rust: quick-start: update minimum Ubuntu version
  docs: rust: quick-start: add Ubuntu 26.04 LTS and remove subsection
    title
  docs: rust: quick-start: remove Gentoo "testing" note
  docs: rust: quick-start: remove Nix "unstable channel" note
  docs: rust: quick-start: remove GDB/Binutils mention
  docs: rust: general-information: simplify Kconfig example
  docs: rust: general-information: use real example
  rust: kbuild: support global per-version flags
  rust: kbuild: allow `clippy::precedence` for Rust < 1.86.0

 .clippy.toml                                  |  2 +-
 Documentation/process/changes.rst             |  4 +-
 Documentation/rust/general-information.rst    |  4 +-
 Documentation/rust/quick-start.rst            | 52 +++++++----------
 Makefile                                      | 12 +++-
 arch/Kconfig                                  |  3 +-
 arch/arm64/Kconfig                            |  8 ---
 arch/riscv/Kconfig                            |  3 -
 drivers/android/binder/Makefile               |  3 +-
 drivers/android/binder/page_range.rs          |  6 +-
 drivers/android/binder/page_range_helper.c    | 24 --------
 drivers/android/binder/page_range_helper.h    | 15 -----
 drivers/gpu/nova-core/gsp/cmdq.rs             |  6 +-
 drivers/gpu/nova-core/gsp/fw/r570_144.rs      |  3 -
 init/Kconfig                                  | 15 +----
 rust/Makefile                                 | 31 ++--------
 rust/bindgen_parameters                       |  8 +--
 rust/bindings/bindings_helper.h               |  1 -
 rust/bindings/lib.rs                          |  5 +-
 rust/kernel/alloc/allocator/iter.rs           |  8 +--
 rust/kernel/alloc/kbox.rs                     | 29 +---------
 rust/kernel/block/mq/gen_disk.rs              |  4 +-
 rust/kernel/lib.rs                            | 30 +---------
 rust/kernel/list/arc.rs                       | 22 +------
 rust/kernel/prelude.rs                        |  3 -
 rust/kernel/ptr.rs                            |  1 -
 rust/kernel/slice.rs                          | 49 ----------------
 rust/kernel/sync/arc.rs                       | 21 +------
 rust/kernel/transmute.rs                      | 35 ++---------
 rust/macros/helpers.rs                        |  1 -
 rust/macros/kunit.rs                          |  9 +--
 rust/macros/lib.rs                            |  3 +
 rust/uapi/lib.rs                              |  5 +-
 scripts/Makefile.build                        |  6 +-
 scripts/min-tool-version.sh                   |  4 +-
 scripts/rust_is_available.sh                  | 36 +-----------
 scripts/rust_is_available_bindgen_0_66.h      |  2 -
 ...ust_is_available_bindgen_libclang_concat.h |  3 -
 scripts/rust_is_available_test.py             | 58 +------------------
 39 files changed, 83 insertions(+), 451 deletions(-)
 delete mode 100644 drivers/android/binder/page_range_helper.c
 delete mode 100644 drivers/android/binder/page_range_helper.h
 delete mode 100644 rust/kernel/slice.rs
 delete mode 100644 scripts/rust_is_available_bindgen_0_66.h
 delete mode 100644 scripts/rust_is_available_bindgen_libclang_concat.h


base-commit: 36f5a2b09e650b82d7b2a106e3b93af48c2010d9
--
2.53.0

^ permalink raw reply

* Re: [PATCH 32/33] rust: kbuild: support global per-version flags
From: Miguel Ojeda @ 2026-04-05 23:15 UTC (permalink / raw)
  To: Gary Guo, Nathan Chancellor, Nicolas Schier
  Cc: Miguel Ojeda, Danilo Krummrich, Andreas Hindborg, Catalin Marinas,
	Will Deacon, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Alexandre Courbot, David Airlie, Simona Vetter, Brendan Higgins,
	David Gow, Greg Kroah-Hartman, Arve Hjønnevåg,
	Todd Kjos, Christian Brauner, Carlos Llamas, Alice Ryhl,
	Jonathan Corbet, Boqun Feng, Björn Roy Baron, Benno Lossin,
	Trevor Gross, rust-for-linux, linux-kbuild, Lorenzo Stoakes,
	Vlastimil Babka, Liam R . Howlett, Uladzislau Rezki, linux-block,
	moderated for non-subscribers, Alexandre Ghiti, linux-riscv,
	nouveau, dri-devel, Rae Moar, linux-kselftest, kunit-dev,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm, linux-kernel,
	Shuah Khan, linux-doc
In-Reply-To: <DHHX9O7V06VZ.G0N1CQ7BUKFO@garyguo.net>

On Thu, Apr 2, 2026 at 12:28 AM Gary Guo <gary@garyguo.net> wrote:
>
> I think I would prefer moving these down.
>
> The current approach append the flags to all variables, which will cause the
> following equivalence to stop holding after the flag update.
>
> KBUILD_HOSTRUSTFLAGS := $(rust_common_flags) -O -Cstrip=debuginfo \
>                         -Zallow-features= $(HOSTRUSTFLAGS)
>
> (Per version flags doesn't go before -O anymore, it comes after HOSTRUSTFLAGS).

[ For context for others, Sashiko reported the same and we also talked
about it in a Rust for Linux call. ]

I have been thinking about this, and about potential other ways to
achieve the same thing. I think the best at the moment is to move just
the `$(HOSTRUSTFLAGS)` below, but not the rest.

The reason is that it is closer to what we do with other user (kernel)
flags (e.g. arch flags come after the general ones). But I am
wondering if we should/could set all the user variables later in the
`Makefile` in general `HOST*FLAGS` later in the `Makefile`.

In fact, there is already a limitation with the host flags: `-Werror`,
i.e. that one gets appended later, and so users cannot override it.

This may be considered a bug, because commit 7ded7d37e5f5
("scripts/Makefile.extrawarn: Respect CONFIG_WERROR / W=e for
hostprogs") says:

    While it is
    possible to avoid this behavior by passing HOSTCFLAGS=-w or
    HOSTCFLAGS=-Wno-error, it may not be the most intuitive for regular
    users not intimately familiar with Kbuild.

But passing `HOSTCFLAGS=-Wno-error` doesn't work, since it comes
earlier (`-w` does work, but because it turns off everything).

I am also a bit confused with:

    While this means there is a small portion of
    the build that does not have -Werror enabled (namely scripts/kconfig/*
    and scripts/basic/fixdep)

because it gets enabled in the build (I think it is referring to other
targets like the config ones).

Anyway, for now I moved the expansion of `HOSTRUSTFLAGS` in v2. If
Kbuild (Nathan, Nicolas) think it is a good idea to do one of the
bigger changes (e.g. for more `HOST*` flags, appending it even later),
then we can do it afterwards.

Cheers,
Miguel

^ permalink raw reply

* Re: [PATCH v6 0/1] mm/damon: add node_eligible_mem_bp and node_ineligible_mem_bp goal metrics
From: SeongJae Park @ 2026-04-05 22:51 UTC (permalink / raw)
  To: Ravi Jonnalagadda
  Cc: SeongJae Park, damon, linux-mm, linux-kernel, linux-doc, akpm,
	corbet, bijan311, ajayjoshi, honggyu.kim, yunjeong.mun
In-Reply-To: <20260405184247.2690-1-ravis.opensrc@gmail.com>

Hello Ravi,

On Sun,  5 Apr 2026 11:42:46 -0700 Ravi Jonnalagadda <ravis.opensrc@gmail.com> wrote:

> Changes since v5:
> =================
> https://lore.kernel.org/linux-mm/20260404012215.1539-1-ravis.opensrc@gmail.com/
> 
> - Rebased onto mm-new instead of damon/next for sashiko review

Thank you for doing this.  sashiko was able to review and find some good
points.  I shared the full review with my opinions as a reply to the patch 1.
Please check and reply.

> - Removed Reported-by/Closes tags per maintainer feedback (not needed
>   for bugs found before merge)
> 
> Changes since v4:
> =================
> https://lore.kernel.org/linux-mm/20260320190453.1430-1-ravis.opensrc@gmail.com/
> 
> - Fixed commit message description for DAMOS_QUOTA_NODE_INELIGIBLE_MEM_BP
>   per review feedback
> - Added clarifying comment for ops-common.h include (for damon_get_folio())
> - Fixed build error when CONFIG_DAMON_PADDR is disabled by adding
>   #ifdef CONFIG_DAMON_PADDR guards around functions using damon_get_folio()
> - Dropped RFC tag per maintainer feedback
> 
> This patch is based on top of mm-new.
> 
> Background and Motivation
> =========================
> 
> In heterogeneous memory systems, controlling memory distribution across
> NUMA nodes is essential for performance optimization. This patch enables
> system-wide page distribution with target-state goals such as "maintain
> 30% of scheme-eligible memory on CXL" using PA-mode DAMON schemes.
> 
> What These Metrics Measure
> ==========================
> 
> node_eligible_mem_bp:
>     scheme_eligible_bytes_on_node / total_scheme_eligible_bytes * 10000
> 
> node_ineligible_mem_bp:
>     (total - scheme_eligible_bytes_on_node) / total * 10000
> 
> These metrics are complementary: eligible_bp + ineligible_bp = 10000 bp.

As I mentioned on sashiko review, I now think node_ineligible_mem_bp is a
confusing name, and thinking a new name, maybe node_eligible_mem_bp_complement
is better.  Let's further discuss on sashiko review reply thread.

> 
> Two-Scheme Setup for Hot Page Distribution
> ==========================================
> 
> For maintaining hot memory on DRAM (node 0) and CXL (node 1) in a 7:3
> ratio:
> 
>     PUSH scheme: migrate_hot from node 0 -> node 1
>       goal: node_ineligible_mem_bp, nid=0, target=3000
>       "Move hot pages from DRAM to CXL if more than 70% of hot data is
>        in DRAM"
> 
>     PULL scheme: migrate_hot from node 1 -> node 0
>       goal: node_eligible_mem_bp, nid=0, target=7000
>       "Move hot pages from CXL to DRAM if less than 70% of hot data is
>        in DRAM"
> 
> The complementary goals create a feedback loop that converges to the
> target distribution.
> 
> Testing Results
> ===============
> 
> Functionally tested on a two-node heterogeneous memory system with DRAM
> (node 0) and CXL memory (node 1). A PUSH+PULL scheme configuration using
> migrate_hot actions was used to reach a target hot memory ratio between
> the two tiers. Testing used the TEMPORAL goal tuner available in
> damon/next and mm-unstable.
> 
> With the TEMPORAL tuner, the system converges quickly to the target
> distribution. The tuner drives esz to maximum when under goal and to
> zero once the goal is met, forming a simple on/off feedback loop that
> stabilizes at the desired ratio.
> 
> With the CONSIST tuner, the scheme still converges but more slowly, as
> it migrates and then throttles itself based on quota feedback. The time
> to reach the goal varies depending on workload intensity.
> 
> Note: These metrics work with both TEMPORAL and CONSIST goal tuners.
> 
> Ravi Jonnalagadda (1):
>   mm/damon: add node_eligible_mem_bp and node_ineligible_mem_bp goal
>     metrics
> 
>  include/linux/damon.h    |   6 ++
>  mm/damon/core.c          | 188 ++++++++++++++++++++++++++++++++++++---
>  mm/damon/sysfs-schemes.c |  12 +++
>  3 files changed, 192 insertions(+), 14 deletions(-)

Btw, having a cover letter for single patch looks odd.  Why don't you add this
cover letter to the patch's commit message?


Thanks,
SJ

[...]

^ permalink raw reply

* Re: (sashiko review) [PATCH v6 1/1] mm/damon: add node_eligible_mem_bp and node_ineligible_mem_bp goal metrics
From: SeongJae Park @ 2026-04-05 22:45 UTC (permalink / raw)
  To: Ravi Jonnalagadda
  Cc: SeongJae Park, damon, linux-mm, linux-kernel, linux-doc, akpm,
	corbet, bijan311, ajayjoshi, honggyu.kim, yunjeong.mun
In-Reply-To: <20260405184247.2690-2-ravis.opensrc@gmail.com>


Ravi, thank you for reposting this patch after the rebase.  This time sashiko
was able to review this, and found good points including things that deserve
another revision of this patch.

Forwarding full sashiko review in a reply format with my inline comments below,
for sharing details of my view and doing followup discussions via mails.  Ravi,
could you please reply?

> # review url: https://sashiko.dev/#/patchset/20260405184247.2690-2-ravis.opensrc@gmail.com
> # start of sashiko.dev inline review
> commit 5f6ea8da06d136b84d97827777acf2b07047d42c
> Author: Ravi Jonnalagadda <ravis.opensrc@gmail.com>
> mm/damon: add node_eligible_mem_bp and node_ineligible_mem_bp goal metrics
> 
> This commit adds quota goal metrics for tracking scheme-eligible and
> ineligible memory distribution across NUMA nodes. It iterates over
> scheme-eligible regions and uses damon_get_folio() to determine placement.
> 
> > diff --git a/mm/damon/core.c b/mm/damon/core.c
> > --- a/mm/damon/core.c
> > +++ b/mm/damon/core.c
> 
> [ ... ]
> 
> > +static unsigned long damos_calc_eligible_bytes(struct damon_ctx *c,
> > +		struct damos *s, int nid, unsigned long *total)
> > +{
> > +	struct damon_target *t;
> > +	struct damon_region *r;
> > +	unsigned long total_eligible = 0;
> > +	unsigned long node_eligible = 0;
> 
> Can total_eligible and node_eligible overflow on 32-bit architectures? 
> Since these accumulators track raw physical bytes, regions spanning multiple
> gigabytes might wrap around the 32-bit unsigned long limit. Would it be
> safer to use u64 or track the counts in pages instead?

Makes sense.  Ravi, could we update these to use phys_addr_t?

> 
> > +
> > +	damon_for_each_target(t, c) {
> > +		damon_for_each_region(r, t) {
> > +			phys_addr_t addr, end_addr;
> > +
> > +			if (!__damos_valid_target(r, s))
> > +				continue;
> 
> Should this loop also check damos_core_filter_out()? By only checking
> __damos_valid_target(), it seems memory explicitly excluded by user-defined
> region filters (like target ID or memcg limits) is still counted as
> eligible, which might inflate the total and affect the quota tuning loop.

No, we intentionally defined "eligible" based on only the access pattern.  We
may be able to extend this to apply filters in future, if we find a use case.
But, for now, I'd suggest keeping this as is for now.

> 
> > +
> > +			/* Convert from core address units to physical bytes */
> > +			addr = r->ar.start * c->addr_unit;
> > +			end_addr = r->ar.end * c->addr_unit;
> > +			while (addr < end_addr) {
> 
> Could this unbounded loop cause CPU soft lockups? Since DAMON regions can
> span hundreds of gigabytes, executing millions of folio lookups sequentially
> without a cond_resched() could monopolize the CPU.

Good point.  Most DAMOS action implementations are also doing cond_resched()
per region.  Ravi, could we add cond_resched() per region to this function,
too?

> 
> > +				struct folio *folio;
> > +				unsigned long folio_sz, counted;
> > +
> > +				folio = damon_get_folio(PHYS_PFN(addr));
> 
> What happens if this metric is assigned to a DAMON context configured for
> virtual address space monitoring? If the context uses DAMON_OPS_VADDR,
> passing a user-space virtual address to PHYS_PFN() might cause invalid
> memory accesses or out-of-bounds page struct reads. Should this code
> explicitly verify the operations type first?

Good finding.  We intend to support only paddr ops.  But there is no guard for
using this on vaddr ops configuration.  Ravi, could we add underlying ops
check?  I think damon_commit_ctx() is a good place to add that.  The check
could be something like below?

'''
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -1515,10 +1515,23 @@ static int damon_commit_sample_control(
 int damon_commit_ctx(struct damon_ctx *dst, struct damon_ctx *src)
 {
        int err;
+       struct damos *scheme;
+       struct damos_quota_goal *goal;

        dst->maybe_corrupted = true;
        if (!is_power_of_2(src->min_region_sz))
                return -EINVAL;
+       if (src->ops.id != DAMON_OPS_PADDR) {
+               damon_for_each_scheme(scheme, src) {
+                       damos_for_each_quota_goal(goal, &scheme->quota) {
+                               switch (goal->metric) {
+                               case DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP:
+                               case DAMOS_QUOTA_NODE_INELIGIBLE_MEMPBP:
+                                       return -EINVAL;
+                               }
+                       }
+               }
+       }

        err = damon_commit_schemes(dst, src);
        if (err)
'''

> 
> > +				if (!folio) {
> > +					addr += PAGE_SIZE;
> > +					continue;
> > +				}
> > +
> > +				folio_sz = folio_size(folio);
> > +				/*
> > +				 * Clip to region boundaries to avoid counting
> > +				 * bytes outside the region when folio spans
> > +				 * region boundaries.
> > +				 */
> > +				counted = min(folio_sz, (unsigned long)(end_addr - addr));
> 
> Does this accurately calculate the remaining bytes if the region starts at an
> unaligned offset within a large folio? folio_size() returns the full size
> of the folio, so this calculation might overestimate the eligible bytes by
> not accounting for the initial offset within the folio.
> 
> > +				total_eligible += counted;
> > +				if (folio_nid(folio) == nid)
> > +					node_eligible += counted;
> > +
> > +				addr += folio_sz;
> 
> Can this pointer advancement overshoot the end of the current folio? If
> addr was unaligned, adding the full folio_sz will skip past the beginning
> of the next contiguous physical memory folio.

Above two points make sense to me.  Ravi, could we fix these?

> 
> > +				folio_put(folio);
> > +			}
> > +		}
> > +	}
> > +
> > +	*total = total_eligible;
> > +	return node_eligible;
> > +}
> 
> [ ... ]
> 
> > +static unsigned long damos_get_node_ineligible_mem_bp(struct damon_ctx *c,
> > +		struct damos *s, int nid)
> > +{
> > +	unsigned long total_eligible = 0;
> > +	unsigned long node_eligible;
> > +
> > +	if (nid < 0 || nid >= MAX_NUMNODES || !node_online(nid))
> > +		return 0;
> > +
> > +	node_eligible = damos_calc_eligible_bytes(c, s, nid, &total_eligible);
> > +
> > +	/* No eligible memory anywhere - ratio is undefined, return 0 */
> > +	if (!total_eligible)
> > +		return 0;
> > +
> > +	/* Compute ineligible ratio directly: 10000 - eligible_bp */
> > +	return 10000 - mult_frac(node_eligible, 10000, total_eligible);
> > +}
> 
> Does this return value match the documented metric? The formula computes the
> percentage of the system's eligible memory located on other NUMA nodes,
> rather than the amount of actual ineligible (filtered out) memory residing
> on the target node. Could this semantic mismatch cause confusion when
> configuring quota policies?

Nice catch.  The name and the documentation are confusing.  We actually
confused a few times in previous revisions, and I'm again confused now.  IIUC,
the current implementation is the intended and right one for the given use
case, though.  If my understanding is correct, how about renaming
DAMOS_QUOTA_NODE_INELIGIBLE_MEM_BP to
DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP_COMPLEMENT, and updating the documentation
together?  Ravi, what do you think?

> 
> 
> # end of sashiko.dev inline review
> # review url: https://sashiko.dev/#/patchset/20260405184247.2690-2-ravis.opensrc@gmail.com


Thanks,
SJ

# hkml [1] generated a draft of this mail.  You can regenerate
# this using below command:
#
#     hkml patch sashiko_dev --for_forwarding \
#             20260405184247.2690-2-ravis.opensrc@gmail.com
#

^ permalink raw reply

* [PATCH net-next v4 3/3] selftests: net: add bridge STP mode selection test
From: Andy Roulin @ 2026-04-05 20:52 UTC (permalink / raw)
  To: netdev
  Cc: bridge, Nikolay Aleksandrov, Ido Schimmel, Andrew Lunn,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Jonathan Corbet, Shuah Khan, Petr Machata,
	Donald Hunter, Jonas Gorski, linux-doc, linux-kselftest,
	linux-kernel, Andy Roulin, Nikolay Aleksandrov
In-Reply-To: <20260405205224.3163000-1-aroulin@nvidia.com>

Add a selftest for the IFLA_BR_STP_MODE bridge attribute that verifies:

1. stp_mode defaults to auto on new bridges
2. stp_mode can be toggled between user, kernel, and auto
3. Changing stp_mode while STP is active is rejected with -EBUSY
4. Re-setting the same stp_mode while STP is active succeeds
5. stp_mode user in a network namespace yields userspace STP (stp_state=2)
6. stp_mode kernel forces kernel STP (stp_state=1)
7. stp_mode auto in a netns preserves traditional fallback to kernel STP
8. stp_mode and stp_state can be set atomically in a single message
9. stp_mode persists across STP disable/enable cycles

Test 5 is the key use case: it demonstrates that userspace STP can now
be enabled in non-init network namespaces by setting stp_mode to user
before enabling STP.

Test 8 verifies the atomic usage pattern where both attributes are set
in a single netlink message, which is supported because br_changelink()
processes IFLA_BR_STP_MODE before IFLA_BR_STP_STATE.

The test gracefully skips if the installed iproute2 does not support
the stp_mode attribute.

Assisted-by: Claude:claude-opus-4-6
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: Andy Roulin <aroulin@nvidia.com>
---

Notes:
    v2:
      * Fix shellcheck CI: add SC2329 suppression.
      * Add idempotent stp_mode test.
    v4:
      * Add disable+mode-change simultaneous test.

 tools/testing/selftests/net/Makefile          |   1 +
 .../testing/selftests/net/bridge_stp_mode.sh  | 288 ++++++++++++++++++
 2 files changed, 289 insertions(+)
 create mode 100755 tools/testing/selftests/net/bridge_stp_mode.sh

diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index 6bced3ed798b0..053c7b83c76dd 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -15,6 +15,7 @@ TEST_PROGS := \
 	big_tcp.sh \
 	bind_bhash.sh \
 	bpf_offload.py \
+	bridge_stp_mode.sh \
 	bridge_vlan_dump.sh \
 	broadcast_ether_dst.sh \
 	broadcast_pmtu.sh \
diff --git a/tools/testing/selftests/net/bridge_stp_mode.sh b/tools/testing/selftests/net/bridge_stp_mode.sh
new file mode 100755
index 0000000000000..0c81fd029d794
--- /dev/null
+++ b/tools/testing/selftests/net/bridge_stp_mode.sh
@@ -0,0 +1,288 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# shellcheck disable=SC2034,SC2154,SC2317,SC2329
+#
+# Test for bridge STP mode selection (IFLA_BR_STP_MODE).
+#
+# Verifies that:
+# - stp_mode defaults to auto on new bridges
+# - stp_mode can be toggled between user, kernel, and auto
+# - stp_mode change is rejected while STP is active (-EBUSY)
+# - stp_mode user in a netns yields userspace STP (stp_state=2)
+# - stp_mode kernel forces kernel STP (stp_state=1)
+# - stp_mode auto preserves traditional fallback to kernel STP
+# - stp_mode and stp_state can be set atomically in one message
+# - stp_mode persists across STP disable/enable cycles
+
+source lib.sh
+
+require_command jq
+
+ALL_TESTS="
+	test_default_auto
+	test_set_modes
+	test_reject_change_while_stp_active
+	test_idempotent_mode_while_stp_active
+	test_user_mode_in_netns
+	test_kernel_mode
+	test_auto_mode
+	test_atomic_mode_and_state
+	test_mode_persistence
+"
+
+bridge_info_get()
+{
+	ip -n "$NS1" -d -j link show "$1" | \
+		jq -r ".[0].linkinfo.info_data.$2"
+}
+
+check_stp_mode()
+{
+	local br=$1; shift
+	local expected=$1; shift
+	local msg=$1; shift
+	local val
+
+	val=$(bridge_info_get "$br" stp_mode)
+	[ "$val" = "$expected" ]
+	check_err $? "$msg: expected $expected, got $val"
+}
+
+check_stp_state()
+{
+	local br=$1; shift
+	local expected=$1; shift
+	local msg=$1; shift
+	local val
+
+	val=$(bridge_info_get "$br" stp_state)
+	[ "$val" = "$expected" ]
+	check_err $? "$msg: expected $expected, got $val"
+}
+
+# Create a bridge in NS1, bring it up, and defer its deletion.
+bridge_create()
+{
+	ip -n "$NS1" link add "$1" type bridge
+	ip -n "$NS1" link set "$1" up
+	defer ip -n "$NS1" link del "$1"
+}
+
+setup_prepare()
+{
+	setup_ns NS1
+}
+
+cleanup()
+{
+	defer_scopes_cleanup
+	cleanup_all_ns
+}
+
+# Check that stp_mode defaults to auto when creating a bridge.
+test_default_auto()
+{
+	RET=0
+
+	ip -n "$NS1" link add br-test type bridge
+	defer ip -n "$NS1" link del br-test
+
+	check_stp_mode br-test auto "stp_mode default"
+
+	log_test "stp_mode defaults to auto"
+}
+
+# Test setting stp_mode to user, kernel, and back to auto.
+test_set_modes()
+{
+	RET=0
+
+	ip -n "$NS1" link add br-test type bridge
+	defer ip -n "$NS1" link del br-test
+
+	ip -n "$NS1" link set dev br-test type bridge stp_mode user
+	check_err $? "Failed to set stp_mode to user"
+	check_stp_mode br-test user "after set user"
+
+	ip -n "$NS1" link set dev br-test type bridge stp_mode kernel
+	check_err $? "Failed to set stp_mode to kernel"
+	check_stp_mode br-test kernel "after set kernel"
+
+	ip -n "$NS1" link set dev br-test type bridge stp_mode auto
+	check_err $? "Failed to set stp_mode to auto"
+	check_stp_mode br-test auto "after set auto"
+
+	log_test "stp_mode set user/kernel/auto"
+}
+
+# Verify that stp_mode cannot be changed while STP is active.
+test_reject_change_while_stp_active()
+{
+	RET=0
+
+	bridge_create br-test
+
+	ip -n "$NS1" link set dev br-test type bridge stp_mode kernel
+	check_err $? "Failed to set stp_mode to kernel"
+
+	ip -n "$NS1" link set dev br-test type bridge stp_state 1
+	check_err $? "Failed to enable STP"
+
+	# Changing stp_mode while STP is active should fail.
+	ip -n "$NS1" link set dev br-test type bridge stp_mode auto 2>/dev/null
+	check_fail $? "Changing stp_mode should fail while STP is active"
+
+	check_stp_mode br-test kernel "mode unchanged after rejected change"
+
+	# Disable STP, then change should succeed.
+	ip -n "$NS1" link set dev br-test type bridge stp_state 0
+	check_err $? "Failed to disable STP"
+
+	ip -n "$NS1" link set dev br-test type bridge stp_mode auto
+	check_err $? "Changing stp_mode should succeed after STP is disabled"
+
+	log_test "reject stp_mode change while STP is active"
+}
+
+# Verify that re-setting the same stp_mode while STP is active succeeds.
+test_idempotent_mode_while_stp_active()
+{
+	RET=0
+
+	bridge_create br-test
+
+	ip -n "$NS1" link set dev br-test type bridge stp_mode user stp_state 1
+	check_err $? "Failed to enable STP with user mode"
+
+	# Re-setting the same mode while STP is active should succeed.
+	ip -n "$NS1" link set dev br-test type bridge stp_mode user
+	check_err $? "Idempotent stp_mode set should succeed while STP is active"
+
+	check_stp_state br-test 2 "stp_state after idempotent set"
+
+	# Changing mode while disabling STP in the same message should succeed.
+	ip -n "$NS1" link set dev br-test type bridge stp_mode auto stp_state 0
+	check_err $? "Mode change with simultaneous STP disable should succeed"
+
+	check_stp_mode br-test auto "mode changed after disable+change"
+	check_stp_state br-test 0 "stp_state after disable+change"
+
+	log_test "idempotent and simultaneous mode change while STP active"
+}
+
+# Test that stp_mode user in a non-init netns yields userspace STP
+# (stp_state == 2). This is the key use case: userspace STP without
+# needing /sbin/bridge-stp or being in init_net.
+test_user_mode_in_netns()
+{
+	RET=0
+
+	bridge_create br-test
+
+	ip -n "$NS1" link set dev br-test type bridge stp_mode user
+	check_err $? "Failed to set stp_mode to user"
+
+	ip -n "$NS1" link set dev br-test type bridge stp_state 1
+	check_err $? "Failed to enable STP"
+
+	check_stp_state br-test 2 "stp_state with user mode"
+
+	log_test "stp_mode user in netns yields userspace STP"
+}
+
+# Test that stp_mode kernel forces kernel STP (stp_state == 1)
+# regardless of whether /sbin/bridge-stp exists.
+test_kernel_mode()
+{
+	RET=0
+
+	bridge_create br-test
+
+	ip -n "$NS1" link set dev br-test type bridge stp_mode kernel
+	check_err $? "Failed to set stp_mode to kernel"
+
+	ip -n "$NS1" link set dev br-test type bridge stp_state 1
+	check_err $? "Failed to enable STP"
+
+	check_stp_state br-test 1 "stp_state with kernel mode"
+
+	log_test "stp_mode kernel forces kernel STP"
+}
+
+# Test that stp_mode auto preserves traditional behavior: in a netns
+# (non-init_net), bridge-stp is not called and STP falls back to
+# kernel mode (stp_state == 1).
+test_auto_mode()
+{
+	RET=0
+
+	bridge_create br-test
+
+	# Auto mode is the default; enable STP in a netns.
+	ip -n "$NS1" link set dev br-test type bridge stp_state 1
+	check_err $? "Failed to enable STP"
+
+	# In a netns with auto mode, bridge-stp is skipped (init_net only),
+	# so STP should fall back to kernel mode (stp_state == 1).
+	check_stp_state br-test 1 "stp_state with auto mode in netns"
+
+	log_test "stp_mode auto preserves traditional behavior"
+}
+
+# Test that stp_mode and stp_state can be set in a single netlink
+# message. This is the intended atomic usage pattern.
+test_atomic_mode_and_state()
+{
+	RET=0
+
+	bridge_create br-test
+
+	# Set both stp_mode and stp_state in one command.
+	ip -n "$NS1" link set dev br-test type bridge stp_mode user stp_state 1
+	check_err $? "Failed to set stp_mode user and stp_state 1 atomically"
+
+	check_stp_state br-test 2 "stp_state after atomic set"
+
+	log_test "atomic stp_mode user + stp_state 1 in single message"
+}
+
+# Test that stp_mode persists across STP disable/enable cycles.
+test_mode_persistence()
+{
+	RET=0
+
+	bridge_create br-test
+
+	# Set user mode and enable STP.
+	ip -n "$NS1" link set dev br-test type bridge stp_mode user
+	ip -n "$NS1" link set dev br-test type bridge stp_state 1
+	check_err $? "Failed to enable STP with user mode"
+
+	# Disable STP.
+	ip -n "$NS1" link set dev br-test type bridge stp_state 0
+	check_err $? "Failed to disable STP"
+
+	# Verify mode is still user.
+	check_stp_mode br-test user "stp_mode after STP disable"
+
+	# Re-enable STP -- should use user mode again.
+	ip -n "$NS1" link set dev br-test type bridge stp_state 1
+	check_err $? "Failed to re-enable STP"
+
+	check_stp_state br-test 2 "stp_state after re-enable"
+
+	log_test "stp_mode persists across STP disable/enable cycles"
+}
+
+# Check iproute2 support before setting up resources.
+if ! ip link add type bridge help 2>&1 | grep -q "stp_mode"; then
+	echo "SKIP: iproute2 too old, missing stp_mode support"
+	exit "$ksft_skip"
+fi
+
+trap cleanup EXIT
+
+setup_prepare
+tests_run
+
+exit "$EXIT_STATUS"
-- 
2.43.0


^ permalink raw reply related

* [PATCH net-next v4 2/3] docs: net: bridge: document stp_mode attribute
From: Andy Roulin @ 2026-04-05 20:52 UTC (permalink / raw)
  To: netdev
  Cc: bridge, Nikolay Aleksandrov, Ido Schimmel, Andrew Lunn,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Jonathan Corbet, Shuah Khan, Petr Machata,
	Donald Hunter, Jonas Gorski, linux-doc, linux-kselftest,
	linux-kernel, Andy Roulin, Nikolay Aleksandrov
In-Reply-To: <20260405205224.3163000-1-aroulin@nvidia.com>

Add documentation for the IFLA_BR_STP_MODE bridge attribute in the
"User space STP helper" section of the bridge documentation. Reference
the BR_STP_MODE_* values via kernel-doc and describe the use case for
network namespace environments.

Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: Andy Roulin <aroulin@nvidia.com>
---
 Documentation/networking/bridge.rst | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/Documentation/networking/bridge.rst b/Documentation/networking/bridge.rst
index ef8b73e157b26..c1e6ea52c9e59 100644
--- a/Documentation/networking/bridge.rst
+++ b/Documentation/networking/bridge.rst
@@ -148,6 +148,28 @@ called by the kernel when STP is enabled/disabled on a bridge
 stp_state <0|1>``).  The kernel enables user_stp mode if that command returns
 0, or enables kernel_stp mode if that command returns any other value.
 
+STP mode selection
+------------------
+
+The ``IFLA_BR_STP_MODE`` bridge attribute allows explicit control over how
+STP operates when enabled, bypassing the ``/sbin/bridge-stp`` helper
+entirely for the ``user`` and ``kernel`` modes.
+
+.. kernel-doc:: include/uapi/linux/if_link.h
+   :doc: Bridge STP mode values
+
+The default mode is ``BR_STP_MODE_AUTO``, which preserves the traditional
+behavior of invoking the ``/sbin/bridge-stp`` helper. The ``user`` and
+``kernel`` modes are particularly useful in network namespace environments
+where the helper mechanism is not available, as ``call_usermodehelper()``
+is restricted to the initial network namespace.
+
+Example::
+
+  ip link set dev br0 type bridge stp_mode user stp_state 1
+
+The mode can only be changed while STP is disabled.
+
 VLAN
 ====
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH net-next v4 1/3] net: bridge: add stp_mode attribute for STP mode selection
From: Andy Roulin @ 2026-04-05 20:52 UTC (permalink / raw)
  To: netdev
  Cc: bridge, Nikolay Aleksandrov, Ido Schimmel, Andrew Lunn,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Jonathan Corbet, Shuah Khan, Petr Machata,
	Donald Hunter, Jonas Gorski, linux-doc, linux-kselftest,
	linux-kernel, Andy Roulin, Nikolay Aleksandrov
In-Reply-To: <20260405205224.3163000-1-aroulin@nvidia.com>

The bridge-stp usermode helper is currently restricted to the initial
network namespace, preventing userspace STP daemons (e.g. mstpd) from
operating on bridges in other network namespaces. Since commit
ff62198553e4 ("bridge: Only call /sbin/bridge-stp for the initial
network namespace"), bridges in non-init namespaces silently fall
back to kernel STP with no way to use userspace STP.

Add a new bridge attribute IFLA_BR_STP_MODE that allows explicit
per-bridge control over STP mode selection:

  BR_STP_MODE_AUTO (default) - Existing behavior: invoke the
    /sbin/bridge-stp helper in init_net only; fall back to kernel STP
    if it fails or in non-init namespaces.

  BR_STP_MODE_USER - Directly enable userspace STP (BR_USER_STP)
    without invoking the helper. Works in any network namespace.
    Userspace is responsible for ensuring an STP daemon manages the
    bridge.

  BR_STP_MODE_KERNEL - Directly enable kernel STP (BR_KERNEL_STP)
    without invoking the helper.

The mode can only be changed while STP is disabled, or set to the
same value (-EBUSY otherwise). IFLA_BR_STP_MODE is processed before
IFLA_BR_STP_STATE in br_changelink(), so both can be set atomically
in a single netlink message. The mode can also be changed in the
same message that disables STP.

The stp_mode struct field is u8 since all possible values fit, while
NLA_U32 is used for the netlink attribute since it occupies the same
space in the netlink message as NLA_U8.

A new stp_helper_active boolean tracks whether the /sbin/bridge-stp
helper was invoked during br_stp_start(), so that br_stp_stop() only
calls the helper for stop when it was called for start. This avoids
calling the helper asymmetrically when stp_mode changes between
start and stop.

Suggested-by: Ido Schimmel <idosch@nvidia.com>
Assisted-by: Claude:claude-opus-4-6
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: Andy Roulin <aroulin@nvidia.com>
---

Notes:
    v2:
      * Add rt-link.yaml netlink spec update.
      * Allow idempotent stp_mode set while STP is active.
      * Move stp_mode next to root_port to fill a struct hole.
      * Rephrase BR_STP_MODE_USER doc.
    v3:
      * Name enum br_stp_mode for YNL codegen.
      * Add enum-name to rt-link.yaml spec.
    v4:
      * Use u8 for stp_mode struct field.
      * Add stp_helper_active bool to track whether the
        usermode helper was invoked during start.
      * Allow mode change when STP is being disabled in the
        same netlink message.

 Documentation/netlink/specs/rt-link.yaml | 12 ++++++++
 include/uapi/linux/if_link.h             | 39 ++++++++++++++++++++++++
 net/bridge/br_device.c                   |  1 +
 net/bridge/br_netlink.c                  | 24 ++++++++++++++-
 net/bridge/br_private.h                  |  2 ++
 net/bridge/br_stp_if.c                   | 19 +++++++-----
 6 files changed, 89 insertions(+), 8 deletions(-)

diff --git a/Documentation/netlink/specs/rt-link.yaml b/Documentation/netlink/specs/rt-link.yaml
index df4b56beb8187..495836a569e8f 100644
--- a/Documentation/netlink/specs/rt-link.yaml
+++ b/Documentation/netlink/specs/rt-link.yaml
@@ -833,6 +833,14 @@ definitions:
     entries:
       - p2p
       - mp
+  -
+    name: br-stp-mode
+    type: enum
+    enum-name: br-stp-mode
+    entries:
+      - auto
+      - user
+      - kernel
 
 attribute-sets:
   -
@@ -1543,6 +1551,10 @@ attribute-sets:
       -
         name: fdb-max-learned
         type: u32
+      -
+        name: stp-mode
+        type: u32
+        enum: br-stp-mode
   -
     name: linkinfo-brport-attrs
     name-prefix: ifla-brport-
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 83a96c56b8cad..f159be39a6e78 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -744,6 +744,11 @@ enum in6_addr_gen_mode {
  * @IFLA_BR_FDB_MAX_LEARNED
  *   Set the number of max dynamically learned FDB entries for the current
  *   bridge.
+ *
+ * @IFLA_BR_STP_MODE
+ *   Set the STP mode for the bridge, which controls how the bridge
+ *   selects between userspace and kernel STP. The valid values are
+ *   documented below in the ``BR_STP_MODE_*`` constants.
  */
 enum {
 	IFLA_BR_UNSPEC,
@@ -796,11 +801,45 @@ enum {
 	IFLA_BR_MCAST_QUERIER_STATE,
 	IFLA_BR_FDB_N_LEARNED,
 	IFLA_BR_FDB_MAX_LEARNED,
+	IFLA_BR_STP_MODE,
 	__IFLA_BR_MAX,
 };
 
 #define IFLA_BR_MAX	(__IFLA_BR_MAX - 1)
 
+/**
+ * DOC: Bridge STP mode values
+ *
+ * @BR_STP_MODE_AUTO
+ *   Default. The kernel invokes the ``/sbin/bridge-stp`` helper to hand
+ *   the bridge to a userspace STP daemon (e.g. mstpd). Only attempted in
+ *   the initial network namespace; in other namespaces this falls back to
+ *   kernel STP.
+ *
+ * @BR_STP_MODE_USER
+ *   Directly enable userspace STP (``BR_USER_STP``) without invoking the
+ *   ``/sbin/bridge-stp`` helper. Works in any network namespace.
+ *   Userspace is responsible for ensuring an STP daemon manages the
+ *   bridge.
+ *
+ * @BR_STP_MODE_KERNEL
+ *   Directly enable kernel STP (``BR_KERNEL_STP``) without invoking the
+ *   helper.
+ *
+ * The mode controls how the bridge selects between userspace and kernel
+ * STP when STP is enabled via ``IFLA_BR_STP_STATE``. It can only be
+ * changed while STP is disabled (``IFLA_BR_STP_STATE`` == 0), returns
+ * ``-EBUSY`` otherwise. The default value is ``BR_STP_MODE_AUTO``.
+ */
+enum br_stp_mode {
+	BR_STP_MODE_AUTO,
+	BR_STP_MODE_USER,
+	BR_STP_MODE_KERNEL,
+	__BR_STP_MODE_MAX
+};
+
+#define BR_STP_MODE_MAX (__BR_STP_MODE_MAX - 1)
+
 struct ifla_bridge_id {
 	__u8	prio[2];
 	__u8	addr[6]; /* ETH_ALEN */
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index f7502e62dd357..a35ceae0a6f2c 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -518,6 +518,7 @@ void br_dev_setup(struct net_device *dev)
 	ether_addr_copy(br->group_addr, eth_stp_addr);
 
 	br->stp_enabled = BR_NO_STP;
+	br->stp_mode = BR_STP_MODE_AUTO;
 	br->group_fwd_mask = BR_GROUPFWD_DEFAULT;
 	br->group_fwd_mask_required = BR_GROUPFWD_DEFAULT;
 
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 0264730938f4b..6fd5386a1d646 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -1270,6 +1270,9 @@ static const struct nla_policy br_policy[IFLA_BR_MAX + 1] = {
 		NLA_POLICY_EXACT_LEN(sizeof(struct br_boolopt_multi)),
 	[IFLA_BR_FDB_N_LEARNED] = { .type = NLA_REJECT },
 	[IFLA_BR_FDB_MAX_LEARNED] = { .type = NLA_U32 },
+	[IFLA_BR_STP_MODE] = NLA_POLICY_RANGE(NLA_U32,
+					      BR_STP_MODE_AUTO,
+					      BR_STP_MODE_MAX),
 };
 
 static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
@@ -1306,6 +1309,23 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
 			return err;
 	}
 
+	if (data[IFLA_BR_STP_MODE]) {
+		u32 mode = nla_get_u32(data[IFLA_BR_STP_MODE]);
+
+		if (mode != br->stp_mode) {
+			bool stp_off = br->stp_enabled == BR_NO_STP ||
+				       (data[IFLA_BR_STP_STATE] &&
+					!nla_get_u32(data[IFLA_BR_STP_STATE]));
+
+			if (!stp_off) {
+				NL_SET_ERR_MSG_MOD(extack,
+						   "Can't change STP mode while STP is enabled");
+				return -EBUSY;
+			}
+		}
+		br->stp_mode = mode;
+	}
+
 	if (data[IFLA_BR_STP_STATE]) {
 		u32 stp_enabled = nla_get_u32(data[IFLA_BR_STP_STATE]);
 
@@ -1634,6 +1654,7 @@ static size_t br_get_size(const struct net_device *brdev)
 	       nla_total_size(sizeof(u8)) +     /* IFLA_BR_NF_CALL_ARPTABLES */
 #endif
 	       nla_total_size(sizeof(struct br_boolopt_multi)) + /* IFLA_BR_MULTI_BOOLOPT */
+	       nla_total_size(sizeof(u32)) +    /* IFLA_BR_STP_MODE */
 	       0;
 }
 
@@ -1686,7 +1707,8 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev)
 	    nla_put(skb, IFLA_BR_MULTI_BOOLOPT, sizeof(bm), &bm) ||
 	    nla_put_u32(skb, IFLA_BR_FDB_N_LEARNED,
 			atomic_read(&br->fdb_n_learned)) ||
-	    nla_put_u32(skb, IFLA_BR_FDB_MAX_LEARNED, br->fdb_max_learned))
+	    nla_put_u32(skb, IFLA_BR_FDB_MAX_LEARNED, br->fdb_max_learned) ||
+	    nla_put_u32(skb, IFLA_BR_STP_MODE, br->stp_mode))
 		return -EMSGSIZE;
 
 #ifdef CONFIG_BRIDGE_VLAN_FILTERING
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 6dbca845e625d..361a9b84451ec 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -523,6 +523,8 @@ struct net_bridge {
 	unsigned char			topology_change;
 	unsigned char			topology_change_detected;
 	u16				root_port;
+	u8				stp_mode;
+	bool				stp_helper_active;
 	unsigned long			max_age;
 	unsigned long			hello_time;
 	unsigned long			forward_delay;
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index cc4b27ff1b088..28c1d3f7e22f6 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -149,7 +149,9 @@ static void br_stp_start(struct net_bridge *br)
 {
 	int err = -ENOENT;
 
-	if (net_eq(dev_net(br->dev), &init_net))
+	/* AUTO mode: try bridge-stp helper in init_net only */
+	if (br->stp_mode == BR_STP_MODE_AUTO &&
+	    net_eq(dev_net(br->dev), &init_net))
 		err = br_stp_call_user(br, "start");
 
 	if (err && err != -ENOENT)
@@ -162,8 +164,9 @@ static void br_stp_start(struct net_bridge *br)
 	else if (br->bridge_forward_delay > BR_MAX_FORWARD_DELAY)
 		__br_set_forward_delay(br, BR_MAX_FORWARD_DELAY);
 
-	if (!err) {
+	if (br->stp_mode == BR_STP_MODE_USER || !err) {
 		br->stp_enabled = BR_USER_STP;
+		br->stp_helper_active = !err;
 		br_debug(br, "userspace STP started\n");
 	} else {
 		br->stp_enabled = BR_KERNEL_STP;
@@ -180,12 +183,14 @@ static void br_stp_start(struct net_bridge *br)
 
 static void br_stp_stop(struct net_bridge *br)
 {
-	int err;
-
 	if (br->stp_enabled == BR_USER_STP) {
-		err = br_stp_call_user(br, "stop");
-		if (err)
-			br_err(br, "failed to stop userspace STP (%d)\n", err);
+		if (br->stp_helper_active) {
+			int err = br_stp_call_user(br, "stop");
+
+			if (err)
+				br_err(br, "failed to stop userspace STP (%d)\n", err);
+			br->stp_helper_active = false;
+		}
 
 		/* To start timers on any ports left in blocking */
 		spin_lock_bh(&br->lock);
-- 
2.43.0


^ permalink raw reply related

* [PATCH net-next v4 0/3] net: bridge: add stp_mode attribute for STP mode selection
From: Andy Roulin @ 2026-04-05 20:52 UTC (permalink / raw)
  To: netdev
  Cc: bridge, Nikolay Aleksandrov, Ido Schimmel, Andrew Lunn,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Jonathan Corbet, Shuah Khan, Petr Machata,
	Donald Hunter, Jonas Gorski, linux-doc, linux-kselftest,
	linux-kernel, Andy Roulin

The bridge-stp usermode helper is currently restricted to the initial
network namespace, preventing userspace STP daemons like mstpd from
operating on bridges in other namespaces. Since commit ff62198553e4
("bridge: Only call /sbin/bridge-stp for the initial network
namespace"), bridges in non-init namespaces silently fall back to
kernel STP with no way to request userspace STP.

This series adds a new IFLA_BR_STP_MODE bridge attribute that allows
explicit per-bridge control over STP mode selection. Three modes are
supported:

  - auto (default): existing behavior, try /sbin/bridge-stp in
    init_net, fall back to kernel STP otherwise
  - user: directly enable BR_USER_STP without invoking the helper,
    works in any network namespace
  - kernel: directly enable BR_KERNEL_STP without invoking the helper

The user and kernel modes bypass call_usermodehelper() entirely,
addressing the security concerns discussed at [1]. Userspace is
responsible for ensuring an STP daemon manages the bridge, rather
than relying on the kernel to invoke /sbin/bridge-stp.

Patch 1 adds the kernel support. The mode can only be changed while
STP is disabled and is processed before IFLA_BR_STP_STATE in
br_changelink() so both can be set atomically in a single netlink
message.

Patch 2 adds documentation for the new attribute in the bridge docs.

Patch 3 adds a selftest with 9 test cases. The test requires iproute2
with IFLA_BR_STP_MODE support and can be run with virtme-ng:

  vng --run arch/x86/boot/bzImage --skip-modules \
      --overlay-rwdir /sbin --overlay-rwdir /tmp --overlay-rwdir /bin \
      --exec 'cp /path/to/iproute2-next/ip/ip /bin/ip && \
              cd tools/testing/selftests/net && \
              bash bridge_stp_mode.sh'

iproute2 support can be found here [2].

[1] https://lore.kernel.org/netdev/565B7F7D.80208@nod.at/
[2] https://github.com/aroulin/iproute2-next/tree/bridge-stp-mode

v4:
        Patch #1:
                * Use u8 for stp_mode struct field.
                * Add stp_helper_active bool to track whether the
                  usermode helper was invoked during start.
                * Allow mode change when STP is being disabled in
                  the same netlink message.
        Patch #3:
                * Add disable+mode-change simultaneous test.
v3:
        Patch #1:
                * Name enum br_stp_mode for YNL codegen.
                * Add enum-name to rt-link.yaml spec.
v2:
        Patch #1:
                * Add rt-link.yaml netlink spec update.
                * Allow idempotent stp_mode set while STP is active.
                * Move stp_mode next to root_port to fill a struct
                  hole.
                * Rephrase BR_STP_MODE_USER doc.
        Patch #3:
                * Fix shellcheck CI: add SC2329 suppression.
                * Add idempotent stp_mode test.

Suggested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Andy Roulin <aroulin@nvidia.com>

Andy Roulin (3):
  net: bridge: add stp_mode attribute for STP mode selection
  docs: net: bridge: document stp_mode attribute
  selftests: net: add bridge STP mode selection test

 Documentation/netlink/specs/rt-link.yaml      |  12 +
 Documentation/networking/bridge.rst           |  22 ++
 include/uapi/linux/if_link.h                  |  39 +++
 net/bridge/br_device.c                        |   1 +
 net/bridge/br_netlink.c                       |  24 +-
 net/bridge/br_private.h                       |   2 +
 net/bridge/br_stp_if.c                        |  19 +-
 tools/testing/selftests/net/Makefile          |   1 +
 .../testing/selftests/net/bridge_stp_mode.sh  | 288 ++++++++++++++++++
 9 files changed, 400 insertions(+), 8 deletions(-)
 create mode 100755 tools/testing/selftests/net/bridge_stp_mode.sh

--
2.43.0


^ permalink raw reply

* Re: [PATCH 23/33] docs: rust: quick-start: update Ubuntu versioned packages
From: Miguel Ojeda @ 2026-04-05 19:35 UTC (permalink / raw)
  To: Tamir Duberstein
  Cc: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Trevor Gross, rust-for-linux,
	linux-kbuild, Lorenzo Stoakes, Vlastimil Babka, Liam R . Howlett,
	Uladzislau Rezki, linux-block, linux-arm-kernel, Alexandre Ghiti,
	linux-riscv, nouveau, dri-devel, Rae Moar, linux-kselftest,
	kunit-dev, Nick Desaulniers, Bill Wendling, Justin Stitt, llvm,
	linux-kernel, Shuah Khan, linux-doc
In-Reply-To: <177508434465.73816.4492182082440539007.b4-review@b4>

On Thu, Apr 2, 2026 at 1:01 AM Tamir Duberstein <tamird@kernel.org> wrote:
>
> RUST_LIB_SRC is also mentioned in the nix section, do you know if it is
> still needed there?

Yeah, that would be nice to know.

I tried on my own, and it does seem still required (at least with
those packages mentioned in the example). But perhaps a Nix user knows
of a better way to do it, anyway.

So I kept it.

By the way, I think it would be nice to have a "standard",
well-maintained `shell.nix` (or a flake or whatever is best nowadays)
in the kernel tree somewhere, i.e. one that is known to work, that
covers most tooling used in the kernel, etc.

Cheers,
Miguel

^ permalink raw reply

* Re: (sashiko review) [RFC PATCH v2 3/9] Docs/mm/damon/design: document fail_charge_{num,denom}
From: SeongJae Park @ 2026-04-05 19:34 UTC (permalink / raw)
  To: SeongJae Park; +Cc: damon, linux-doc, linux-kernel, linux-mm
In-Reply-To: <20260405151232.102690-4-sj@kernel.org>

TL; DR: sashiko gave me a sounds-good suggestion.  I will make a change on the
next revision of this patch.

Forwarding full sashiko review in a reply format with my inline
comments below, for sharing details of my view and doing
followup discussions via mails if needed.

> # review url: https://sashiko.dev/#/patchset/20260405151232.102690-4-sj@kernel.org
> # start of sashiko.dev inline review
> commit c4d090b9bc99178548ec06da52d6f75e0b392a34
> Author: SeongJae Park <sj@kernel.org>
> 
> Docs/mm/damon/design: document fail_charge_{num,denom}
> 
> Update the DAMON design document to describe the new fail_charge_num and
> fail_charge_denom parameters. These parameters configure the DAMOS action
> failed region quota charge ratio.
> 
> > diff --git a/Documentation/mm/damon/design.rst b/Documentation/mm/damon/design.rst
> > index afc7d52bda2f7..8a8b04b5e8537 100644
> > --- a/Documentation/mm/damon/design.rst
> > +++ b/Documentation/mm/damon/design.rst
> > @@ -565,6 +565,27 @@ interface <sysfs_interface>`, refer to :ref:`weights <sysfs_quotas>` part of
> >  the documentation.
> >  
> >  
> > +.. _damon_design_damos_quotas_failed_memory_charging_ratio:
> > +
> > +Action-failed Memory Charging Ratio
> > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > +
> > +DAMOS action to a given region can fail for some subsets of the memory of the
> > +region.  For example, if the action is ``pageout`` and the region has some
> > +unreclaimable pages, applying the action to the pages will fail.  The amount of
> > +system resource that is taken for such failed action applications is usually
> > +different from that for successful action applications.  For such cases, users
> > +can set different charging ratio for such failed memory.  The ratio can be
> > +specified using ``fail_charge_num`` and ``fail_charge_denom`` parameters.  The
> > +two parameters represent the numerator and denominator of the ratio.
> 
> Should this documentation include the fallback and default behavior when
> fail_charge_denom is set to 0?
> 
> Looking at the core kernel implementation in
> mm/damon/core.c:damos_charge_quota(), the code checks for
> !quota->fail_charge_denom and falls back to charging the entire region size to
> avoid a division-by-zero error.
> 
> Additionally, since struct damon_sysfs_quotas is allocated using kzalloc(),
> fail_charge_denom is 0 by default. Would it be helpful to explain this default
> 0 state and the resulting fallback behavior here?

Good suggestion, I will add that.

> 
> > +
> > +For example, let's suppose a DAMOS action is applied to a region of 1,000 MiB
> > +size.  The action is successfully applied to only 700 MiB of the region.
> > +``fail_charge_num`` and ``fail_charge_denom`` are set to ``1`` and ``1024``,
> > +respectively.  Then only 700 MiB and 300 KiB of size (``700 MiB + 300 MiB * 1 /
> > +1024``) will be charged.
> > +
> 
> [ ... ]
> 
> 
> # end of sashiko.dev inline review
> # review url: https://sashiko.dev/#/patchset/20260405151232.102690-4-sj@kernel.org


Thanks,
SJ

# hkml [1] generated a draft of this mail.  You can regenerate
# this using below command:
#
#     hkml patch sashiko_dev --for_forwarding \
#             20260405151232.102690-4-sj@kernel.org
#
# [1] https://github.com/sjp38/hackermail

^ permalink raw reply

* Re: [PATCH 20/33] rust: kbuild: remove unneeded old `allow`s for generated layout tests
From: Miguel Ojeda @ 2026-04-05 19:31 UTC (permalink / raw)
  To: Tamir Duberstein
  Cc: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Trevor Gross, rust-for-linux,
	linux-kbuild, Lorenzo Stoakes, Vlastimil Babka, Liam R . Howlett,
	Uladzislau Rezki, linux-block, linux-arm-kernel, Alexandre Ghiti,
	linux-riscv, nouveau, dri-devel, Rae Moar, linux-kselftest,
	kunit-dev, Nick Desaulniers, Bill Wendling, Justin Stitt, llvm,
	linux-kernel, Shuah Khan, linux-doc
In-Reply-To: <177508434460.73816.4231801886718165891.b4-review@b4>

On Thu, Apr 2, 2026 at 1:01 AM Tamir Duberstein <tamird@kernel.org> wrote:
>
> How about ordering this, the previous patch, and the next patch ahead of
> the version bump to avoid the need to mention it here?

That is reasonable, yeah.

Cheers,
Miguel

^ permalink raw reply

* Re: [PATCH 17/33] rust: kbuild: update `bindgen --rust-target` version and replace comment
From: Miguel Ojeda @ 2026-04-05 19:31 UTC (permalink / raw)
  To: Tamir Duberstein
  Cc: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Trevor Gross, rust-for-linux,
	linux-kbuild, Lorenzo Stoakes, Vlastimil Babka, Liam R . Howlett,
	Uladzislau Rezki, linux-block, linux-arm-kernel, Alexandre Ghiti,
	linux-riscv, nouveau, dri-devel, Rae Moar, linux-kselftest,
	kunit-dev, Nick Desaulniers, Bill Wendling, Justin Stitt, llvm,
	linux-kernel, Shuah Khan, linux-doc
In-Reply-To: <177508434455.73816.15756486388132647025.b4-review@b4>

On Thu, Apr 2, 2026 at 1:00 AM Tamir Duberstein <tamird@kernel.org> wrote:
>
> Some citations pointing to the upstream changes would be good.

I added a couple links as usual, plus a reference to commit
7a5f93ea5862 ("rust: kbuild: set `bindgen`'s Rust target version")
that has most of the details.

[ The comment already mentioned the version, and the commit that added
that message has the details, but I agree it is a good idea to add
some references. ]

Cheers,
Miguel

^ permalink raw reply

* Re: [PATCH 11/33] rust: alloc: simplify with `NonNull::add()` now that it is stable
From: Miguel Ojeda @ 2026-04-05 19:31 UTC (permalink / raw)
  To: Tamir Duberstein
  Cc: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Trevor Gross, rust-for-linux,
	linux-kbuild, Lorenzo Stoakes, Vlastimil Babka, Liam R . Howlett,
	Uladzislau Rezki, linux-block, linux-arm-kernel, Alexandre Ghiti,
	linux-riscv, nouveau, dri-devel, Rae Moar, linux-kselftest,
	kunit-dev, Nick Desaulniers, Bill Wendling, Justin Stitt, llvm,
	linux-kernel, Shuah Khan, linux-doc
In-Reply-To: <177508434445.73816.7873322235592463050.b4-review@b4>

On Thu, Apr 2, 2026 at 1:00 AM Tamir Duberstein <tamird@kernel.org> wrote:
>
> This description is inconsistent with the previous one which had
> citations for both the feature (function in this case) and the feature
> in which it became stable (available in this case). I don't prefer
> either style in particular, just that things are consistent.

Sure, I added a couple references. I think it is good to be consistent
(well, at least within a patch series, but I wouldn't say no to more
information even if it is inconsistent sometimes, especially across
different patch series, since everyone writes messages a bit
differently...).

Cheers,
Miguel

^ permalink raw reply

* Re: [PATCH] docs: use acknowledgment in submitting-patches
From: Krzysztof Kozlowski @ 2026-04-05 19:30 UTC (permalink / raw)
  To: CaoRuichuang, corbet; +Cc: skhan, workflows, linux-doc, linux-kernel
In-Reply-To: <20260405183602.73797-1-create0818@163.com>

On 05/04/2026 20:36, CaoRuichuang wrote:
> Signed-off-by: CaoRuichuang <create0818@163.com>
> ---
>  Documentation/process/submitting-patches.rst | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/process/submitting-patches.rst b/Documentation/process/submitting-patches.rst
> index e69d19a..5c44be9 100644
> --- a/Documentation/process/submitting-patches.rst
> +++ b/Documentation/process/submitting-patches.rst
> @@ -486,9 +486,9 @@ reviewed it as thoroughly as if a Reviewed-by: was provided.  Similarly, a key
>  user may not have carried out a technical review of the patch, yet they may be
>  satisfied with the general approach, the feature or the user-facing interface.
>  
> -Acked-by: does not necessarily indicate acknowledgement of the entire patch.
> +Acked-by: does not necessarily indicate acknowledgment of the entire patch.

Pointless change. You are replacing one correct spelling with another
correct one. And your commit msg is empty...

Please run scripts/checkpatch.pl on the patches and fix reported
warnings. After that, run also 'scripts/checkpatch.pl --strict' on the
patches and (probably) fix more warnings. Some warnings can be ignored,
especially from --strict run, but the code here looks like it needs a
fix. Feel free to get in touch if the warning is not clear.

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH 10/33] rust: transmute: simplify code with Rust 1.80.0 `split_at_*checked()`
From: Miguel Ojeda @ 2026-04-05 19:29 UTC (permalink / raw)
  To: Tamir Duberstein
  Cc: Miguel Ojeda, Nathan Chancellor, Nicolas Schier, Danilo Krummrich,
	Andreas Hindborg, Catalin Marinas, Will Deacon, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, Alexandre Courbot, David Airlie,
	Simona Vetter, Brendan Higgins, David Gow, Greg Kroah-Hartman,
	Arve Hjønnevåg, Todd Kjos, Christian Brauner,
	Carlos Llamas, Alice Ryhl, Jonathan Corbet, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Trevor Gross, rust-for-linux,
	linux-kbuild, Lorenzo Stoakes, Vlastimil Babka, Liam R . Howlett,
	Uladzislau Rezki, linux-block, linux-arm-kernel, Alexandre Ghiti,
	linux-riscv, nouveau, dri-devel, Rae Moar, linux-kselftest,
	kunit-dev, Nick Desaulniers, Bill Wendling, Justin Stitt, llvm,
	linux-kernel, Shuah Khan, linux-doc
In-Reply-To: <177508434443.73816.5437391869400189147.b4-review@b4>

On Thu, Apr 2, 2026 at 1:00 AM Tamir Duberstein <tamird@kernel.org> wrote:
>
> "beyond" is probably not the right word here?

I think you are right -- reworded.

Thanks!

Cheers,
Miguel

^ permalink raw reply

* [PATCH v6 1/1] mm/damon: add node_eligible_mem_bp and node_ineligible_mem_bp goal metrics
From: Ravi Jonnalagadda @ 2026-04-05 18:42 UTC (permalink / raw)
  To: sj, damon, linux-mm, linux-kernel, linux-doc
  Cc: akpm, corbet, bijan311, ajayjoshi, honggyu.kim, yunjeong.mun,
	ravis.opensrc
In-Reply-To: <20260405184247.2690-1-ravis.opensrc@gmail.com>

Add new quota goal metrics for memory tiering that track scheme-eligible
memory distribution across NUMA nodes:

- DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP: ratio of eligible memory on a node
- DAMOS_QUOTA_NODE_INELIGIBLE_MEM_BP: ratio of ineligible memory on a
  node

These complementary metrics enable push-pull migration schemes that
maintain a target memory distribution across different NUMA nodes
representing different memory tiers, based on access patterns defined
by each scheme.

The metrics iterate scheme-eligible regions and use damon_get_folio()
to determine NUMA node placement of each folio, calculating the ratio
of eligible memory on the specified node versus total eligible memory.

The implementation is guarded by CONFIG_DAMON_PADDR since damon_get_folio()
is only available when physical address space monitoring is enabled.

Suggested-by: SeongJae Park <sj@kernel.org>
Signed-off-by: Ravi Jonnalagadda <ravis.opensrc@gmail.com>
---
 include/linux/damon.h    |   6 ++
 mm/damon/core.c          | 188 ++++++++++++++++++++++++++++++++++++---
 mm/damon/sysfs-schemes.c |  12 +++
 3 files changed, 192 insertions(+), 14 deletions(-)

diff --git a/include/linux/damon.h b/include/linux/damon.h
index f2cdb7c3f5e6..a268f44beabf 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -159,6 +159,10 @@ enum damos_action {
  * @DAMOS_QUOTA_NODE_MEMCG_FREE_BP:	MemFree ratio of a node for a cgroup.
  * @DAMOS_QUOTA_ACTIVE_MEM_BP:		Active to total LRU memory ratio.
  * @DAMOS_QUOTA_INACTIVE_MEM_BP:	Inactive to total LRU memory ratio.
+ * @DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP:	Scheme-eligible memory ratio of a
+ *					node.
+ * @DAMOS_QUOTA_NODE_INELIGIBLE_MEM_BP:	Scheme-ineligible memory ratio of a
+ *					node.
  * @NR_DAMOS_QUOTA_GOAL_METRICS:	Number of DAMOS quota goal metrics.
  *
  * Metrics equal to larger than @NR_DAMOS_QUOTA_GOAL_METRICS are unsupported.
@@ -172,6 +176,8 @@ enum damos_quota_goal_metric {
 	DAMOS_QUOTA_NODE_MEMCG_FREE_BP,
 	DAMOS_QUOTA_ACTIVE_MEM_BP,
 	DAMOS_QUOTA_INACTIVE_MEM_BP,
+	DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP,
+	DAMOS_QUOTA_NODE_INELIGIBLE_MEM_BP,
 	NR_DAMOS_QUOTA_GOAL_METRICS,
 };
 
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 3bc7a2bbfe7d..bac810f740c3 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -17,6 +17,9 @@
 #include <linux/string.h>
 #include <linux/string_choices.h>
 
+/* for damon_get_folio() used by node eligible memory metrics */
+#include "ops-common.h"
+
 #define CREATE_TRACE_POINTS
 #include <trace/events/damon.h>
 
@@ -2282,7 +2285,136 @@ static unsigned long damos_get_node_memcg_used_bp(
 		numerator = i.totalram - used_pages;
 	return mult_frac(numerator, 10000, i.totalram);
 }
-#else
+
+#ifdef CONFIG_DAMON_PADDR
+/*
+ * damos_calc_eligible_bytes() - Calculate raw eligible bytes per node.
+ * @c:		The DAMON context.
+ * @s:		The scheme.
+ * @nid:	The target NUMA node id.
+ * @total:	Output for total eligible bytes across all nodes.
+ *
+ * Iterates through each folio in eligible regions to accurately determine
+ * which node the memory resides on. Returns eligible bytes on the specified
+ * node and sets *total to the sum across all nodes.
+ *
+ * Note: This function requires damon_get_folio() from ops-common.c, which is
+ * only available when CONFIG_DAMON_PADDR or CONFIG_DAMON_VADDR is enabled.
+ */
+static unsigned long damos_calc_eligible_bytes(struct damon_ctx *c,
+		struct damos *s, int nid, unsigned long *total)
+{
+	struct damon_target *t;
+	struct damon_region *r;
+	unsigned long total_eligible = 0;
+	unsigned long node_eligible = 0;
+
+	damon_for_each_target(t, c) {
+		damon_for_each_region(r, t) {
+			phys_addr_t addr, end_addr;
+
+			if (!__damos_valid_target(r, s))
+				continue;
+
+			/* Convert from core address units to physical bytes */
+			addr = r->ar.start * c->addr_unit;
+			end_addr = r->ar.end * c->addr_unit;
+			while (addr < end_addr) {
+				struct folio *folio;
+				unsigned long folio_sz, counted;
+
+				folio = damon_get_folio(PHYS_PFN(addr));
+				if (!folio) {
+					addr += PAGE_SIZE;
+					continue;
+				}
+
+				folio_sz = folio_size(folio);
+				/*
+				 * Clip to region boundaries to avoid counting
+				 * bytes outside the region when folio spans
+				 * region boundaries.
+				 */
+				counted = min(folio_sz, (unsigned long)(end_addr - addr));
+				total_eligible += counted;
+				if (folio_nid(folio) == nid)
+					node_eligible += counted;
+
+				addr += folio_sz;
+				folio_put(folio);
+			}
+		}
+	}
+
+	*total = total_eligible;
+	return node_eligible;
+}
+
+/*
+ * damos_get_node_eligible_mem_bp() - Get eligible memory ratio for a node.
+ * @c:		The DAMON context.
+ * @s:		The scheme.
+ * @nid:	The target NUMA node id.
+ *
+ * Calculates scheme-eligible bytes on the specified node and returns the
+ * ratio in basis points (0-10000) relative to total eligible bytes across
+ * all nodes.
+ */
+static unsigned long damos_get_node_eligible_mem_bp(struct damon_ctx *c,
+		struct damos *s, int nid)
+{
+	unsigned long total_eligible = 0;
+	unsigned long node_eligible = 0;
+
+	if (nid < 0 || nid >= MAX_NUMNODES || !node_online(nid))
+		return 0;
+
+	node_eligible = damos_calc_eligible_bytes(c, s, nid, &total_eligible);
+
+	if (!total_eligible)
+		return 0;
+
+	return mult_frac(node_eligible, 10000, total_eligible);
+}
+
+static unsigned long damos_get_node_ineligible_mem_bp(struct damon_ctx *c,
+		struct damos *s, int nid)
+{
+	unsigned long total_eligible = 0;
+	unsigned long node_eligible;
+
+	if (nid < 0 || nid >= MAX_NUMNODES || !node_online(nid))
+		return 0;
+
+	node_eligible = damos_calc_eligible_bytes(c, s, nid, &total_eligible);
+
+	/* No eligible memory anywhere - ratio is undefined, return 0 */
+	if (!total_eligible)
+		return 0;
+
+	/* Compute ineligible ratio directly: 10000 - eligible_bp */
+	return 10000 - mult_frac(node_eligible, 10000, total_eligible);
+}
+#else /* CONFIG_DAMON_PADDR */
+/*
+ * Stub functions when CONFIG_DAMON_PADDR is disabled.
+ * The node_eligible/ineligible metrics require physical address operations
+ * to iterate folios, which are only available with PA-mode DAMON.
+ */
+static unsigned long damos_get_node_eligible_mem_bp(struct damon_ctx *c,
+		struct damos *s, int nid)
+{
+	return 0;
+}
+
+static unsigned long damos_get_node_ineligible_mem_bp(struct damon_ctx *c,
+		struct damos *s, int nid)
+{
+	return 0;
+}
+#endif /* CONFIG_DAMON_PADDR */
+
+#else /* CONFIG_NUMA */
 static __kernel_ulong_t damos_get_node_mem_bp(
 		struct damos_quota_goal *goal)
 {
@@ -2294,7 +2426,19 @@ static unsigned long damos_get_node_memcg_used_bp(
 {
 	return 0;
 }
-#endif
+
+static unsigned long damos_get_node_eligible_mem_bp(struct damon_ctx *c,
+		struct damos *s, int nid)
+{
+	return 0;
+}
+
+static unsigned long damos_get_node_ineligible_mem_bp(struct damon_ctx *c,
+		struct damos *s, int nid)
+{
+	return 0;
+}
+#endif /* CONFIG_NUMA */
 
 /*
  * Returns LRU-active or inactive memory to total LRU memory size ratio.
@@ -2314,7 +2458,8 @@ static unsigned int damos_get_in_active_mem_bp(bool active_ratio)
 	return mult_frac(inactive, 10000, total);
 }
 
-static void damos_set_quota_goal_current_value(struct damos_quota_goal *goal)
+static void damos_set_quota_goal_current_value(struct damon_ctx *c,
+		struct damos *s, struct damos_quota_goal *goal)
 {
 	u64 now_psi_total;
 
@@ -2340,19 +2485,28 @@ static void damos_set_quota_goal_current_value(struct damos_quota_goal *goal)
 		goal->current_value = damos_get_in_active_mem_bp(
 				goal->metric == DAMOS_QUOTA_ACTIVE_MEM_BP);
 		break;
+	case DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP:
+		goal->current_value = damos_get_node_eligible_mem_bp(c, s,
+				goal->nid);
+		break;
+	case DAMOS_QUOTA_NODE_INELIGIBLE_MEM_BP:
+		goal->current_value = damos_get_node_ineligible_mem_bp(c, s,
+				goal->nid);
+		break;
 	default:
 		break;
 	}
 }
 
 /* Return the highest score since it makes schemes least aggressive */
-static unsigned long damos_quota_score(struct damos_quota *quota)
+static unsigned long damos_quota_score(struct damon_ctx *c, struct damos *s)
 {
+	struct damos_quota *quota = &s->quota;
 	struct damos_quota_goal *goal;
 	unsigned long highest_score = 0;
 
 	damos_for_each_quota_goal(goal, quota) {
-		damos_set_quota_goal_current_value(goal);
+		damos_set_quota_goal_current_value(c, s, goal);
 		highest_score = max(highest_score,
 				mult_frac(goal->current_value, 10000,
 					goal->target_value));
@@ -2361,17 +2515,20 @@ static unsigned long damos_quota_score(struct damos_quota *quota)
 	return highest_score;
 }
 
-static void damos_goal_tune_esz_bp_consist(struct damos_quota *quota)
+static void damos_goal_tune_esz_bp_consist(struct damon_ctx *c, struct damos *s)
 {
-	unsigned long score = damos_quota_score(quota);
+	struct damos_quota *quota = &s->quota;
+	unsigned long score = damos_quota_score(c, s);
 
 	quota->esz_bp = damon_feed_loop_next_input(
 			max(quota->esz_bp, 10000UL), score);
 }
 
-static void damos_goal_tune_esz_bp_temporal(struct damos_quota *quota)
+static void damos_goal_tune_esz_bp_temporal(struct damon_ctx *c,
+		struct damos *s)
 {
-	unsigned long score = damos_quota_score(quota);
+	struct damos_quota *quota = &s->quota;
+	unsigned long score = damos_quota_score(c, s);
 
 	if (score >= 10000)
 		quota->esz_bp = 0;
@@ -2384,8 +2541,9 @@ static void damos_goal_tune_esz_bp_temporal(struct damos_quota *quota)
 /*
  * Called only if quota->ms, or quota->sz are set, or quota->goals is not empty
  */
-static void damos_set_effective_quota(struct damos_quota *quota)
+static void damos_set_effective_quota(struct damon_ctx *c, struct damos *s)
 {
+	struct damos_quota *quota = &s->quota;
 	unsigned long throughput;
 	unsigned long esz = ULONG_MAX;
 
@@ -2396,9 +2554,9 @@ static void damos_set_effective_quota(struct damos_quota *quota)
 
 	if (!list_empty(&quota->goals)) {
 		if (quota->goal_tuner == DAMOS_QUOTA_GOAL_TUNER_CONSIST)
-			damos_goal_tune_esz_bp_consist(quota);
+			damos_goal_tune_esz_bp_consist(c, s);
 		else if (quota->goal_tuner == DAMOS_QUOTA_GOAL_TUNER_TEMPORAL)
-			damos_goal_tune_esz_bp_temporal(quota);
+			damos_goal_tune_esz_bp_temporal(c, s);
 		esz = quota->esz_bp / 10000;
 	}
 
@@ -2445,7 +2603,9 @@ static void damos_adjust_quota(struct damon_ctx *c, struct damos *s)
 	/* First charge window */
 	if (!quota->total_charged_sz && !quota->charged_from) {
 		quota->charged_from = jiffies;
-		damos_set_effective_quota(quota);
+		damos_set_effective_quota(c, s);
+		if (trace_damos_esz_enabled())
+			damos_trace_esz(c, s, quota);
 	}
 
 	/* New charge window starts */
@@ -2460,7 +2620,7 @@ static void damos_adjust_quota(struct damon_ctx *c, struct damos *s)
 		quota->charged_sz = 0;
 		if (trace_damos_esz_enabled())
 			cached_esz = quota->esz;
-		damos_set_effective_quota(quota);
+		damos_set_effective_quota(c, s);
 		if (trace_damos_esz_enabled() && quota->esz != cached_esz)
 			damos_trace_esz(c, s, quota);
 	}
diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c
index 5186966dafb3..aade681b4868 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -1084,6 +1084,14 @@ struct damos_sysfs_qgoal_metric_name damos_sysfs_qgoal_metric_names[] = {
 		.metric = DAMOS_QUOTA_INACTIVE_MEM_BP,
 		.name = "inactive_mem_bp",
 	},
+	{
+		.metric = DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP,
+		.name = "node_eligible_mem_bp",
+	},
+	{
+		.metric = DAMOS_QUOTA_NODE_INELIGIBLE_MEM_BP,
+		.name = "node_ineligible_mem_bp",
+	},
 };
 
 static ssize_t target_metric_show(struct kobject *kobj,
@@ -2655,6 +2663,10 @@ static int damos_sysfs_add_quota_score(
 		case DAMOS_QUOTA_NODE_MEM_FREE_BP:
 			goal->nid = sysfs_goal->nid;
 			break;
+		case DAMOS_QUOTA_NODE_ELIGIBLE_MEM_BP:
+		case DAMOS_QUOTA_NODE_INELIGIBLE_MEM_BP:
+			goal->nid = sysfs_goal->nid;
+			break;
 		case DAMOS_QUOTA_NODE_MEMCG_USED_BP:
 		case DAMOS_QUOTA_NODE_MEMCG_FREE_BP:
 			err = damon_sysfs_memcg_path_to_id(
-- 
2.43.0


^ permalink raw reply related

* [PATCH v6 0/1] mm/damon: add node_eligible_mem_bp and node_ineligible_mem_bp goal metrics
From: Ravi Jonnalagadda @ 2026-04-05 18:42 UTC (permalink / raw)
  To: sj, damon, linux-mm, linux-kernel, linux-doc
  Cc: akpm, corbet, bijan311, ajayjoshi, honggyu.kim, yunjeong.mun,
	ravis.opensrc

Changes since v5:
=================
https://lore.kernel.org/linux-mm/20260404012215.1539-1-ravis.opensrc@gmail.com/

- Rebased onto mm-new instead of damon/next for sashiko review
- Removed Reported-by/Closes tags per maintainer feedback (not needed
  for bugs found before merge)

Changes since v4:
=================
https://lore.kernel.org/linux-mm/20260320190453.1430-1-ravis.opensrc@gmail.com/

- Fixed commit message description for DAMOS_QUOTA_NODE_INELIGIBLE_MEM_BP
  per review feedback
- Added clarifying comment for ops-common.h include (for damon_get_folio())
- Fixed build error when CONFIG_DAMON_PADDR is disabled by adding
  #ifdef CONFIG_DAMON_PADDR guards around functions using damon_get_folio()
- Dropped RFC tag per maintainer feedback

This patch is based on top of mm-new.

Background and Motivation
=========================

In heterogeneous memory systems, controlling memory distribution across
NUMA nodes is essential for performance optimization. This patch enables
system-wide page distribution with target-state goals such as "maintain
30% of scheme-eligible memory on CXL" using PA-mode DAMON schemes.

What These Metrics Measure
==========================

node_eligible_mem_bp:
    scheme_eligible_bytes_on_node / total_scheme_eligible_bytes * 10000

node_ineligible_mem_bp:
    (total - scheme_eligible_bytes_on_node) / total * 10000

These metrics are complementary: eligible_bp + ineligible_bp = 10000 bp.

Two-Scheme Setup for Hot Page Distribution
==========================================

For maintaining hot memory on DRAM (node 0) and CXL (node 1) in a 7:3
ratio:

    PUSH scheme: migrate_hot from node 0 -> node 1
      goal: node_ineligible_mem_bp, nid=0, target=3000
      "Move hot pages from DRAM to CXL if more than 70% of hot data is
       in DRAM"

    PULL scheme: migrate_hot from node 1 -> node 0
      goal: node_eligible_mem_bp, nid=0, target=7000
      "Move hot pages from CXL to DRAM if less than 70% of hot data is
       in DRAM"

The complementary goals create a feedback loop that converges to the
target distribution.

Testing Results
===============

Functionally tested on a two-node heterogeneous memory system with DRAM
(node 0) and CXL memory (node 1). A PUSH+PULL scheme configuration using
migrate_hot actions was used to reach a target hot memory ratio between
the two tiers. Testing used the TEMPORAL goal tuner available in
damon/next and mm-unstable.

With the TEMPORAL tuner, the system converges quickly to the target
distribution. The tuner drives esz to maximum when under goal and to
zero once the goal is met, forming a simple on/off feedback loop that
stabilizes at the desired ratio.

With the CONSIST tuner, the scheme still converges but more slowly, as
it migrates and then throttles itself based on quota feedback. The time
to reach the goal varies depending on workload intensity.

Note: These metrics work with both TEMPORAL and CONSIST goal tuners.

Ravi Jonnalagadda (1):
  mm/damon: add node_eligible_mem_bp and node_ineligible_mem_bp goal
    metrics

 include/linux/damon.h    |   6 ++
 mm/damon/core.c          | 188 ++++++++++++++++++++++++++++++++++++---
 mm/damon/sysfs-schemes.c |  12 +++
 3 files changed, 192 insertions(+), 14 deletions(-)


base-commit: b47b4fa4c232ee36aae58630e9d6520e35d33f3a
-- 
2.43.0


^ permalink raw reply

* [PATCH] docs: use acknowledgment in submitting-patches
From: CaoRuichuang @ 2026-04-05 18:36 UTC (permalink / raw)
  To: corbet; +Cc: skhan, workflows, linux-doc, linux-kernel, CaoRuichuang

Signed-off-by: CaoRuichuang <create0818@163.com>
---
 Documentation/process/submitting-patches.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/process/submitting-patches.rst b/Documentation/process/submitting-patches.rst
index e69d19a..5c44be9 100644
--- a/Documentation/process/submitting-patches.rst
+++ b/Documentation/process/submitting-patches.rst
@@ -486,9 +486,9 @@ reviewed it as thoroughly as if a Reviewed-by: was provided.  Similarly, a key
 user may not have carried out a technical review of the patch, yet they may be
 satisfied with the general approach, the feature or the user-facing interface.
 
-Acked-by: does not necessarily indicate acknowledgement of the entire patch.
+Acked-by: does not necessarily indicate acknowledgment of the entire patch.
 For example, if a patch affects multiple subsystems and has an Acked-by: from
-one subsystem maintainer then this usually indicates acknowledgement of just
+one subsystem maintainer then this usually indicates acknowledgment of just
 the part which affects that maintainer's code.  Judgement should be used here.
 When in doubt people should refer to the original discussion in the mailing
 list archives.  A "# Suffix" may also be used in this case to clarify.
-- 
2.39.5 (Apple Git-154)


^ permalink raw reply related

* Re: [PATCH v3 02/24] PCI: Add API to track PCI devices preserved across Live Update
From: Zhu Yanjun @ 2026-04-05 16:56 UTC (permalink / raw)
  To: David Matlack, yanjun.zhu@linux.dev
  Cc: Alex Williamson, Bjorn Helgaas, Adithya Jayachandran,
	Alexander Graf, Alex Mastro, Andrew Morton, Ankit Agrawal,
	Arnd Bergmann, Askar Safin, Borislav Petkov (AMD), Chris Li,
	Dapeng Mi, David Rientjes, Feng Tang, Jacob Pan, Jason Gunthorpe,
	Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Kees Cook,
	Kevin Tian, kexec, kvm, Leon Romanovsky, Leon Romanovsky,
	linux-doc, linux-kernel, linux-kselftest, linux-mm, linux-pci,
	Li RongQing, Lukas Wunner, Marco Elver, Michał Winiarski,
	Mike Rapoport, Parav Pandit, Pasha Tatashin, Paul E. McKenney,
	Pawan Gupta, Peter Zijlstra (Intel), Pranjal Shrivastava,
	Pratyush Yadav, Raghavendra Rao Ananta, Randy Dunlap,
	Rodrigo Vivi, Saeed Mahameed, Samiullah Khawaja, Shuah Khan,
	Vipin Sharma, Vivek Kasireddy, William Tu, Yi Liu
In-Reply-To: <CALzav=eyf4XRTi8MfE_GBNSm+tjmfX7=d0M8Aj5Hh0vJn7huew@mail.gmail.com>


在 2026/4/3 14:58, David Matlack 写道:
> On Thu, Apr 2, 2026 at 2:29 PM Yanjun.Zhu <yanjun.zhu@linux.dev> wrote:
>> On 3/23/26 4:57 PM, David Matlack wrote:
>>> +config PCI_LIVEUPDATE
>>> +     bool "PCI Live Update Support (EXPERIMENTAL)"
>>> +     depends on PCI && LIVEUPDATE
>>> +     help
>>> +       Support for preserving PCI devices across a Live Update. This option
>>> +       should only be enabled by developers working on implementing this
>>> +       support. Once enough support as landed in the kernel, this option
>>> +       will no longer be marked EXPERIMENTAL.
>>> +
>>> +       If unsure, say N.
>> Currently, it only supports 'n' or 'y'. Is it possible to add 'm'
>> (modular support)?
>>
>> This would allow the feature to be built as a kernel module. For
>> development
>>
>> purposes, modularization means we only need to recompile a single module
>>
>> for testing, rather than rebuilding the entire kernel. Compiling a
>> module should
>>
>> be significantly faster than a full kernel build.
> I don't think it is possible for CONFIG_PCI_LIVEUPDATE to support 'm'.
> pci_setup_device() (which is under CONFIG_PCI) needs to call
> pci_liveupdate_setup_device(), and CONFIG_PCI cannot be built as a
> module. This call is necessary so the PCI core knows whether a device
> being enumerated was preserved across a previous Live Update.

After the following changes, the liveupdate.ko can be generated 
successfully.

"

# ls drivers/pci/liveupdate.ko
drivers/pci/liveupdate.ko
"


diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig

index 05307d89c3f4..e172c31b33fa 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -335,7 +335,7 @@ config VGA_ARB_MAX_GPUS
           multiple GPUS.  The overhead for each GPU is very small.

  config PCI_LIVEUPDATE
-       bool "PCI Live Update Support (EXPERIMENTAL)"
+       tristate "PCI Live Update Support (EXPERIMENTAL)"
         depends on PCI && LIVEUPDATE
         help
           Support for preserving PCI devices across a Live Update. This 
option
diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
index c1251f4f8438..71bab8ecba85 100644
--- a/drivers/pci/liveupdate.c
+++ b/drivers/pci/liveupdate.c
@@ -413,3 +413,26 @@ void pci_liveupdate_unregister_flb(struct 
liveupdate_file_handler *fh)
         liveupdate_unregister_flb(fh, &pci_liveupdate_flb);
  }
  EXPORT_SYMBOL_GPL(pci_liveupdate_unregister_flb);
+
+extern void (*pci_liveupdate_setup_device_hook)(struct pci_dev *dev);
+extern u32 (*pci_liveupdate_incoming_nr_devices_hook)(void);
+static int __init liveupdate_module_init(void)
+{
+       pci_liveupdate_setup_device_hook = pci_liveupdate_setup_device;
+       pci_liveupdate_incoming_nr_devices_hook = 
pci_liveupdate_incoming_nr_devices;
+       pr_info("loaded\n");
+       return 0;
+}
+
+static void __exit liveupdate_module_exit(void)
+{
+       pci_liveupdate_setup_device_hook = NULL;
+       pci_liveupdate_incoming_nr_devices_hook = NULL;
+       pr_info("unloaded\n");
+}
+
+module_init(liveupdate_module_init);
+module_exit(liveupdate_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PCI Live Update Support");
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 979cb9921340..93f76500cb0d 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -1434,18 +1434,12 @@ static inline int pci_msix_write_tph_tag(struct 
pci_dev *pdev, unsigned int inde
         (PCI_CONF1_ADDRESS(bus, dev, func, reg) | \
          PCI_CONF1_EXT_REG(reg))

-#ifdef CONFIG_PCI_LIVEUPDATE
+#if IS_ENABLED(CONFIG_PCI_LIVEUPDATE)
  void pci_liveupdate_setup_device(struct pci_dev *dev);
-u32 pci_liveupdate_incoming_nr_devices(void);
  #else
  static inline void pci_liveupdate_setup_device(struct pci_dev *dev)
  {
  }
-
-static inline u32 pci_liveupdate_incoming_nr_devices(void)
-{
-       return 0;
-}
  #endif

  #endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 165056d71e66..4880302bca43 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1369,6 +1369,9 @@ bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 
*sec, u8 *sub)
         return true;
  }

+u32 (*pci_liveupdate_incoming_nr_devices_hook)(void) = NULL;
+EXPORT_SYMBOL_GPL(pci_liveupdate_incoming_nr_devices_hook);
+
  static bool pci_assign_all_busses(void)
  {
         if (!pcibios_assign_all_busses())
@@ -1389,7 +1392,7 @@ static bool pci_assign_all_busses(void)
          * numbers during the initial cold boot, and then that topology 
would
          * then remain fixed across any subsequent Live Updates.
          */
-       if (pci_liveupdate_incoming_nr_devices()) {
+       if (pci_liveupdate_incoming_nr_devices_hook && 
pci_liveupdate_incoming_nr_devices_hook()) {
                 pr_info_once("Ignoring pci=assign-busses and inheriting 
bus numbers during Live Update\n");
                 return false;
         }
@@ -2030,6 +2033,9 @@ static const char *pci_type_str(struct pci_dev *dev)
         }
  }

+void (*pci_liveupdate_setup_device_hook)(struct pci_dev *dev) = NULL;
+EXPORT_SYMBOL_GPL(pci_liveupdate_setup_device_hook);
+
  /**
   * pci_setup_device - Fill in class and map information of a device
   * @dev: the device structure to fill
@@ -2091,7 +2097,8 @@ int pci_setup_device(struct pci_dev *dev)
         if (pci_early_dump)
                 early_dump_pci_device(dev);

-       pci_liveupdate_setup_device(dev);
+       if (pci_liveupdate_setup_device_hook)
+               pci_liveupdate_setup_device_hook(dev);

         /* Need to have dev->class ready */
         dev->cfg_size = pci_cfg_space_size(dev);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 27ee9846a2fd..aaab6adb487e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -592,7 +592,7 @@ struct pci_dev {
         u8              tph_mode;       /* TPH mode */
         u8              tph_req_type;   /* TPH requester type */
  #endif
-#ifdef CONFIG_PCI_LIVEUPDATE
+#if IS_ENABLED(CONFIG_PCI_LIVEUPDATE)
         unsigned int    liveupdate_incoming:1;  /* Preserved by 
previous kernel */
         unsigned int    liveupdate_outgoing:1;  /* Preserved for next 
kernel */
  #endif
@@ -2876,7 +2876,7 @@ void pci_uevent_ers(struct pci_dev *pdev, enum  
pci_ers_result err_type);
         WARN_ONCE(condition, "%s %s: " fmt, \
                   dev_driver_string(&(pdev)->dev), pci_name(pdev), ##arg)

-#ifdef CONFIG_PCI_LIVEUPDATE
+#if IS_ENABLED(CONFIG_PCI_LIVEUPDATE)
  int pci_liveupdate_preserve(struct pci_dev *dev);
  void pci_liveupdate_unpreserve(struct pci_dev *dev);
  int pci_liveupdate_retrieve(struct pci_dev *dev);
diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c
index 874830f8e44d..33fbdc6c417c 100644
--- a/kernel/liveupdate/luo_flb.c
+++ b/kernel/liveupdate/luo_flb.c
@@ -461,7 +461,7 @@ int liveupdate_register_flb(struct 
liveupdate_file_handler *fh,

         return 0;
  }
-
+EXPORT_SYMBOL_GPL(liveupdate_register_flb);
  /**
   * liveupdate_unregister_flb - Remove an FLB dependency from a file 
handler.
   * @fh:   The file handler that is currently depending on the FLB.
@@ -487,7 +487,7 @@ void liveupdate_unregister_flb(struct 
liveupdate_file_handler *fh,

         luo_flb_unregister_one(fh, flb);
  }
-
+EXPORT_SYMBOL_GPL(liveupdate_unregister_flb);
  /**
   * liveupdate_flb_get_incoming - Retrieve the incoming FLB object.
   * @flb:  The FLB definition.
@@ -525,7 +525,7 @@ int liveupdate_flb_get_incoming(struct 
liveupdate_flb *flb, void **objp)

         return 0;
  }
-
+EXPORT_SYMBOL_GPL(liveupdate_flb_get_incoming);
  /**
   * liveupdate_flb_get_outgoing - Retrieve the outgoing FLB object.
   * @flb:  The FLB definition.
@@ -552,6 +552,7 @@ int liveupdate_flb_get_outgoing(struct 
liveupdate_flb *flb, void **objp)

         return 0;
  }
+EXPORT_SYMBOL_GPL(liveupdate_flb_get_outgoing);

  int __init luo_flb_setup_outgoing(void *fdt_out)
  {

-- 
Best Regards,
Yanjun.Zhu


^ permalink raw reply related

* [PATCH v1] Documentation/rtla: Convert links to RST format
From: Costa Shulyupin @ 2026-04-05 16:38 UTC (permalink / raw)
  To: Steven Rostedt, Tomas Glozar, Jonathan Corbet, Shuah Khan,
	linux-trace-kernel, linux-kernel, linux-doc
  Cc: Costa Shulyupin

Web links in the documentation are not properly displayed.

In the man pages web links look like:
  Osnoise tracer  documentation:  <  <https://www.kernel.org/doc/html/lat‐
  est/trace/osnoise-tracer.html> >

On web pages the URL caption is the URL itself.

Convert tracer documentation links to RST anonymous hyperlink format
for better rendering. Use newer docs.kernel.org instead of
www.kernel.org/doc/html/latest for brevity.

After the change, the links in the man pages look like:
  Osnoise tracer <https://docs.kernel.org/trace/osnoise-tracer.html>

On web pages the captions are the titles of the links.

Signed-off-by: Costa Shulyupin <costa.shul@redhat.com>
---
 Documentation/tools/rtla/rtla-hwnoise.rst       | 2 +-
 Documentation/tools/rtla/rtla-osnoise-hist.rst  | 2 +-
 Documentation/tools/rtla/rtla-osnoise-top.rst   | 2 +-
 Documentation/tools/rtla/rtla-osnoise.rst       | 2 +-
 Documentation/tools/rtla/rtla-timerlat-hist.rst | 2 +-
 Documentation/tools/rtla/rtla-timerlat-top.rst  | 2 +-
 Documentation/tools/rtla/rtla-timerlat.rst      | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/Documentation/tools/rtla/rtla-hwnoise.rst b/Documentation/tools/rtla/rtla-hwnoise.rst
index 26512b15fe7b..5930bbca4522 100644
--- a/Documentation/tools/rtla/rtla-hwnoise.rst
+++ b/Documentation/tools/rtla/rtla-hwnoise.rst
@@ -100,7 +100,7 @@ SEE ALSO
 
 **rtla-osnoise**\(1)
 
-Osnoise tracer documentation: <https://www.kernel.org/doc/html/latest/trace/osnoise-tracer.html>
+`Osnoise tracer <https://docs.kernel.org/trace/osnoise-tracer.html>`__
 
 AUTHOR
 ======
diff --git a/Documentation/tools/rtla/rtla-osnoise-hist.rst b/Documentation/tools/rtla/rtla-osnoise-hist.rst
index 007521c865d9..6ddea2c6d490 100644
--- a/Documentation/tools/rtla/rtla-osnoise-hist.rst
+++ b/Documentation/tools/rtla/rtla-osnoise-hist.rst
@@ -59,7 +59,7 @@ SEE ALSO
 ========
 **rtla-osnoise**\(1), **rtla-osnoise-top**\(1)
 
-*osnoise* tracer documentation: <https://www.kernel.org/doc/html/latest/trace/osnoise-tracer.html>
+`Osnoise tracer <https://docs.kernel.org/trace/osnoise-tracer.html>`__
 
 AUTHOR
 ======
diff --git a/Documentation/tools/rtla/rtla-osnoise-top.rst b/Documentation/tools/rtla/rtla-osnoise-top.rst
index 6ccadae38945..b91c02ac2bbe 100644
--- a/Documentation/tools/rtla/rtla-osnoise-top.rst
+++ b/Documentation/tools/rtla/rtla-osnoise-top.rst
@@ -54,7 +54,7 @@ SEE ALSO
 
 **rtla-osnoise**\(1), **rtla-osnoise-hist**\(1)
 
-Osnoise tracer documentation: <https://www.kernel.org/doc/html/latest/trace/osnoise-tracer.html>
+`Osnoise tracer <https://docs.kernel.org/trace/osnoise-tracer.html>`__
 
 AUTHOR
 ======
diff --git a/Documentation/tools/rtla/rtla-osnoise.rst b/Documentation/tools/rtla/rtla-osnoise.rst
index 540d2bf6c152..decd9e11fcf2 100644
--- a/Documentation/tools/rtla/rtla-osnoise.rst
+++ b/Documentation/tools/rtla/rtla-osnoise.rst
@@ -50,7 +50,7 @@ SEE ALSO
 ========
 **rtla-osnoise-top**\(1), **rtla-osnoise-hist**\(1)
 
-Osnoise tracer documentation: <https://www.kernel.org/doc/html/latest/trace/osnoise-tracer.html>
+`Osnoise tracer <https://docs.kernel.org/trace/osnoise-tracer.html>`__
 
 AUTHOR
 ======
diff --git a/Documentation/tools/rtla/rtla-timerlat-hist.rst b/Documentation/tools/rtla/rtla-timerlat-hist.rst
index f56fe546411b..dab75677b06e 100644
--- a/Documentation/tools/rtla/rtla-timerlat-hist.rst
+++ b/Documentation/tools/rtla/rtla-timerlat-hist.rst
@@ -104,7 +104,7 @@ SEE ALSO
 ========
 **rtla-timerlat**\(1), **rtla-timerlat-top**\(1)
 
-*timerlat* tracer documentation: <https://www.kernel.org/doc/html/latest/trace/timerlat-tracer.html>
+`Timerlat tracer <https://docs.kernel.org/trace/timerlat-tracer.html>`__
 
 AUTHOR
 ======
diff --git a/Documentation/tools/rtla/rtla-timerlat-top.rst b/Documentation/tools/rtla/rtla-timerlat-top.rst
index 72d85e36c193..05959f1a4661 100644
--- a/Documentation/tools/rtla/rtla-timerlat-top.rst
+++ b/Documentation/tools/rtla/rtla-timerlat-top.rst
@@ -127,7 +127,7 @@ SEE ALSO
 --------
 **rtla-timerlat**\(1), **rtla-timerlat-hist**\(1)
 
-*timerlat* tracer documentation: <https://www.kernel.org/doc/html/latest/trace/timerlat-tracer.html>
+`Timerlat tracer <https://docs.kernel.org/trace/timerlat-tracer.html>`__
 
 AUTHOR
 ------
diff --git a/Documentation/tools/rtla/rtla-timerlat.rst b/Documentation/tools/rtla/rtla-timerlat.rst
index ce9f57e038c3..63718c52aa3f 100644
--- a/Documentation/tools/rtla/rtla-timerlat.rst
+++ b/Documentation/tools/rtla/rtla-timerlat.rst
@@ -45,7 +45,7 @@ SEE ALSO
 ========
 **rtla-timerlat-top**\(1), **rtla-timerlat-hist**\(1)
 
-*timerlat* tracer documentation: <https://www.kernel.org/doc/html/latest/trace/timerlat-tracer.html>
+`Timerlat tracer <https://docs.kernel.org/trace/timerlat-tracer.html>`__
 
 AUTHOR
 ======
-- 
2.53.0


^ permalink raw reply related

* [RFC PATCH v2 4/9] Docs/admin-guide/mm/damon/usage: document fail_charge_{num,denom} files
From: SeongJae Park @ 2026-04-05 15:12 UTC (permalink / raw)
  Cc: SeongJae Park, Liam R. Howlett, Andrew Morton, David Hildenbrand,
	Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
	Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
	linux-kernel, linux-mm
In-Reply-To: <20260405151232.102690-1-sj@kernel.org>

Update DAMON usage document for the DAMOS action failed regions quota
charge ratio control sysfs files.

Signed-off-by: SeongJae Park <sj@kernel.org>
---
 Documentation/admin-guide/mm/damon/usage.rst | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/Documentation/admin-guide/mm/damon/usage.rst b/Documentation/admin-guide/mm/damon/usage.rst
index bfdb717441f05..d5548e460857c 100644
--- a/Documentation/admin-guide/mm/damon/usage.rst
+++ b/Documentation/admin-guide/mm/damon/usage.rst
@@ -84,7 +84,9 @@ comma (",").
     │ │ │ │ │ │ │ │ sz/min,max
     │ │ │ │ │ │ │ │ nr_accesses/min,max
     │ │ │ │ │ │ │ │ age/min,max
-    │ │ │ │ │ │ │ :ref:`quotas <sysfs_quotas>`/ms,bytes,reset_interval_ms,effective_bytes,goal_tuner
+    │ │ │ │ │ │ │ :ref:`quotas <sysfs_quotas>`/ms,bytes,reset_interval_ms,
+    │ │ │ │ │ │ │     effective_bytes,goal_tuner,
+    │ │ │ │ │ │ │     fail_charge_num,fail_charge_denom
     │ │ │ │ │ │ │ │ weights/sz_permil,nr_accesses_permil,age_permil
     │ │ │ │ │ │ │ │ :ref:`goals <sysfs_schemes_quota_goals>`/nr_goals
     │ │ │ │ │ │ │ │ │ 0/target_metric,target_value,current_value,nid,path
@@ -381,9 +383,10 @@ schemes/<N>/quotas/
 The directory for the :ref:`quotas <damon_design_damos_quotas>` of the given
 DAMON-based operation scheme.
 
-Under ``quotas`` directory, five files (``ms``, ``bytes``,
-``reset_interval_ms``, ``effective_bytes`` and ``goal_tuner``) and two
-directories (``weights`` and ``goals``) exist.
+Under ``quotas`` directory, seven files (``ms``, ``bytes``,
+``reset_interval_ms``, ``effective_bytes``, ``goal_tuner``, ``fail_charge_num``
+and ``fail_charge_denom``) and two directories (``weights`` and ``goals``)
+exist.
 
 You can set the ``time quota`` in milliseconds, ``size quota`` in bytes, and
 ``reset interval`` in milliseconds by writing the values to the three files,
@@ -402,6 +405,13 @@ the background design of the feature and the name of the selectable algorithms.
 Refer to :ref:`goals directory <sysfs_schemes_quota_goals>` for the goals
 setup.
 
+You can set the action-failed memory quota charging ratio by writing the
+numerator and the denominator for the ratio to ``fail_charge_num`` and
+``fail_charge_denom`` files, respectively.  Reading those files will return the
+current set values.  Refer to :ref:`design
+<damon_design_damos_quotas_failed_memory_charging_ratio>` for more details of
+the ratio feature.
+
 The time quota is internally transformed to a size quota.  Between the
 transformed size quota and user-specified size quota, smaller one is applied.
 Based on the user-specified :ref:`goal <sysfs_schemes_quota_goals>`, the
-- 
2.47.3

^ permalink raw reply related

* [RFC PATCH v2 3/9] Docs/mm/damon/design: document fail_charge_{num,denom}
From: SeongJae Park @ 2026-04-05 15:12 UTC (permalink / raw)
  Cc: SeongJae Park, Liam R. Howlett, Andrew Morton, David Hildenbrand,
	Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
	Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
	linux-kernel, linux-mm
In-Reply-To: <20260405151232.102690-1-sj@kernel.org>

Update DAMON design document for the DAMOS action failed region quota
charge ratio.

Signed-off-by: SeongJae Park <sj@kernel.org>
---
 Documentation/mm/damon/design.rst | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/Documentation/mm/damon/design.rst b/Documentation/mm/damon/design.rst
index 510ec6375178d..3ea9c81b756c8 100644
--- a/Documentation/mm/damon/design.rst
+++ b/Documentation/mm/damon/design.rst
@@ -572,6 +572,27 @@ interface <sysfs_interface>`, refer to :ref:`weights <sysfs_quotas>` part of
 the documentation.
 
 
+.. _damon_design_damos_quotas_failed_memory_charging_ratio:
+
+Action-failed Memory Charging Ratio
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+DAMOS action to a given region can fail for some subsets of the memory of the
+region.  For example, if the action is ``pageout`` and the region has some
+unreclaimable pages, applying the action to the pages will fail.  The amount of
+system resource that is taken for such failed action applications is usually
+different from that for successful action applications.  For such cases, users
+can set different charging ratio for such failed memory.  The ratio can be
+specified using ``fail_charge_num`` and ``fail_charge_denom`` parameters.  The
+two parameters represent the numerator and denominator of the ratio.
+
+For example, let's suppose a DAMOS action is applied to a region of 1,000 MiB
+size.  The action is successfully applied to only 700 MiB of the region.
+``fail_charge_num`` and ``fail_charge_denom`` are set to ``1`` and ``1024``,
+respectively.  Then only 700 MiB and 300 KiB of size (``700 MiB + 300 MiB * 1 /
+1024``) will be charged.
+
+
 .. _damon_design_damos_quotas_auto_tuning:
 
 Aim-oriented Feedback-driven Auto-tuning
-- 
2.47.3

^ permalink raw reply related

* [RFC PATCH v2 0/9] mm/damon: introduce DAMOS failed region quota charge ratio
From: SeongJae Park @ 2026-04-05 15:12 UTC (permalink / raw)
  Cc: SeongJae Park, Liam R. Howlett, Andrew Morton, Brendan Higgins,
	David Gow, David Hildenbrand, Jonathan Corbet, Lorenzo Stoakes,
	Michal Hocko, Mike Rapoport, Shuah Khan, Shuah Khan,
	Suren Baghdasaryan, Vlastimil Babka, damon, kunit-dev, linux-doc,
	linux-kernel, linux-kselftest, linux-mm

TL; DR: Let users set different DAMOS quota charge ratios for DAMOS
action failed regions, for deterministic and consistent DAMOS action
progress.

Common Reports: Unexpectedly Slow DAMOS
=======================================

One common issue report that we get from DAMON users is that DAMOS
action applying progress speed is sometimes much slower than expected.
And one common root cause is that the DAMOS quota is exceeded by the
action applying failed memory regions.

For example, a group of users tried to run DAMOS-based proactive memory
reclamation (DAMON_RECLAIM) with 100 MiB per second DAMOS quota.  They
ran it on a system having no active workload which means all memory of
the system is cold.  The expectation was that the system will show 100
MiB per second reclamation until (nearly) all memory is reclaimed. But
what they found is that the speed is quite inconsistent and sometimes it
becomes very slower than the expectation, sometimes even no reclamation
at all for about tens of seconds.  The upper limit of the speed (100 MiB
per second) was being kept as expected, though.

By monitoring the qt_exceeds (number of DAMOS quota exceed events) DAMOS
stat, we found DAMOS quota is always exceeded when the speed is slow. By
monitoring sz_tried and sz_applied (the total amount of DAMOS action
tried memory and succeeded memory) DAMOS stats together, we found the
reclamation attempts nearly always failed when the speed is slow.

DAMOS quota charges DAMOS action tried regions regardless of the
successfulness of the try.  Hence in the example reported case, there
was unreclaimable memory spread around the system memory.  Sometimes
nearly 100 MiB of memory that DAMOS tried to reclaim in the given quota
interval was reclaimable, and therefore showed nearly 100 MiB per second
speed.  Sometimes nearly 99 MiB of memory that DAMOS was trying to
reclaim in the given quota interval was unreclaimable, and therefore
showing only about 1 MiB per second reclaim speed.

We explained it is an expected behavior of the feature rather than a
bug, as DAMOS quota is there for only the upper-limit of the speed.  The
users agreed and later reported a huge win from the adoption of
DAMON_RECLAIM on their products.

It is Not a Bug but a Feature; But...
=====================================

So nothing is broken.  DAMOS quota is working as intended, as the upper
limit of the speed.  It also provides its behavior observability via
DAMOS stat.  In the real world production environment that runs long
term active workloads and matters stability, the speed sometimes being
slow is not a real problem.

But, the non-deterministic behavior is sometimes annoying, especially in
lab environments.  Even in a realistic production environment, when
there is a huge amount of DAMOS action unapplicable memory, the speed
could be problematically slow.  Let's suppose a virtual machines
provider that setup 99% of the host memory as hugetlb pages that cannot
be reclaimed, to give it to virtual machines.  Also, when aim-oriented
DAMOS auto-tuning is applied, this could also make the internal feedback
loop confused.

The intention of the current behavior was that trying DAMOS action to
regions would anyway impose some overhead, and therefore somehow be
charged.  But in the real world, the overhead for failed action is much
lighter than successful action.  Charging those at the same ratio may be
unfair, or at least suboptimum in some environments.

DAMOS Action Failed Region Quota Charge Ratio
=============================================

Let users set the charge ratio for the action-failed memory, for more
optimal and deterministic use of DAMOS.  It allows users to specify the
numerator and the denominator of the ratio for flexible setup.  For
example, let's suppose the numerator and the denominator are set to 1
and 4,096, respectively.  The ratio is 1 / 4,096.  A DAMOS scheme action
is applied to 5 GiB memory.  For 1 GiB of the memory, the action is
succeeded.  For the rest (4 GiB), the action is failed.  Then, only 1
GiB and 1 MiB quota is charged.

The optimal charge ratio will depend on the use case and
system/workload.  I'd recommend starting from setting the nominator as 1
and the denominator as PAGE_SIZE and tune based on the results, because
many DAMOS actions are applied at page level.

Tests
=====

I tested this feature in the steps below.

1. Allocate 50% of system memory and mlock() it using a test program.
2. Fill up the page cache to exhaust nearly all free memory.
3. Start DAMON-based proactive reclamation with 100 MiB/second DAMOS
   hard-quota.  Auto-tune the DAMOS soft-quota under the hard-quota for
   achieving 40% free memory of the system with 'temporal' tuner.

For step 1, I run a simple C program that is written by Gemini.  It is
quite straightforward, so I'm not sharing the code here.

For step 2, I use dd command like below:

   dd if=/dev/zero of=foo bs=1M count=$50_percent_of_system_memory

For step 3, I use the latest version of DAMON user-space tool (damo)
like below.

    sudo damo start --damos_action pageout \
            ` # Do the pageout only up to 100 MiB per second ` \
            --damos_quota_space 100M --damos_quota_interval 1s \
            ` # Auto-tune the quota below the hard quota aiming` \
            ` # 40% free memory of the node 0 ` \
            ` # (entire node of the test system)` \
            --damos_quota_goal node_mem_free_bp 40% 0 \
            ` # use temporal tuner, which is easy to understnd ` \
            --damos_quota_goal_tuner temporal

As expected, the progress of the reclamation is not consistent, because
the quota is exceeded for the failed reclamation of the unreclaimable
memory.

I do this again, but with the failed region charge ratio feature.  For
this, the above 'damo' command is used, after appending command line
option for setup of the charge ratio like below.  Note that the option
was added to 'damo' after v3.1.9.

    sudo ./damo start --damos_action pageout \
            [...]
            ` # quota-charge only 1/4096 for pageout-failed regions ` \
            --damos_quota_fail_charge_ratio 1 4096

The progress of the reclamation was nearly 100 MiB per second until the
goal was achieved, meeting the expectation.

Patches Sequence
================

Patch 1 implements the feature and exposes it via DAMON core API.
Patch 2 implements DAMON sysfs ABI for the feature.  Three following
patches (3-5) document the feature and ABI on design, usage, and ABI
documents, respectively.  Four patches for testing of the new feature
follow.  Patch 6 implements a kunit test for the feature.  Patches 7
and 8 extend DAMON selftest helpers for DAMON sysfs control and internal
state dumping for adding a new selftest for the feature.  Patch 9
extends existing DAMON sysfs interface selftest to test the new feature
using the extended helper scripts.

Changelog
=========

Changes from RFC v1
(https://lore.kernel.org/20260404163943.89278-1-sj@kernel.org)
- Avoid overflows in charge amount calculation.
- Fix/wordsmith documentation for grammar, typo, and wrong examples.
- Improve unit test for more consistent comparison source use.

SeongJae Park (9):
  mm/damon/core: introduce failed region quota charge ratio
  mm/damon/sysfs-schemes: implement fail_charge_{num,denom} files
  Docs/mm/damon/design: document fail_charge_{num,denom}
  Docs/admin-guide/mm/damon/usage: document fail_charge_{num,denom}
    files
  Docs/ABI/damon: document fail_charge_{num,denom}
  mm/damon/tests/core-kunit: test fail_charge_{num,denom} committing
  selftets/damon/_damon_sysfs: support failed region quota charge ratio
  selftests/damon/drgn_dump_damon_status: support failed region quota
    charge ratio
  selftets/damon/sysfs.py: test failed region quota charge ratio

 .../ABI/testing/sysfs-kernel-mm-damon         | 12 +++++
 Documentation/admin-guide/mm/damon/usage.rst  | 18 +++++--
 Documentation/mm/damon/design.rst             | 21 ++++++++
 include/linux/damon.h                         |  9 ++++
 mm/damon/core.c                               | 21 +++++++-
 mm/damon/sysfs-schemes.c                      | 54 +++++++++++++++++++
 mm/damon/tests/core-kunit.h                   |  6 +++
 tools/testing/selftests/damon/_damon_sysfs.py | 21 +++++++-
 .../selftests/damon/drgn_dump_damon_status.py |  2 +
 tools/testing/selftests/damon/sysfs.py        |  6 +++
 10 files changed, 163 insertions(+), 7 deletions(-)


base-commit: 36eed23041e834175ca57dc38ac0e128808b1abb
-- 
2.47.3

^ permalink raw reply

* Re: [PATCH v3 2/2] docs: add advanced search benchmark harness and instrumentation
From: kernel test robot @ 2026-04-05 12:43 UTC (permalink / raw)
  To: Rito Rhymes, corbet, skhan
  Cc: oe-kbuild-all, linux-doc, linux-kernel, Rito Rhymes
In-Reply-To: <20260404073413.32309-3-rito@ritovision.com>

Hi Rito,

kernel test robot noticed the following build warnings:

[auto build test WARNING on lwn/docs-next]
[also build test WARNING on linus/master v7.0-rc6 next-20260403]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Rito-Rhymes/docs-add-advanced-search-for-kernel-documentation/20260405-132032
base:   git://git.lwn.net/linux.git docs-next
patch link:    https://lore.kernel.org/r/20260404073413.32309-3-rito%40ritovision.com
patch subject: [PATCH v3 2/2] docs: add advanced search benchmark harness and instrumentation
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
docutils: docutils (Docutils 0.21.2, Python 3.13.5, on linux)
reproduce: (https://download.01.org/0day-ci/archive/20260405/202604051424.8oinrnwW-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604051424.8oinrnwW-lkp@intel.com/

All warnings (new ones prefixed by >>):

   Warning: Documentation/devicetree/bindings/mfd/motorola-cpcap.txt references a file that doesn't exist: Documentation/devicetree/bindings/rtc/cpcap-rtc.txt
   Warning: Documentation/devicetree/bindings/regulator/siliconmitus,sm5703-regulator.yaml references a file that doesn't exist: Documentation/devicetree/bindings/mfd/siliconmitus,sm5703.yaml
   Warning: Documentation/devicetree/bindings/rtc/motorola,cpcap-rtc.yaml references a file that doesn't exist: Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
   Warning: Documentation/doc-guide/parse-headers.rst references a file that doesn't exist: Documentation/userspace-api/media/Makefile
   Warning: Documentation/leds/leds-lp5812.rst references a file that doesn't exist: Documentation/ABI/testing/sysfs-class-led-multicolor.rst
>> Warning: Documentation/sphinx-static/kernel-search.js references a file that doesn't exist: Documentation/search.html
   Warning: Documentation/translations/it_IT/doc-guide/parse-headers.rst references a file that doesn't exist: Documentation/userspace-api/media/Makefile
   Warning: Documentation/translations/ja_JP/SubmittingPatches references a file that doesn't exist: linux-2.6.12-vanilla/Documentation/dontdiff
   Warning: Documentation/translations/ja_JP/process/submit-checklist.rst references a file that doesn't exist: Documentation/translations/ja_JP/SubmitChecklist
   Warning: Documentation/translations/zh_CN/doc-guide/parse-headers.rst references a file that doesn't exist: Documentation/userspace-api/media/Makefile
   Warning: Documentation/translations/zh_CN/filesystems/gfs2-glocks.rst references a file that doesn't exist: Documentation/filesystems/gfs2-glocks.rst

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH v3 2/2] Documentation: drm: Remove drm_atomic_state rename entry
From: kernel test robot @ 2026-04-05 11:32 UTC (permalink / raw)
  To: Maxime Ripard, David Airlie, Simona Vetter, Maarten Lankhorst,
	Thomas Zimmermann, Jonathan Corbet
  Cc: oe-kbuild-all, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
	Tvrtko Ursulin, Alex Deucher, Christian König, Rob Clark,
	Dmitry Baryshkov, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Dave Stevenson, Laurent Pinchart, dri-devel, linux-doc,
	Maxime Ripard, Luca Ceresoli
In-Reply-To: <20260402-drm-drm-atomic-update-v3-2-b826f51ac511@kernel.org>

Hi Maxime,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 9bdbf7eb25b3121ef19533df4fb70f2c39fc0d6a]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxime-Ripard/drm-Rename-struct-drm_atomic_state-to-drm_atomic_commit/20260405-115623
base:   9bdbf7eb25b3121ef19533df4fb70f2c39fc0d6a
patch link:    https://lore.kernel.org/r/20260402-drm-drm-atomic-update-v3-2-b826f51ac511%40kernel.org
patch subject: [PATCH v3 2/2] Documentation: drm: Remove drm_atomic_state rename entry
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
docutils: docutils (Docutils 0.21.2, Python 3.13.5, on linux)
reproduce: (https://download.01.org/0day-ci/archive/20260405/202604051325.jSSmpYZj-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604051325.jSSmpYZj-lkp@intel.com/

All warnings (new ones prefixed by >>):

   Examples
   ~~~~~~~~ [docutils]
>> Documentation/gpu/komeda-kms.rst:420: WARNING: Title underline too short.


vim +420 Documentation/gpu/komeda-kms.rst

557c37360eca86 james qian wang (Arm Technology China  2019-01-03  408) 
557c37360eca86 james qian wang (Arm Technology China  2019-01-03  409)     struct komeda_component {
557c37360eca86 james qian wang (Arm Technology China  2019-01-03  410)         struct drm_private_obj obj;
557c37360eca86 james qian wang (Arm Technology China  2019-01-03  411)         ...
557c37360eca86 james qian wang (Arm Technology China  2019-01-03  412)     }
557c37360eca86 james qian wang (Arm Technology China  2019-01-03  413) 
557c37360eca86 james qian wang (Arm Technology China  2019-01-03  414)     struct komeda_pipeline {
557c37360eca86 james qian wang (Arm Technology China  2019-01-03  415)         struct drm_private_obj obj;
557c37360eca86 james qian wang (Arm Technology China  2019-01-03  416)         ...
557c37360eca86 james qian wang (Arm Technology China  2019-01-03  417)     }
557c37360eca86 james qian wang (Arm Technology China  2019-01-03  418) 
77e56dfef2e28b Maxime Ripard                          2026-04-02  419  Tracking component_state/pipeline_state by drm_atomic_commit
557c37360eca86 james qian wang (Arm Technology China  2019-01-03 @420) -----------------------------------------------------------
557c37360eca86 james qian wang (Arm Technology China  2019-01-03  421) 

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox