From: SJ Park <sj@kernel.org>
To: sashiko-bot@kernel.org
Cc: SJ Park <sj@kernel.org>, damon@lists.linux.dev
Subject: Re: [RFC PATCH 07/16] mm/damon/core: extend merge function to work with probe hits
Date: Sun, 5 Jul 2026 14:38:16 -0700 [thread overview]
Message-ID: <20260705213817.100841-1-sj@kernel.org> (raw)
In-Reply-To: <20260705211101.F2F061F000E9@smtp.kernel.org>
On Sun, 05 Jul 2026 21:11:01 +0000 sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
>
> New issues:
> - [High] Incompatible scale and domain mismatch between weighted scores and unweighted merge thresholds.
> - [High] Unsafe use of `abs()` macro on large unsigned integer score differences causes silent signed integer overflow.
> - [Medium] Calculating the weighted sum of probe hits in `damon_probe_hits_wsum` can easily overflow a 32-bit `unsigned int`.
>
> Pre-existing issues:
> - [High] Weighted average calculations in `damon_merge_two_regions` silently overflow 32-bit `unsigned long` on 32-bit architectures.
> --
>
> commit 54d6e0bb9900e63a1a016ffee9632b6aa602175b
> Author: SJ Park <sj@kernel.org>
>
> mm/damon/core: extend merge function to work with probe hits
>
> This commit extends damon_merge_regions_of() to consider the weighted sum
> of probe hits when calculating regions to merge, introducing
> damon_has_probe_weights() and modifying the scoring logic to use these weights.
>
> > diff --git a/mm/damon/core.c b/mm/damon/core.c
> > index c370eaff5795d..f6e03746b170e 100644
> > --- a/mm/damon/core.c
> > +++ b/mm/damon/core.c
> [ ... ]
> > @@ -3187,6 +3192,16 @@ static void damon_merge_two_regions(struct damon_target *t,
> > damon_destroy_region(r, t);
> > }
>
> [Severity: High]
> This isn't a bug introduced by this patch, but can the weighted average
> calculations in damon_merge_two_regions() silently overflow a 32-bit
> unsigned long on 32-bit architectures?
>
> On 32-bit architectures, sz_l is a 32-bit unsigned long.
>
> If the region size is large (e.g., hundreds of megabytes), multiplying sz_l
> by nr_accesses or probe_hits could exceed the 4.29B maximum of a 32-bit
> integer, corrupting the merged region's statistics.
>
> mm/damon/core.c:damon_merge_two_regions() {
> ...
> l->nr_accesses = (l->nr_accesses * sz_l + r->nr_accesses * sz_r) /
> (sz_l + sz_r);
> ...
> for (i = 0; i < DAMON_MAX_PROBES; i++)
> l->probe_hits[i] = (l->probe_hits[i] * sz_l + r->probe_hits[i]
> * sz_r) / (sz_l + sz_r);
> ...
> }
This doesn't cause a critical consequenes like kernel crash. Knnown low
priority issue.
>
> > +static unsigned int damon_merge_score(struct damon_region *r, bool last,
> > + struct damon_ctx *ctx, bool use_probe_hits)
> > +{
> > + if (use_probe_hits)
> > + return damon_probe_hits_wsum(r, last, ctx);
>
> [Severity: Medium]
> Can the multiplication in damon_probe_hits_wsum() overflow a 32-bit
> unsigned int?
>
> probe->weight is an unsigned int.
>
> If users supply a large weight, multiplying it by r->probe_hits[i] (which can
> be up to 255) might exceed UINT_MAX, causing the sum to wrap around and yield
> artificially small scores for highly active regions.
>
> mm/damon/core.c:damon_probe_hits_wsum() {
> ...
> if (last)
> sum += r->last_probe_hits[i++] * probe->weight;
> else
> sum += r->probe_hits[i++] * probe->weight;
> ...
> }
No critical consequence like kernel crash. Known low priority issue.
>
> > + if (last)
> > + return r->last_nr_accesses;
> > + return r->nr_accesses;
> > +}
> > +
> > /*
> > * Merge adjacent regions having similar access frequencies
> > *
> > @@ -3195,24 +3210,37 @@ static void damon_merge_two_regions(struct damon_target *t,
> > * sz_limit size upper limit of each region
> > */
> > static void damon_merge_regions_of(struct damon_target *t, unsigned int thres,
> > - unsigned long sz_limit)
> > + unsigned long sz_limit, struct damon_ctx *ctx)
> > {
> > struct damon_region *r, *prev = NULL, *next;
> > + bool use_probe_hits = damon_has_probe_weights(ctx);
> >
> > damon_for_each_region_safe(r, next, t) {
> > - if (abs(r->nr_accesses - r->last_nr_accesses) > thres)
> > + unsigned int score, last_score;
> > +
> > + score = damon_merge_score(r, false, ctx, use_probe_hits);
> > + last_score = damon_merge_score(r, true, ctx, use_probe_hits);
> > +
> > + if (abs(score - last_score) > thres)
>
> [Severity: High]
> Does the use of abs() here cause a silent signed integer overflow for large
> unsigned differences?
>
> The macro abs() implicitly casts an unsigned int to a signed int.
>
> If the mathematical difference between score and last_score exceeds INT_MAX
> (which might happen with large user-defined probe weights), the cast wraps to
> a negative number.
>
> The abs() macro then negates it into an artificially small positive integer,
> which could cause the code to incorrectly bypass the > thres check and merge
> regions with vastly different access profiles.
Pre-existing issue. I will fix this separately.
>
> [Severity: High]
> Is there a domain mismatch between the weighted score differences and the
> unweighted thres parameter?
>
> When use_probe_hits is true, the score is a weighted sum derived from probe
> hits and user-defined weights. However, thres operates in the unweighted access
> frequency domain.
>
> This mismatch appears to carry over to kdamond_merge_regions(), where max_thres
> is also scaled in the unweighted domain (aggr_interval / sample_interval).
>
> Because weighted scores operate in a different numerical domain, could they
> easily exceed max_thres, forcing the merge loop in kdamond_merge_regions() to
> terminate prematurely?
>
> mm/damon/core.c:kdamond_merge_regions() {
> ...
> max_thres = c->attrs.aggr_interval /
> (c->attrs.sample_interval ? c->attrs.sample_interval : 1);
> do {
> ...
> threshold = max(1, threshold * 2);
> } while (nr_regions > c->attrs.max_nr_regions &&
> threshold / 2 < max_thres);
> ...
> }
Yes, and that will be fixed by the later commit of this series.
>
> > r->age = 0;
> > - else if ((r->nr_accesses == 0) != (r->last_nr_accesses == 0))
> > + else if ((score == 0) != (last_score == 0))
> > r->age = 0;
> > else
> > r->age++;
> >
> > - if (prev && prev->ar.end == r->ar.start &&
> > - abs(prev->nr_accesses - r->nr_accesses) <= thres &&
> > - damon_sz_region(prev) + damon_sz_region(r) <= sz_limit)
> > - damon_merge_two_regions(t, prev, r);
> > - else
> > - prev = r;
> > + if (!prev)
> > + goto set_prev_continue;
> > + if (prev->ar.end != r->ar.start)
> > + goto set_prev_continue;
> > + if (abs(damon_merge_score(prev, false, ctx, use_probe_hits) -
> > + score) > thres)
>
> [Severity: High]
> Does this abs() usage also suffer from the same silent signed integer overflow
> as mentioned above when comparing large unsigned score differences?
Pre-existing issue. I will separately work on this.
>
> > + goto set_prev_continue;
> > + if (damon_sz_region(prev) + damon_sz_region(r) > sz_limit)
> > + goto set_prev_continue;
> > + damon_merge_two_regions(t, prev, r);
> > + continue;
> > +set_prev_continue:
> > + prev = r;
> > }
> > }
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260705205743.98656-1-sj@kernel.org?part=7
Thanks,
SJ
next prev parent reply other threads:[~2026-07-05 21:38 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-05 20:57 [RFC PATCH 00/16] mm/damon: introduce data attributes only monitoring SJ Park
2026-07-05 20:57 ` [RFC PATCH 01/16] mm/damon/core: introduce damon_probe->weight SJ Park
2026-07-05 21:04 ` sashiko-bot
2026-07-05 21:21 ` SJ Park
2026-07-05 20:57 ` [RFC PATCH 02/16] mm/damon/core: ask apply_probes() ops callback to set sampling address SJ Park
2026-07-05 21:07 ` sashiko-bot
2026-07-05 21:25 ` SJ Park
2026-07-05 20:57 ` [RFC PATCH 03/16] mm/damon/paddr: set samples in apply_probes() if requested SJ Park
2026-07-05 21:11 ` sashiko-bot
2026-07-05 21:28 ` SJ Park
2026-07-05 20:57 ` [RFC PATCH 04/16] mm/damon/core: ask apply_probe() to return max probe hits weighted sum SJ Park
2026-07-05 20:57 ` [RFC PATCH 05/16] mm/damon/core: implement damon_probe_hits_wsum() SJ Park
2026-07-05 21:13 ` sashiko-bot
2026-07-05 21:30 ` SJ Park
2026-07-05 20:57 ` [RFC PATCH 06/16] mm/damon/paddr: respect return_max_wsum SJ Park
2026-07-05 20:57 ` [RFC PATCH 07/16] mm/damon/core: extend merge function to work with probe hits SJ Park
2026-07-05 21:11 ` sashiko-bot
2026-07-05 21:38 ` SJ Park [this message]
2026-07-05 20:57 ` [RFC PATCH 08/16] mm/damon/core: disable access monitoring when probe weights are set SJ Park
2026-07-05 21:19 ` sashiko-bot
2026-07-05 20:57 ` [RFC PATCH 09/16] mm/damon/core: set samples in apply_probes() if " SJ Park
2026-07-05 20:57 ` [RFC PATCH 10/16] mm/damon/core: s/max_nr_accesses/max_merge_score/ in kdamond_fn() SJ Park
2026-07-05 20:57 ` [RFC PATCH 11/16] mm/damon/core: get merge threshold from probe hits when weights are set SJ Park
2026-07-05 21:12 ` sashiko-bot
2026-07-05 21:41 ` SJ Park
2026-07-05 20:57 ` [RFC PATCH 12/16] mm/damon/core: implement damon_has_probe_weight() SJ Park
2026-07-05 21:15 ` sashiko-bot
2026-07-05 21:45 ` SJ Park
2026-07-05 20:57 ` [RFC PATCH 13/16] mm/damon/sysfs: implement probe/weight file SJ Park
2026-07-05 20:57 ` [RFC PATCH 14/16] Docs/mm/damon/design: document attrs-only monitoring SJ Park
2026-07-05 21:05 ` sashiko-bot
2026-07-05 21:46 ` SJ Park
2026-07-05 20:57 ` [RFC PATCH 15/16] Docs/admin-guide/mm/damon/usage: document weight sysfs file SJ Park
2026-07-05 21:07 ` sashiko-bot
2026-07-05 21:48 ` SJ Park
2026-07-05 20:57 ` [RFC PATCH 16/16] Docs/ABI/damon: document probe weight file 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=20260705213817.100841-1-sj@kernel.org \
--to=sj@kernel.org \
--cc=damon@lists.linux.dev \
--cc=sashiko-bot@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.