[RFC PATCH v1.2 07/19] mm/damon/core: use abs_diff() instead of abs()

From: SJ Park

Date: Thu Jul 09 2026 - 10:15:33 EST


Use of abs() in damon_merge_regions_of() could cause a silent integer
overflow since the macro casts unsigned int to signed int. It is
unlikely to have such a large value for nr_accesses. Even though it
happens, the user impact is just degraded monitoring results. Users
showing bad monitoring results for weird setup is quite trivial. But
the code is obviously wrong. Use abs_diff() instead.

The issue was discovered [1] by Sashiko.

[1] https://lore.kernel.org/20260705213817.100841-1-sj@xxxxxxxxxx/

Signed-off-by: SJ Park <sj@xxxxxxxxxx>
---
mm/damon/core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/damon/core.c b/mm/damon/core.c
index fea97399b5754..4c7e8a12a9b67 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -3261,7 +3261,7 @@ static void damon_merge_regions_of(struct damon_target *t, unsigned int thres,
struct damon_region *r, *prev = NULL, *next;

damon_for_each_region_safe(r, next, t) {
- if (abs(r->nr_accesses - r->last_nr_accesses) > thres)
+ if (abs_diff(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;
@@ -3269,7 +3269,7 @@ static void damon_merge_regions_of(struct damon_target *t, unsigned int thres,
r->age++;

if (prev && prev->ar.end == r->ar.start &&
- abs(prev->nr_accesses - r->nr_accesses) <= thres &&
+ abs_diff(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
--
2.47.3