DAMON development mailing list
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jiayuan Chen" <jiayuan.chen@linux.dev>
Cc: damon@lists.linux.dev
Subject: Re: [PATCH 1/2] mm/damon/core: cover discrete System RAM areas with per-range regions
Date: Mon, 27 Jul 2026 10:07:31 +0000	[thread overview]
Message-ID: <20260727100731.BC8B01F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260727095429.143527-1-jiayuan.chen@linux.dev>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Time-of-check to time-of-use (TOCTOU) race condition in `damon_find_system_rams()` leads to a heap out-of-bounds write during concurrent memory hotplug.
- [High] DAMON initialization fails with `-EINVAL` on systems with sub-page System RAM gaps due to alignment overlap in `damon_set_regions()`.
--

--- Patch [1]: [PATCH 1/2] mm/damon/core: cover discrete System RAM areas with per-range regions ---
commit 20fb01bf6e8e4cefc6016dfc073fb77c95ca3511
Author: Jiayuan Chen <jiayuan.chen@shopee.com>

mm/damon/core: cover discrete System RAM areas with per-range regions

This commit changes how DAMON sets default monitoring regions for System RAM.
Instead of a single region covering all RAM (and the holes between), it now
creates separate regions for each discrete System RAM area. This excludes
large memory holes from being monitored.

> diff --git a/mm/damon/core.c b/mm/damon/core.c
> index 644daf5a16560..365c43271c0c6 100644
> --- a/mm/damon/core.c
> +++ b/mm/damon/core.c

[ ... ]

> +static int damon_find_system_rams(struct damon_addr_range **ranges_out,
> +				  unsigned long addr_unit)
> +{
> +	struct damon_system_ram_range_walk_arg arg = { .addr_unit = addr_unit };
> +	struct damon_addr_range *ranges;
>  
> +	/* First pass: count the coalesced ranges. */
>  	walk_system_ram_res(0, -1, &arg, damon_system_ram_walk_fn);
> -	if (!arg.walked)
> -		return false;
> -	*start = damon_res_to_core_addr(arg.res.start, addr_unit);
> -	*end = damon_res_to_core_addr(arg.res.end + 1, addr_unit);
> -	if (*end <= *start)
> -		return false;
> -	return true;
> +	if (!arg.nr_ranges)
> +		return 0;
> +	ranges = kvmalloc_objs(*ranges, arg.nr_ranges, GFP_KERNEL);
> +	if (!ranges)
> +		return -ENOMEM;
> +	/* Second pass: fill in the coalesced ranges. */
> +	arg.ranges = ranges;
> +	arg.nr_ranges = 0;
> +	arg.has_prev = false;
> +	walk_system_ram_res(0, -1, &arg, damon_system_ram_walk_fn);

[Severity: High]
Can this race with memory hotplug events and cause an out-of-bounds write?

walk_system_ram_res() is called twice without holding memory hotplug locks.
If a new System RAM region is hotplugged between or during the second pass,
the number of visited regions could exceed the allocated buffer size.

If that happens, damon_system_ram_walk_fn() would write past the end of the
kvmalloc-allocated buffer:

mm/damon/core.c:damon_system_ram_walk_fn() {
	...
	if (a->ranges) {
		a->ranges[a->nr_ranges].start = start;
		a->ranges[a->nr_ranges].end = end;
	}
	a->nr_ranges++;
	...
}

> +	*ranges_out = ranges;
> +	return arg.nr_ranges;
>  }

[ ... ]

> @@ -3984,14 +4021,25 @@ int damon_set_region_system_rams_default(struct damon_target *t,
>  			unsigned long addr_unit, unsigned long min_region_sz)
>  {
>  	struct damon_addr_range addr_range;
> +	struct damon_addr_range *ranges;
> +	int nr_ranges, err;
>  
> -	if (!*start && !*end &&
> -		!damon_find_system_rams_range(start, end, addr_unit))
> -		return -EINVAL;
> +	if (*start || *end) {
> +		addr_range.start = *start;
> +		addr_range.end = *end;
> +		return damon_set_regions(t, &addr_range, 1, min_region_sz);
> +	}
>  
> -	addr_range.start = *start;
> -	addr_range.end = *end;
> -	return damon_set_regions(t, &addr_range, 1, min_region_sz);
> +	nr_ranges = damon_find_system_rams(&ranges, addr_unit);
> +	if (nr_ranges < 0)
> +		return nr_ranges;
> +	if (!nr_ranges)
> +		return -EINVAL;
> +	*start = ranges[0].start;
> +	*end = ranges[nr_ranges - 1].end;
> +	err = damon_set_regions(t, ranges, nr_ranges, min_region_sz);

[Severity: High]
Could this fail with -EINVAL during initialization on systems with sub-page
memory gaps?

If the system has System RAM fragmented by small non-RAM holes (like sub-page
BIOS or EFI reserved regions), damon_system_ram_walk_fn() will create separate
discrete regions.

When these regions are passed to damon_set_regions(), it aligns the boundaries
to min_region_sz (typically PAGE_SIZE):

mm/damon/core.c:damon_set_regions() {
	for (i = 0; i < nr_ranges; i++) {
		...
		start = ALIGN_DOWN(ranges[i].start, min_region_sz);
		end = ALIGN(ranges[i].end, min_region_sz);
		if (start >= end)
			return -EINVAL;
		if (i > 0 && last_end > start)
			return -EINVAL;
		last_end = end;
	}
	...
}

If the gap between two RAM areas is smaller than PAGE_SIZE, the ALIGN of the
first region's end will evaluate to a higher address than the ALIGN_DOWN of
the second region's start. Does this cause the strictly-ascending overlap
check (last_end > start) to trigger and reject valid configurations?

> +	kvfree(ranges);
> +	return err;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260727095429.143527-1-jiayuan.chen@linux.dev?part=1

  parent reply	other threads:[~2026-07-27 10:07 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-27  9:54 [PATCH 1/2] mm/damon/core: cover discrete System RAM areas with per-range regions Jiayuan Chen
2026-07-27  9:54 ` [PATCH 2/2] mm/damon/sysfs-schemes: report the number of tried regions Jiayuan Chen
2026-07-27 14:34   ` SJ Park
2026-07-27 10:07 ` sashiko-bot [this message]
2026-07-27 11:04   ` [PATCH 1/2] mm/damon/core: cover discrete System RAM areas with per-range regions Jiayuan Chen
2026-07-27 14:26 ` SJ Park

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260727100731.BC8B01F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=damon@lists.linux.dev \
    --cc=jiayuan.chen@linux.dev \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox