diff options
| author | SJ Park <sj@kernel.org> | 2026-07-10 06:46:36 -0700 |
|---|---|---|
| committer | Andrew Morton <akpm@linux-foundation.org> | 2026-08-04 19:18:50 -0700 |
| commit | e1f150d41516c192e3b78f360a7fb2dd9879abda (patch) | |
| tree | 36526c69c45cdfeca044e11cb9387901a882894b | |
| parent | 3858025f48cf764c3c653b311a1fa1b2eb720a5c (diff) | |
mm/damon/core: use abs_diff() instead of abs()
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.
Link: https://lore.kernel.org/20260710134651.18084-8-sj@kernel.org
Link: https://lore.kernel.org/20260705213817.100841-1-sj@kernel.org/ [1]
Signed-off-by: SJ Park <sj@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
| -rw-r--r-- | mm/damon/core.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/mm/damon/core.c b/mm/damon/core.c index fea97399b575..4c7e8a12a9b6 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 |
