FAILED: patch "[PATCH] mm/damon/core: skip aging from repeated aggressive merging" failed to apply to 7.2-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 7.2-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-7.2.y
git checkout FETCH_HEAD
git cherry-pick -x 0250dbe08c730d003ef9f484da56ae09a1ea0c4c
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090839-reoccupy-dizzy-a7bd@gregkh' --subject-prefix 'PATCH 7.2.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 0250dbe08c730d003ef9f484da56ae09a1ea0c4c Mon Sep 17 00:00:00 2001
From: SJ Park <[email protected]>
Date: Sun, 12 Jul 2026 09:54:30 -0700
Subject: [PATCH] mm/damon/core: skip aging from repeated aggressive merging
The number of DAMON regions could temporarily exceed the user-defined maximum number of regions limit for corner cases. For example, users could lower the limit via runtime parameters update. For such a case, kdamond_merge_regions() repeats merging regions in the case doubling the merge threshold. The repeated merge operation could update the age of regions multiple times. This corrupts the monitoring results. Fix the issue by asking the merge operation to skip aging for the corner case.
The user impact is degradation of the monitoring quality. The impact should be mild, since the degradation is only temporal, and it is not common to happen in realistic setups.
The issue was discovered [1,2] by Sashiko.
mm/damon/core.c +13 -8
@@ -3308,7 +3308,7 @@ static unsigned int damon_merge_score(struct damon_region *r, bool last,* 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,struct damon_ctx *ctx) +unsigned long sz_limit,struct damon_ctx *ctx,bool count_age) {struct damon_region *r, *prev =NULL , *next;bool use_probe_hits =damon_has_probe_weights (ctx);
@@ -3319,12 +3319,14 @@ static void damon_merge_regions_of(struct damon_target *t, unsigned int thres, score =damon_merge_score (r, false, ctx, use_probe_hits); last_score =damon_merge_score (r, true, ctx, use_probe_hits); -if (abs_diff (score, last_score) > thres) - r->age =0 ; -else if ((score ==0 ) != (last_score ==0 )) - r->age =0 ; -else - r->age++; +if (count_age) { +if (abs_diff (score, last_score) > thres) + r->age =0 ; +else if ((score ==0 ) != (last_score ==0 )) + r->age =0 ; +else + r->age++; + }if (!prev) goto set_prev_continue;
@@ -3366,15 +3368,18 @@ static void kdamond_merge_regions(struct damon_ctx *c, unsigned int threshold,struct damon_target *t;unsigned int nr_regions;unsigned int max_thres; +bool count_age = true; max_thres = c->attrs.aggr_interval / (c->attrs.sample_interval ? c->attrs.sample_interval :1 );do { nr_regions =0 ;damon_for_each_target (t, c) { -damon_merge_regions_of (t, threshold, sz_limit, c); +damon_merge_regions_of (t, threshold, sz_limit, c, + count_age); nr_regions +=damon_nr_regions (t); } + count_age = false; threshold =max (1 , threshold *2 ); }while (nr_regions > c->attrs.max_nr_regions && threshold /2 < max_thres);
mm/damon/tests/core-kunit.h +1 -1
@@ -257,7 +257,7 @@ static void damon_test_merge_regions_of(struct kunit *test)damon_add_region (r, t); } -damon_merge_regions_of (t,9 ,9999 , ctx); +damon_merge_regions_of (t,9 ,9999 , ctx, true);/* 0-112, 114-130, 130-156, 156-170, 170-230, 230-10170 */ KUNIT_EXPECT_EQ (test,damon_nr_regions (t),6u );for (i =0 ; i <6 ; i++) {
SJ Park
maintainerPATCH 1/1 mm/damon/core: skip aging from repeated aggressive merging
The number of DAMON regions could temporarily exceed the user-defined maximum number of regions limit for corner cases. For example, users could lower the limit via runtime parameters update. For such a case, kdamond_merge_regions() repeats merging regions in the case doubling the merge threshold. The repeated merge operation could update the age of regions multiple times. This corrupts the monitoring results. Fix the issue by asking the merge operation to skip aging for the corner case.
The user impact is degradation of the monitoring quality. The impact should be mild, since the degradation is only temporal, and it is not common to happen in realistic setups.
The issue was discovered [1,2] by Sashiko.
--- mm/damon/core.c | 21 +++++++++++++-------- mm/damon/tests/core-kunit.h | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-)
mm/damon/core.c +13 -8
@@ -3115,18 +3115,20 @@ static void damon_verify_merge_regions_of(struct damon_region *r)* 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,bool count_age) {struct damon_region *r, *prev =NULL , *next;damon_for_each_region_safe (r, next, t) {damon_verify_merge_regions_of (r); -if (abs (r->nr_accesses - r->last_nr_accesses) > thres) - r->age =0 ; -else if ((r->nr_accesses ==0 ) != (r->last_nr_accesses ==0 )) - r->age =0 ; -else - r->age++; +if (count_age) { +if (abs (r->nr_accesses - r->last_nr_accesses) > thres) + r->age =0 ; +else if ((r->nr_accesses ==0 ) != (r->last_nr_accesses ==0 )) + r->age =0 ; +else + r->age++; + } if (prev && prev->ar.end == r->ar.start && abs(prev->nr_accesses - r->nr_accesses) <= thres &&
@@ -3160,15 +3162,18 @@ static void kdamond_merge_regions(struct damon_ctx *c, unsigned int threshold,struct damon_target *t;unsigned int nr_regions;unsigned int max_thres; +bool count_age = true; max_thres = c->attrs.aggr_interval / (c->attrs.sample_interval ? c->attrs.sample_interval :1 );do { nr_regions =0 ;damon_for_each_target (t, c) { -damon_merge_regions_of (t, threshold, sz_limit); +damon_merge_regions_of (t, threshold, sz_limit, + count_age); nr_regions +=damon_nr_regions (t); } + count_age = false; threshold =max (1 , threshold *2 ); }while (nr_regions > c->attrs.max_nr_regions && threshold /2 < max_thres);
mm/damon/tests/core-kunit.h +1 -1
@@ -256,7 +256,7 @@ static void damon_test_merge_regions_of(struct kunit *test)damon_add_region (r, t); } -damon_merge_regions_of (t,9 ,9999 ); +damon_merge_regions_of (t,9 ,9999 , true);/* 0-112, 114-130, 130-156, 156-170, 170-230, 230-10170 */ KUNIT_EXPECT_EQ (test,damon_nr_regions (t),6u );for (i =0 ; i <6 ; i++) {
Signature · 1 line
2.47.3
[email protected]
AI reviewRe: [PATCH 7.2.y] mm/damon/core: skip aging from repeated aggressive merging
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Unsigned integer wrap-around of threshold causes an infinite loop in kdamond_merge_regions. --
commit 1ad6fba11a691c8367f432e647523c0214515b3e
Author: SJ Park <[email protected]>
mm/damon/core: skip aging from repeated aggressive merging
This commit addresses an issue where the number of DAMON regions can temporarily exceed the maximum limit. It updates kdamond_merge_regions to skip aging during repeated aggressive merging to avoid corrupting monitoring results.
Quoted 4 lines
mm/damon/core.c +0
-0
[ ... ]
Quoted 10 lines
mm/damon/core.c +1
-0@@ -3160,15 +3162,18 @@ static void kdamond_merge_regions(struct damon_ctx *c, unsigned int threshold,struct damon_target *t;unsigned int nr_regions;unsigned int max_thres; +bool count_age = true; max_thres = c->attrs.aggr_interval / (c->attrs.sample_interval ? c->attrs.sample_interval :1 ); do { nr_regions = 0;
mm/damon/core.c static void kdamond_merge_regions(struct damon_ctx *c, unsigned int threshold, · line 3179
Quoted 10 lines
mm/damon/core.c +3
-1damon_for_each_target (t, c) { -damon_merge_regions_of (t, threshold, sz_limit); +damon_merge_regions_of (t, threshold, sz_limit, + count_age); nr_regions +=damon_nr_regions (t); } + count_age = false; threshold =max (1 , threshold *2 ); }while (nr_regions > c->attrs.max_nr_regions && threshold /2 < max_thres);
^^^^^^^^^^^^^^^^^^^^^^^^^
[Severity: High]
This is a pre-existing issue, but could this loop become infinite?
If a user with access to DAMON sysfs sets aggr_interval and sample_interval such that their ratio, stored in max_thres, is greater than 1073741824, can the 32-bit unsigned int threshold wrap around?
Inside the do-while loop, threshold continuously doubles. When it reaches 2147483648, doubling it would wrap it around to 0.
Consequently, threshold / 2 would never exceed 1073741824, making the exit condition infinitely true.
If regions cannot be merged below max_nr_regions due to sz_limit, would this result in a kernel hang on the kdamond thread?
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
Re: [PATCH 7.2.y] mm/damon/core: skip aging from repeated aggressive merging
In reply to SJ ParkQuoted 97 lines · SJ Park
The number of DAMON regions could temporarily exceed the user-defined maximum number of regions limit for corner cases. For example, users could lower the limit via runtime parameters update. For such a case,
kdamond_merge_regions()repeats merging regions in the case doubling the merge threshold. The repeated merge operation could update the age of regions multiple times. This corrupts the monitoring results. Fix the issue by asking the merge operation to skip aging for the corner case.The user impact is degradation of the monitoring quality. The impact should be mild, since the degradation is only temporal, and it is not common to happen in realistic setups.
The issue was discovered [1,2] by Sashiko.
Fixes 310d6c15e910 ("mm/damon/core: merge regions aggressively when max_nr_regions is unmet")Signed-off-by SJ Park <[email protected]>Cc <[email protected]> # 6.10Signed-off-by Andrew Morton <[email protected]>(cherry picked from commit 0250dbe08c730d003ef9f484da56ae09a1ea0c4c)Signed-off-by SJ Park <[email protected]>--- mm/damon/core.c | 21 +++++++++++++-------- mm/damon/tests/core-kunit.h | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-)mm/damon/core.c +13
-8@@ -3115,18 +3115,20 @@ static void damon_verify_merge_regions_of(struct damon_region *r)* 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,bool count_age) {struct damon_region *r, *prev =NULL , *next;damon_for_each_region_safe (r, next, t) {damon_verify_merge_regions_of (r); -if (abs (r->nr_accesses - r->last_nr_accesses) > thres) - r->age =0 ; -else if ((r->nr_accesses ==0 ) != (r->last_nr_accesses ==0 )) - r->age =0 ; -else - r->age++; +if (count_age) { +if (abs (r->nr_accesses - r->last_nr_accesses) > thres) + r->age =0 ; +else if ((r->nr_accesses ==0 ) != (r->last_nr_accesses ==0 )) + r->age =0 ; +else + r->age++; + } if (prev && prev->ar.end == r->ar.start && abs(prev->nr_accesses - r->nr_accesses) <= thres &&@@ -3160,15 +3162,18 @@ static void kdamond_merge_regions(struct damon_ctx *c, unsigned int threshold,struct damon_target *t;unsigned int nr_regions;unsigned int max_thres; +bool count_age = true; max_thres = c->attrs.aggr_interval / (c->attrs.sample_interval ? c->attrs.sample_interval :1 );do { nr_regions =0 ;damon_for_each_target (t, c) { -damon_merge_regions_of (t, threshold, sz_limit); +damon_merge_regions_of (t, threshold, sz_limit, + count_age); nr_regions +=damon_nr_regions (t); } + count_age = false; threshold =max (1 , threshold *2 ); }while (nr_regions > c->attrs.max_nr_regions && threshold /2 < max_thres);mm/damon/tests/core-kunit.h +1
-1@@ -256,7 +256,7 @@ static void damon_test_merge_regions_of(struct kunit *test)damon_add_region (r, t); } -damon_merge_regions_of (t,9 ,9999 ); +damon_merge_regions_of (t,9 ,9999 , true);/* 0-112, 114-130, 130-156, 156-170, 170-230, 230-10170 */ KUNIT_EXPECT_EQ (test,damon_nr_regions (t),6u );for (i =0 ; i <6 ; i++) {Signature · 1 line
2.47.3
Does not apply to the latest 7.2.y queue :(
SJ Park
maintainerRe: [PATCH 7.2.y] mm/damon/core: skip aging from repeated aggressive merging
On Wed, 9 Sep 2026 14:19:27 +0200 Greg KH <[email protected]> wrote:
[...]
Quoted 1 line
Does not apply to the latest 7.2.y queue :(
Thank you, just rebased the patch to 7.2.5-rc1 and posted as another reply [1].
As number of stable patches for DAMON is increasing, this kind of patch applying-order based conflict might be even more common in future. Maybe I could reduce this kind of issues if I could post fixed patches as single patch series, instead of replying to this kind of individual failure report.
I was initially worried if your workflow is dependent to the guided workflow (replying ported patch as a reply to each failure report), and hence if this could make your job more difficult. But I know the stable patch submission rules are quite flexible. And you may already have good enough automation for such small change.s So as long as I keep the essential stable patches rule (use 'cherry-pick -x' option and add target branch name as patch subject tag), that might not really make your work worse?
If that is fine, I will try that from the next time, unless only single failure is reported on the day.
[1] https://lore.kernel.org/[email protected]
Thanks,
SJ
[...]
Re: [PATCH 7.2.y] mm/damon/core: skip aging from repeated aggressive merging
Quoted 11 lines · SJ Park
On Wed, 9 Sep 2026 14:19:27 +0200 Greg KH <[email protected]> wrote:
[...]Quoted 1 line
Does not apply to the latest 7.2.y queue :(
Thank you, just rebased the patch to 7.2.5-rc1 and posted as another reply [1].
As number of stable patches for DAMON is increasing, this kind of patch applying-order based conflict might be even more common in future. Maybe I could reduce this kind of issues if I could post fixed patches as single patch series, instead of replying to this kind of individual failure report.
Quoted 7 lines
I was initially worried if your workflow is dependent to the guided workflow (replying ported patch as a reply to each failure report), and hence if this could make your job more difficult. But I know the stable patch submission rules are quite flexible. And you may already have good enough automation for such small change.s So as long as I keep the essential stable patches rule (use 'cherry-pick -x' option and add target branch name as patch subject tag), that might not really make your work worse?
A patch series is great, and much simpler for me to apply, otherwise I have to just guess and go by the email date/time stamp to order them.
thanks,
greg k-h
SJ Park
maintainerRe: [PATCH 7.2.y] mm/damon/core: skip aging from repeated aggressive merging
Quoted 20 lines · On Thu, 10 Sep 2026 08:15:05 +0200 Greg KH <[email protected]> wrote:
Quoted 11 lines · SJ Park
On Wed, 9 Sep 2026 14:19:27 +0200 Greg KH <[email protected]> wrote:
[...]Quoted 1 line
Does not apply to the latest 7.2.y queue :(
Thank you, just rebased the patch to 7.2.5-rc1 and posted as another reply [1].
As number of stable patches for DAMON is increasing, this kind of patch applying-order based conflict might be even more common in future. Maybe I could reduce this kind of issues if I could post fixed patches as single patch series, instead of replying to this kind of individual failure report.
Quoted 7 lines
I was initially worried if your workflow is dependent to the guided workflow (replying ported patch as a reply to each failure report), and hence if this could make your job more difficult. But I know the stable patch submission rules are quite flexible. And you may already have good enough automation for such small change.s So as long as I keep the essential stable patches rule (use 'cherry-pick -x' option and add target branch name as patch subject tag), that might not really make your work worse?
Quoted 2 lines
A patch series is great, and much simpler for me to apply, otherwise I have to just guess and go by the email date/time stamp to order them.
Thank you, I will try this next time.
Thanks,
SJ
[...]
SJ Park
maintainerPATCH 1/1 mm/damon/core: skip aging from repeated aggressive merging
In reply to [email protected]The number of DAMON regions could temporarily exceed the user-defined maximum number of regions limit for corner cases. For example, users could lower the limit via runtime parameters update. For such a case, kdamond_merge_regions() repeats merging regions in the case doubling the merge threshold. The repeated merge operation could update the age of regions multiple times. This corrupts the monitoring results. Fix the issue by asking the merge operation to skip aging for the corner case.
The user impact is degradation of the monitoring quality. The impact should be mild, since the degradation is only temporal, and it is not common to happen in realistic setups.
The issue was discovered [1,2] by Sashiko.
--- mm/damon/core.c | 21 +++++++++++++-------- mm/damon/tests/core-kunit.h | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-)
mm/damon/core.c +13 -8
@@ -3118,18 +3118,20 @@ static void damon_verify_merge_regions_of(struct damon_region *r)* 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,bool count_age) {struct damon_region *r, *prev =NULL , *next;damon_for_each_region_safe (r, next, t) {damon_verify_merge_regions_of (r); -if (abs (r->nr_accesses - r->last_nr_accesses) > thres) - r->age =0 ; -else if ((r->nr_accesses ==0 ) != (r->last_nr_accesses ==0 )) - r->age =0 ; -else - r->age++; +if (count_age) { +if (abs (r->nr_accesses - r->last_nr_accesses) > thres) + r->age =0 ; +else if ((r->nr_accesses ==0 ) != (r->last_nr_accesses ==0 )) + r->age =0 ; +else + r->age++; + } if (prev && prev->ar.end == r->ar.start && abs(prev->nr_accesses - r->nr_accesses) <= thres &&
@@ -3163,15 +3165,18 @@ static void kdamond_merge_regions(struct damon_ctx *c, unsigned int threshold,struct damon_target *t;unsigned int nr_regions;unsigned int max_thres; +bool count_age = true; max_thres = c->attrs.aggr_interval / (c->attrs.sample_interval ? c->attrs.sample_interval :1 );while (true) { nr_regions =0 ;damon_for_each_target (t, c) { -damon_merge_regions_of (t, threshold, sz_limit); +damon_merge_regions_of (t, threshold, sz_limit, + count_age); nr_regions +=damon_nr_regions (t); } + count_age = false;if (nr_regions <= c->attrs.max_nr_regions || max_thres <= threshold)break ;
mm/damon/tests/core-kunit.h +1 -1
@@ -261,7 +261,7 @@ static void damon_test_merge_regions_of(struct kunit *test)damon_add_region (r, t); } -damon_merge_regions_of (t,9 ,9999 ); +damon_merge_regions_of (t,9 ,9999 , true);/* 0-112, 114-130, 130-156, 156-170, 170-230, 230-10170 */ KUNIT_EXPECT_EQ (test,damon_nr_regions (t),6u );if (damon_nr_regions (t) !=6 )
Signature · 1 line
2.47.3
Re: [PATCH 7.2.y] mm/damon/core: skip aging from repeated aggressive merging
Quoted 3 lines
The number of DAMON regions could temporarily exceed the user-defined maximum number of regions limit for corner cases. For example, users could lower the limit via runtime parameters update.
Queued for 7.2, thanks.
Signature · 2 lines
Thanks, Sasha