FAILED: patch "[PATCH] mm/damon/core: allow esz to be set to zero" failed to apply to 6.12-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.12-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-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 90179da203ba8b708c84a12a07cd44be0f346334
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026092900-prize-superglue-6d70@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 90179da203ba8b708c84a12a07cd44be0f346334 Mon Sep 17 00:00:00 2001
From: Liew Rui Yan <[email protected]>
Date: Tue, 8 Sep 2026 06:54:11 -0700
Subject: [PATCH] mm/damon/core: allow esz to be set to zero
When the temporal quota goal tuner determines that the goal has been achieved (score >= 10000), it sets esz_bp to zero so that the esz becomes zero. However, damos_set_effective_quota() clamps the esz to min_region_sz when quota->ms is set.
This is a minor issue, the main problem is that it doesn't match the description in the documentation, which state that if the goal has already been [over-]achieved, the quota will be set to zero.
Fix this by set quota (esz) as minimum as possible.
mm/damon/core.c +3 -2
@@ -3091,6 +3091,7 @@ static void damos_set_effective_quota(struct damon_ctx *ctx, struct damos *s)struct damos_quota *quota = &s->quota;unsigned long throughput;unsigned long esz =ULONG_MAX ; +unsigned long esz_time;if (!quota->ms &&list_empty ("a->goals)) { quota->esz = quota->sz;
@@ -3111,8 +3112,8 @@ static void damos_set_effective_quota(struct damon_ctx *ctx, struct damos *s) 1000000, quota->total_charged_ns); else throughput =PAGE_SIZE *1024 ; - esz =min (throughput * quota->ms, esz); - esz =max (ctx->min_region_sz, esz); + esz_time =max (throughput * quota->ms, ctx->min_region_sz); + esz =min (esz_time, esz); }if (quota->sz && quota->sz < esz)
Sasha Levin
maintainerPATCH 1/2 mm/damon: rename DAMON_MIN_REGION to DAMON_MIN_REGION_SZ
From: SeongJae Park <[email protected]>
[ Upstream commit dfb1b0c9dc0d61e422905640e1e7334b3cf6f384 ]
The macro is for the default minimum size of each DAMON region. There was a case that a reader was confused if it is the minimum number of total DAMON regions, which is set on damon_attrs->min_nr_regions. Make the name more explicit.
Stable dependency adaptation for 90179da203ba:
Rename every use present in 6.12, including the core KUnit override and filter tests. Drop upstream hunks for address units, per-context region alignment, and the newer damon_set_regions() signature, which are absent from this tree. Preserve the stable region-setting validation and error handling.
Prepare the existing quota calculation for the unmodified target patch:
store the fixed minimum region size in damon_ctx, pass the context and scheme to damos_set_effective_quota(), initialize esz to ULONG_MAX, and use the upstream mult_frac() throughput calculation. Keep the existing minimum quota clamp for the target to fix. No functions are added.
[ sashal: Reduced backport -- upstream dfb1b0c9dc0d6 touches 7 file(s), this
backport carries 4. Not backported here:
mm/damon/lru_sort.c
mm/damon/reclaim.c
mm/damon/sysfs.c
mm/damon/tests/vaddr-kunit.h
This note is generated from the file lists only; see the resolution record for the reasoning. ]
Stable-dep-of: 90179da203ba ("mm/damon/core: allow esz to be set to zero")
--- include/linux/damon.h | 4 ++- mm/damon/core.c | 56 ++++++++++++++++++------------------- mm/damon/tests/core-kunit.h | 36 ++++++++++++------------ mm/damon/vaddr.c | 22 +++++++-------- 4 files changed, 60 insertions(+), 58 deletions(-)
include/linux/damon.h +3 -1
@@ -15,7 +15,7 @@#include <linux/random.h> /* Minimal region size. Every damon_region is aligned by this. */ -#define DAMON_MIN_REGION PAGE_SIZE +#define DAMON_MIN_REGION_SZ PAGE_SIZE/* Max priority score for DAMON-based operation schemes */ #define DAMOS_MAX_SCORE (99)
@@ -631,6 +631,8 @@ struct damon_ctx {struct completion kdamond_started;/* for scheme quotas prioritization */ unsigned long *regions_score_histogram; +/* minimum region size for time quotas, fixed on this stable branch */ +unsigned long min_region_sz;/* public: */ struct task_struct *kdamond;
mm/damon/core.c +28 -28
145 lines not on this page · raw message
mm/damon/tests/core-kunit.h +18 -18
@@ -530,10 +530,10 @@ static void damos_test_filter_out(struct kunit *test) f =damos_new_filter (DAMOS_FILTER_TYPE_ADDR , true); f->addr_range = (struct damon_addr_range ){ - .start =DAMON_MIN_REGION *2 , .end =DAMON_MIN_REGION *6 }; + .start =DAMON_MIN_REGION_SZ *2 , .end =DAMON_MIN_REGION_SZ *6 }; t =damon_new_target (); - r =damon_new_region (DAMON_MIN_REGION *3 ,DAMON_MIN_REGION *5 ); + r =damon_new_region (DAMON_MIN_REGION_SZ *3 ,DAMON_MIN_REGION_SZ *5 );damon_add_region (r, t);/* region in the range */
@@ -541,45 +541,45 @@ static void damos_test_filter_out(struct kunit *test)KUNIT_EXPECT_EQ (test,damon_nr_regions (t),1 );/* region before the range */ - r->ar.start =DAMON_MIN_REGION *1 ; - r->ar.end =DAMON_MIN_REGION *2 ; + r->ar.start =DAMON_MIN_REGION_SZ *1 ; + r->ar.end =DAMON_MIN_REGION_SZ *2 ;KUNIT_EXPECT_FALSE (test,__damos_filter_out (NULL , t, r, f));KUNIT_EXPECT_EQ (test,damon_nr_regions (t),1 );/* region after the range */ - r->ar.start =DAMON_MIN_REGION *6 ; - r->ar.end =DAMON_MIN_REGION *8 ; + r->ar.start =DAMON_MIN_REGION_SZ *6 ; + r->ar.end =DAMON_MIN_REGION_SZ *8 ;KUNIT_EXPECT_FALSE (test,__damos_filter_out (NULL , t, r, f));KUNIT_EXPECT_EQ (test,damon_nr_regions (t),1 );/* region started before the range */ - r->ar.start =DAMON_MIN_REGION *1 ; - r->ar.end =DAMON_MIN_REGION *4 ; + r->ar.start =DAMON_MIN_REGION_SZ *1 ; + r->ar.end =DAMON_MIN_REGION_SZ *4 ;KUNIT_EXPECT_FALSE (test,__damos_filter_out (NULL , t, r, f));/* filter should have split the region */ -KUNIT_EXPECT_EQ (test, r->ar.start,DAMON_MIN_REGION *1 ); -KUNIT_EXPECT_EQ (test, r->ar.end,DAMON_MIN_REGION *2 ); +KUNIT_EXPECT_EQ (test, r->ar.start,DAMON_MIN_REGION_SZ *1 ); +KUNIT_EXPECT_EQ (test, r->ar.end,DAMON_MIN_REGION_SZ *2 );KUNIT_EXPECT_EQ (test,damon_nr_regions (t),2 );if (damon_nr_regions (t) !=2 ) goto out; r2 =damon_next_region (r); -KUNIT_EXPECT_EQ (test, r2->ar.start,DAMON_MIN_REGION *2 ); -KUNIT_EXPECT_EQ (test, r2->ar.end,DAMON_MIN_REGION *4 ); +KUNIT_EXPECT_EQ (test, r2->ar.start,DAMON_MIN_REGION_SZ *2 ); +KUNIT_EXPECT_EQ (test, r2->ar.end,DAMON_MIN_REGION_SZ *4 );damon_destroy_region (r2, t);/* region started in the range */ - r->ar.start =DAMON_MIN_REGION *2 ; - r->ar.end =DAMON_MIN_REGION *8 ; + r->ar.start =DAMON_MIN_REGION_SZ *2 ; + r->ar.end =DAMON_MIN_REGION_SZ *8 ;KUNIT_EXPECT_TRUE (test,__damos_filter_out (NULL , t, r, f));/* filter should have split the region */ -KUNIT_EXPECT_EQ (test, r->ar.start,DAMON_MIN_REGION *2 ); -KUNIT_EXPECT_EQ (test, r->ar.end,DAMON_MIN_REGION *6 ); +KUNIT_EXPECT_EQ (test, r->ar.start,DAMON_MIN_REGION_SZ *2 ); +KUNIT_EXPECT_EQ (test, r->ar.end,DAMON_MIN_REGION_SZ *6 );KUNIT_EXPECT_EQ (test,damon_nr_regions (t),2 );if (damon_nr_regions (t) !=2 ) goto out; r2 =damon_next_region (r); -KUNIT_EXPECT_EQ (test, r2->ar.start,DAMON_MIN_REGION *6 ); -KUNIT_EXPECT_EQ (test, r2->ar.end,DAMON_MIN_REGION *8 ); +KUNIT_EXPECT_EQ (test, r2->ar.start,DAMON_MIN_REGION_SZ *6 ); +KUNIT_EXPECT_EQ (test, r2->ar.end,DAMON_MIN_REGION_SZ *8 );damon_destroy_region (r2, t); out:
mm/damon/vaddr.c +11 -11
@@ -18,8 +18,8 @@#include "ops-common.h" #ifdef CONFIG_DAMON_VADDR_KUNIT_TEST -#undef DAMON_MIN_REGION -#define DAMON_MIN_REGION 1 +#undef DAMON_MIN_REGION_SZ +#define DAMON_MIN_REGION_SZ 1#endif /*
@@ -74,7 +74,7 @@ static int damon_va_evenly_split_region(struct damon_target *t, orig_end = r->ar.end; sz_orig =damon_sz_region (r); - sz_piece =ALIGN_DOWN (sz_orig / nr_pieces,DAMON_MIN_REGION ); + sz_piece =ALIGN_DOWN (sz_orig / nr_pieces,DAMON_MIN_REGION_SZ );if (!sz_piece)return -EINVAL ;
@@ -157,12 +157,12 @@ static int __damon_va_three_regions(struct mm_struct *mm,swap (first_gap, second_gap);/* Store the result */ - regions[0 ].start =ALIGN (start,DAMON_MIN_REGION ); - regions[0 ].end =ALIGN (first_gap.start,DAMON_MIN_REGION ); - regions[1 ].start =ALIGN (first_gap.end,DAMON_MIN_REGION ); - regions[1 ].end =ALIGN (second_gap.start,DAMON_MIN_REGION ); - regions[2 ].start =ALIGN (second_gap.end,DAMON_MIN_REGION ); - regions[2 ].end =ALIGN (prev->vm_end,DAMON_MIN_REGION ); + regions[0 ].start =ALIGN (start,DAMON_MIN_REGION_SZ ); + regions[0 ].end =ALIGN (first_gap.start,DAMON_MIN_REGION_SZ ); + regions[1 ].start =ALIGN (first_gap.end,DAMON_MIN_REGION_SZ ); + regions[1 ].end =ALIGN (second_gap.start,DAMON_MIN_REGION_SZ ); + regions[2 ].start =ALIGN (second_gap.end,DAMON_MIN_REGION_SZ ); + regions[2 ].end =ALIGN (prev->vm_end,DAMON_MIN_REGION_SZ );return 0 ; }
@@ -255,8 +255,8 @@ static void __damon_va_init_regions(struct damon_ctx *ctx, sz += regions[i].end - regions[i].start;if (ctx->attrs.min_nr_regions) sz /= ctx->attrs.min_nr_regions; -if (sz <DAMON_MIN_REGION ) - sz =DAMON_MIN_REGION ; +if (sz <DAMON_MIN_REGION_SZ ) + sz =DAMON_MIN_REGION_SZ ;/* Set the initial three regions of the target */ for (i =0 ; i <3 ; i++) {
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 mm/damon/core: allow esz to be set to zero
From: Liew Rui Yan <[email protected]>
[ Upstream commit 90179da203ba8b708c84a12a07cd44be0f346334 ]
When the temporal quota goal tuner determines that the goal has been achieved (score >= 10000), it sets esz_bp to zero so that the esz becomes zero. However, damos_set_effective_quota() clamps the esz to min_region_sz when quota->ms is set.
This is a minor issue, the main problem is that it doesn't match the description in the documentation, which state that if the goal has already been [over-]achieved, the quota will be set to zero.
Fix this by set quota (esz) as minimum as possible.
--- mm/damon/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
mm/damon/core.c +3 -2
@@ -1638,6 +1638,7 @@ static void damos_set_effective_quota(struct damon_ctx *ctx, struct damos *s)struct damos_quota *quota = &s->quota;unsigned long throughput;unsigned long esz =ULONG_MAX ; +unsigned long esz_time;if (!quota->ms &&list_empty ("a->goals)) { quota->esz = quota->sz;
@@ -1659,8 +1660,8 @@ static void damos_set_effective_quota(struct damon_ctx *ctx, struct damos *s) 1000000, quota->total_charged_ns); else throughput =PAGE_SIZE *1024 ; - esz =min (throughput * quota->ms, esz); - esz =max (ctx->min_region_sz, esz); + esz_time =max (throughput * quota->ms, ctx->min_region_sz); + esz =min (esz_time, esz); }if (quota->sz && quota->sz < esz)
Signature · 1 line
2.53.0
SJ Park
maintainerRe: [PATCH 6.12.y 2/2] mm/damon/core: allow esz to be set to zero
Hello Sasha,
Quoted 9 lines · On Tue, 29 Sep 2026 20:04:01 -0400 Sasha Levin <[email protected]> wrote:
From: Liew Rui Yan <[email protected]>
[ Upstream commit
90179da203ba8b708c84a12a07cd44be0f346334]When the temporal quota goal tuner determines that the goal has been achieved (score >= 10000), it sets
esz_bpto zero so that the esz becomes zero. However,damos_set_effective_quota()clamps the esz tomin_region_szwhenquota->msis set.
Quoted 5 lines
This is a minor issue, the main problem is that it doesn't match the description in the documentation, which state that if the goal has already been [over-]achieved, the quota will be set to zero.
Fix this by set quota (esz) as minimum as possible.
Thank you for doing this backport.
Quoted 3 lines
Fixes 8bbde987c2b8 ("mm/damon/core: disallow time-quota setting zero esz")
However, this patch also depends on temporal tuner feature, which was introduced by 7.1. It is not in <7.1 stable kernels. So this patch shouldn't be applied on those, including 6.12.y. Could you please drop this patch?
Thanks,
SJ
[...]