summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeongJae Park <sj@kernel.org>2026-05-22 08:40:13 -0700
committerAndrew Morton <akpm@linux-foundation.org>2026-06-04 14:45:00 -0700
commitb23dbda659b645482e3234ad10773d991a288e2f (patch)
treec8f5bfedbd97d9f0e9a65dd7c95d0460454685f3
parentce71e5aa8dc83e703a5301644cef57dfc3caaf44 (diff)
downloadlinux-b23dbda659b645482e3234ad10773d991a288e2f.tar.gz
linux-b23dbda659b645482e3234ad10773d991a288e2f.zip
mm/damon/core: do not use region out of a loop in damon_set_regions()
damon_set_regions() assumes the DAMON region iterator is referencing the last region after the region iteration loop is completed. The code is indeed implemented in the way, but that is not a documented safe behavior. Hence it is unreliable and difficult to read. Cleanup the code to avoid the case. No behavioral change is intended. Link: https://lore.kernel.org/20260522154026.80546-3-sj@kernel.org Signed-off-by: SeongJae Park <sj@kernel.org> Cc: Brendan Higgins <brendan.higgins@linux.dev> Cc: Shuah Khan <shuah@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-rw-r--r--mm/damon/core.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 8360cb4c506e..c9946ac8e279 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -374,6 +374,7 @@ int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
for (i = 0; i < nr_ranges; i++) {
struct damon_region *first = NULL, *last, *newr;
struct damon_addr_range *range;
+ bool insert_before_r = false;
range = &ranges[i];
/* Get the first/last regions intersecting with the range */
@@ -383,8 +384,10 @@ int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
first = r;
last = r;
}
- if (r->ar.start >= range->end)
+ if (r->ar.start >= range->end) {
+ insert_before_r = true;
break;
+ }
}
if (!first) {
/* no region intersects with this range */
@@ -394,7 +397,11 @@ int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges,
ALIGN(range->end, min_region_sz));
if (!newr)
return -ENOMEM;
- damon_insert_region(newr, damon_prev_region(r), r, t);
+ if (insert_before_r)
+ damon_insert_region(newr, damon_prev_region(r),
+ r, t);
+ else
+ damon_add_region(newr, t);
} else {
/* resize intersecting regions to fit in this range */
first->ar.start = ALIGN_DOWN(range->start,