FAILED: patch "[PATCH] mm/damon/core: disallow non-power of two min_region_sz" failed to apply to 6.19-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.19-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.19.y
git checkout FETCH_HEAD
git cherry-pick -x c80f46ac228b48403866d65391ad09bdf0e8562a
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026031714-concept-seventh-df3c@gregkh' --subject-prefix 'PATCH 6.19.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From c80f46ac228b48403866d65391ad09bdf0e8562a Mon Sep 17 00:00:00 2001
From: SeongJae Park <[email protected]>
Date: Sat, 14 Feb 2026 13:41:21 -0800
Subject: [PATCH] mm/damon/core: disallow non-power of two min_region_sz
DAMON core uses min_region_sz parameter value as the DAMON region alignment. The alignment is made using ALIGN() and ALIGN_DOWN(), which support only the power of two alignments. But DAMON core API callers can set min_region_sz to an arbitrary number. Users can also set it indirectly, using addr_unit.
When the alignment is not properly set, DAMON behavior becomes difficult to expect and understand, makes it effectively broken. It doesn't cause a kernel crash-like significant issue, though.
Fix the issue by disallowing min_region_sz input that is not a power of two. Add the check to damon_commit_ctx(), as all DAMON API callers who set min_region_sz uses the function.
This can be a sort of behavioral change, but it does not break users, for the following reasons. As the symptom is making DAMON effectively broken, it is not reasonable to believe there are real use cases of non-power of two min_region_sz. There is no known use case or issue reports from the setup, either.
In future, if we find real use cases of non-power of two alignments and we can support it with low enough overhead, we can consider moving the restriction. But, for now, simply disallowing the corner case should be good enough as a hot fix.
mm/damon/core.c +3 -0
@@ -1252,6 +1252,9 @@ int damon_commit_ctx(struct damon_ctx *dst, struct damon_ctx *src) {int err; +if (!is_power_of_2 (src->min_region_sz)) +return -EINVAL ; + err =damon_commit_schemes (dst, src);if (err)return err;
Sasha Levin
maintainerPATCH 1/3 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-dep-of: c80f46ac228b ("mm/damon/core: disallow non-power of two min_region_sz")
--- include/linux/damon.h | 2 +- mm/damon/core.c | 2 +- mm/damon/lru_sort.c | 2 +- mm/damon/reclaim.c | 2 +- mm/damon/sysfs.c | 2 +- mm/damon/tests/vaddr-kunit.h | 2 +- mm/damon/vaddr.c | 24 ++++++++++++------------ 7 files changed, 18 insertions(+), 18 deletions(-)
include/linux/damon.h +1 -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)
mm/damon/core.c +1 -1
@@ -546,7 +546,7 @@ struct damon_ctx *damon_new_ctx(void) ctx->attrs.max_nr_regions =1000 ; ctx->addr_unit =1 ; - ctx->min_sz_region =DAMON_MIN_REGION ; + ctx->min_sz_region =DAMON_MIN_REGION_SZ ;INIT_LIST_HEAD (&ctx->adaptive_targets);INIT_LIST_HEAD (&ctx->schemes);
mm/damon/lru_sort.c +1 -1
@@ -212,7 +212,7 @@ static int damon_lru_sort_apply_parameters(void)if (!monitor_region_start && !monitor_region_end) addr_unit =1 ; param_ctx->addr_unit = addr_unit; - param_ctx->min_sz_region =max (DAMON_MIN_REGION / addr_unit,1 ); + param_ctx->min_sz_region =max (DAMON_MIN_REGION_SZ / addr_unit,1 );if (!damon_lru_sort_mon_attrs.sample_interval) { err = -EINVAL ;
mm/damon/reclaim.c +1 -1
@@ -208,7 +208,7 @@ static int damon_reclaim_apply_parameters(void)if (!monitor_region_start && !monitor_region_end) addr_unit =1 ; param_ctx->addr_unit = addr_unit; - param_ctx->min_sz_region =max (DAMON_MIN_REGION / addr_unit,1 ); + param_ctx->min_sz_region =max (DAMON_MIN_REGION_SZ / addr_unit,1 );if (!damon_reclaim_mon_attrs.aggr_interval) { err = -EINVAL ;
mm/damon/sysfs.c +1 -1
@@ -1470,7 +1470,7 @@ static int damon_sysfs_apply_inputs(struct damon_ctx *ctx,/* addr_unit is respected by only DAMON_OPS_PADDR */ if (sys_ctx->ops_id ==DAMON_OPS_PADDR ) ctx->min_sz_region =max ( -DAMON_MIN_REGION / sys_ctx->addr_unit,1 ); +DAMON_MIN_REGION_SZ / sys_ctx->addr_unit,1 ); err =damon_sysfs_set_attrs (ctx, sys_ctx->attrs);if (err)return err;
mm/damon/tests/vaddr-kunit.h +1 -1
@@ -147,7 +147,7 @@ static void damon_do_test_apply_three_regions(struct kunit *test,damon_add_region (r, t); } -damon_set_regions (t, three_regions,3 ,DAMON_MIN_REGION ); +damon_set_regions (t, three_regions,3 ,DAMON_MIN_REGION_SZ );for (i =0 ; i < nr_expected /2 ; i++) { r =__nth_region_of (t, i);
mm/damon/vaddr.c +12 -12
@@ -19,8 +19,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 /*
@@ -78,7 +78,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 ;
@@ -161,12 +161,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 ; }
@@ -259,8 +259,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++) {
@@ -299,7 +299,7 @@ static void damon_va_update(struct damon_ctx *ctx)damon_for_each_target (t, ctx) {if (damon_va_three_regions (t, three_regions))continue ; -damon_set_regions (t, three_regions,3 ,DAMON_MIN_REGION ); +damon_set_regions (t, three_regions,3 ,DAMON_MIN_REGION_SZ ); } }
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 2/3 mm/damon: rename min_sz_region of damon_ctx to min_region_sz
From: SeongJae Park <[email protected]>
[ Upstream commit cc1db8dff8e751ec3ab352483de366b7f23aefe2 ]
'min_sz_region' field of 'struct damon_ctx' represents the minimum size of each DAMON region for the context. 'struct damos_access_pattern' has a field of the same name. It confuses readers and makes 'grep' less optimal for them. Rename it to 'min_region_sz'.
Stable-dep-of: c80f46ac228b ("mm/damon/core: disallow non-power of two min_region_sz")
--- include/linux/damon.h | 8 ++--- mm/damon/core.c | 69 ++++++++++++++++++++++--------------------- mm/damon/lru_sort.c | 4 +-- mm/damon/reclaim.c | 4 +-- mm/damon/stat.c | 2 +- mm/damon/sysfs.c | 9 +++--- 6 files changed, 49 insertions(+), 47 deletions(-)
include/linux/damon.h +4 -4
@@ -769,7 +769,7 @@ struct damon_attrs {* * @ops: Set of monitoring operations for given use cases. * @addr_unit: Scale factor for core to ops address conversion. -* @min_sz_region: Minimum region size. +* @min_region_sz: Minimum region size. * @adaptive_targets: Head of monitoring targets (&damon_target) list. * @schemes: Head of schemes (&damos) list. */
@@ -812,7 +812,7 @@ struct damon_ctx {struct damon_operations ops;unsigned long addr_unit; -unsigned long min_sz_region; +unsigned long min_region_sz;struct list_head adaptive_targets;struct list_head schemes;
@@ -901,7 +901,7 @@ static inline void damon_insert_region(struct damon_region *r,void damon_add_region (struct damon_region *r,struct damon_target *t);void damon_destroy_region (struct damon_region *r,struct damon_target *t);int damon_set_regions (struct damon_target *t,struct damon_addr_range *ranges, -unsigned int nr_ranges,unsigned long min_sz_region); +unsigned int nr_ranges,unsigned long min_region_sz);void damon_update_region_access_rate (struct damon_region *r,bool accessed,struct damon_attrs *attrs);
@@ -968,7 +968,7 @@ int damos_walk(struct damon_ctx *ctx, struct damos_walk_control *control);int damon_set_region_biggest_system_ram_default (struct damon_target *t,unsigned long *start,unsigned long *end, -unsigned long min_sz_region); +unsigned long min_region_sz);#endif /* CONFIG_DAMON */
mm/damon/core.c +35 -34
235 lines not on this page · raw message
mm/damon/lru_sort.c +2 -2
@@ -212,7 +212,7 @@ static int damon_lru_sort_apply_parameters(void)if (!monitor_region_start && !monitor_region_end) addr_unit =1 ; param_ctx->addr_unit = addr_unit; - param_ctx->min_sz_region =max (DAMON_MIN_REGION_SZ / addr_unit,1 ); + param_ctx->min_region_sz =max (DAMON_MIN_REGION_SZ / addr_unit,1 );if (!damon_lru_sort_mon_attrs.sample_interval) { err = -EINVAL ;
@@ -243,7 +243,7 @@ static int damon_lru_sort_apply_parameters(void) err =damon_set_region_biggest_system_ram_default (param_target, &monitor_region_start, &monitor_region_end, - param_ctx->min_sz_region); + param_ctx->min_region_sz);if (err) goto out; err =damon_commit_ctx (ctx, param_ctx);
mm/damon/reclaim.c +2 -2
@@ -208,7 +208,7 @@ static int damon_reclaim_apply_parameters(void)if (!monitor_region_start && !monitor_region_end) addr_unit =1 ; param_ctx->addr_unit = addr_unit; - param_ctx->min_sz_region =max (DAMON_MIN_REGION_SZ / addr_unit,1 ); + param_ctx->min_region_sz =max (DAMON_MIN_REGION_SZ / addr_unit,1 );if (!damon_reclaim_mon_attrs.aggr_interval) { err = -EINVAL ;
@@ -251,7 +251,7 @@ static int damon_reclaim_apply_parameters(void) err =damon_set_region_biggest_system_ram_default (param_target, &monitor_region_start, &monitor_region_end, - param_ctx->min_sz_region); + param_ctx->min_region_sz);if (err) goto out; err =damon_commit_ctx (ctx, param_ctx);
mm/damon/stat.c +1 -1
@@ -189,7 +189,7 @@ static struct damon_ctx *damon_stat_build_ctx(void) goto free_out;damon_add_target (ctx, target);if (damon_set_region_biggest_system_ram_default (target, &start, &end, - ctx->min_sz_region)) + ctx->min_region_sz)) goto free_out;return ctx; free_out:
mm/damon/sysfs.c +5 -4
@@ -1365,7 +1365,7 @@ static int damon_sysfs_set_attrs(struct damon_ctx *ctx,static int damon_sysfs_set_regions (struct damon_target *t,struct damon_sysfs_regions *sysfs_regions, -unsigned long min_sz_region) +unsigned long min_region_sz) {struct damon_addr_range *ranges =kmalloc_array (sysfs_regions->nr,sizeof (*ranges),GFP_KERNEL | __GFP_NOWARN);
@@ -1387,7 +1387,7 @@ static int damon_sysfs_set_regions(struct damon_target *t,if (ranges[i -1 ].end > ranges[i].start) goto out; } - err =damon_set_regions (t, ranges, sysfs_regions->nr, min_sz_region); + err =damon_set_regions (t, ranges, sysfs_regions->nr, min_region_sz); out:kfree (ranges);return err;
@@ -1409,7 +1409,8 @@ static int damon_sysfs_add_target(struct damon_sysfs_target *sys_target,return -EINVAL ; } t->obsolete = sys_target->obsolete; -return damon_sysfs_set_regions (t, sys_target->regions, ctx->min_sz_region); +return damon_sysfs_set_regions (t, sys_target->regions, + ctx->min_region_sz); } static int damon_sysfs_add_targets(struct damon_ctx *ctx,
@@ -1469,7 +1470,7 @@ static int damon_sysfs_apply_inputs(struct damon_ctx *ctx, ctx->addr_unit = sys_ctx->addr_unit;/* addr_unit is respected by only DAMON_OPS_PADDR */ if (sys_ctx->ops_id ==DAMON_OPS_PADDR ) - ctx->min_sz_region =max ( + ctx->min_region_sz =max (DAMON_MIN_REGION_SZ / sys_ctx->addr_unit,1 ); err =damon_sysfs_set_attrs (ctx, sys_ctx->attrs);if (err)
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 3/3 mm/damon/core: disallow non-power of two min_region_sz
In reply to Sasha LevinFrom: SeongJae Park <[email protected]>
[ Upstream commit c80f46ac228b48403866d65391ad09bdf0e8562a ]
DAMON core uses min_region_sz parameter value as the DAMON region alignment. The alignment is made using ALIGN() and ALIGN_DOWN(), which support only the power of two alignments. But DAMON core API callers can set min_region_sz to an arbitrary number. Users can also set it indirectly, using addr_unit.
When the alignment is not properly set, DAMON behavior becomes difficult to expect and understand, makes it effectively broken. It doesn't cause a kernel crash-like significant issue, though.
Fix the issue by disallowing min_region_sz input that is not a power of two. Add the check to damon_commit_ctx(), as all DAMON API callers who set min_region_sz uses the function.
This can be a sort of behavioral change, but it does not break users, for the following reasons. As the symptom is making DAMON effectively broken, it is not reasonable to believe there are real use cases of non-power of two min_region_sz. There is no known use case or issue reports from the setup, either.
In future, if we find real use cases of non-power of two alignments and we can support it with low enough overhead, we can consider moving the restriction. But, for now, simply disallowing the corner case should be good enough as a hot fix.
--- mm/damon/core.c | 3 +++ 1 file changed, 3 insertions(+)
mm/damon/core.c +3 -0
@@ -1241,6 +1241,9 @@ int damon_commit_ctx(struct damon_ctx *dst, struct damon_ctx *src) {int err; +if (!is_power_of_2 (src->min_region_sz)) +return -EINVAL ; + err =damon_commit_schemes (dst, src);if (err)return err;
Signature · 1 line
2.51.0