Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/damon: add a min_sz_region parameter to damon_set_region_biggest_system_ram_default()

Patch series "mm/damon: fixes for address alignment issues in
DAMON_LRU_SORT and DAMON_RECLAIM", v2.

In DAMON_LRU_SORT and DAMON_RECLAIM, damon_set_regions() will apply
DAMON_MIN_REGION as the core address alignment, and the monitoring target
address ranges would be aligned on DAMON_MIN_REGION * addr_unit. When
users 1) set addr_unit to a value larger than 1, and 2) set the monitoring
target address range as not aligned on DAMON_MIN_REGION * addr_unit, it
will cause DAMON_LRU_SORT and DAMON_RECLAIM to operate on unexpectedly
large physical address ranges.

For example, if the user sets the monitoring target address range to [4,
8) and addr_unit as 1024, the aimed monitoring target address range is [4
KiB, 8 KiB). Assuming DAMON_MIN_REGION is 4096, so resulting target
address range will be [0, 4096) in the DAMON core layer address system,
and [0, 4 MiB) in the physical address space, which is an unexpected
range.

To fix the issue, add a min_sz_region parameter to
damon_set_region_biggest_system_ram_default() and use it when calling
damon_set_regions(), replacing the direct use of DAMON_MIN_REGION.


This patch (of 2):

In DAMON_LRU_SORT, damon_set_regions() will apply DAMON_MIN_REGION as the
core address alignment, and the monitoring target address ranges would be
aligned on DAMON_MIN_REGION * addr_unit. When users 1) set addr_unit to a
value larger than 1, and 2) set the monitoring target address range as not
aligned on DAMON_MIN_REGION * addr_unit, it will cause DAMON_LRU_SORT to
operate on unexpectedly large physical address ranges.

For example, if the user sets the monitoring target address range to [4,
8) and addr_unit as 1024, the aimed monitoring target address range is [4
KiB, 8 KiB). Assuming DAMON_MIN_REGION is 4096, so resulting target
address range will be [0, 4096) in the DAMON core layer address system,
and [0, 4 MiB) in the physical address space, which is an unexpected
range.

To fix the issue, add a min_sz_region parameter to
damon_set_region_biggest_system_ram_default() and use it when calling
damon_set_regions(), replacing the direct use of DAMON_MIN_REGION.

Link: https://lkml.kernel.org/r/20251020130125.2875164-1-yanquanmin1@huawei.com
Link: https://lkml.kernel.org/r/20251020130125.2875164-2-yanquanmin1@huawei.com
Fixes: 2e0fe9245d6b ("mm/damon/lru_sort: support addr_unit for DAMON_LRU_SORT")
Signed-off-by: Quanmin Yan <yanquanmin1@huawei.com>
Reviewed-by: SeongJae Park <sj@kernel.org>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: ze zuo <zuoze1@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Quanmin Yan and committed by
Andrew Morton
e859a224 074f027d

+12 -6
+2 -1
include/linux/damon.h
··· 961 961 int damos_walk(struct damon_ctx *ctx, struct damos_walk_control *control); 962 962 963 963 int damon_set_region_biggest_system_ram_default(struct damon_target *t, 964 - unsigned long *start, unsigned long *end); 964 + unsigned long *start, unsigned long *end, 965 + unsigned long min_sz_region); 965 966 966 967 #endif /* CONFIG_DAMON */ 967 968
+4 -2
mm/damon/core.c
··· 2818 2818 * @t: The monitoring target to set the region. 2819 2819 * @start: The pointer to the start address of the region. 2820 2820 * @end: The pointer to the end address of the region. 2821 + * @min_sz_region: Minimum region size. 2821 2822 * 2822 2823 * This function sets the region of @t as requested by @start and @end. If the 2823 2824 * values of @start and @end are zero, however, this function finds the biggest ··· 2829 2828 * Return: 0 on success, negative error code otherwise. 2830 2829 */ 2831 2830 int damon_set_region_biggest_system_ram_default(struct damon_target *t, 2832 - unsigned long *start, unsigned long *end) 2831 + unsigned long *start, unsigned long *end, 2832 + unsigned long min_sz_region) 2833 2833 { 2834 2834 struct damon_addr_range addr_range; 2835 2835 ··· 2843 2841 2844 2842 addr_range.start = *start; 2845 2843 addr_range.end = *end; 2846 - return damon_set_regions(t, &addr_range, 1, DAMON_MIN_REGION); 2844 + return damon_set_regions(t, &addr_range, 1, min_sz_region); 2847 2845 } 2848 2846 2849 2847 /*
+2 -1
mm/damon/lru_sort.c
··· 242 242 243 243 err = damon_set_region_biggest_system_ram_default(param_target, 244 244 &monitor_region_start, 245 - &monitor_region_end); 245 + &monitor_region_end, 246 + param_ctx->min_sz_region); 246 247 if (err) 247 248 goto out; 248 249 err = damon_commit_ctx(ctx, param_ctx);
+2 -1
mm/damon/reclaim.c
··· 250 250 251 251 err = damon_set_region_biggest_system_ram_default(param_target, 252 252 &monitor_region_start, 253 - &monitor_region_end); 253 + &monitor_region_end, 254 + DAMON_MIN_REGION); 254 255 if (err) 255 256 goto out; 256 257 err = damon_commit_ctx(ctx, param_ctx);
+2 -1
mm/damon/stat.c
··· 188 188 if (!target) 189 189 goto free_out; 190 190 damon_add_target(ctx, target); 191 - if (damon_set_region_biggest_system_ram_default(target, &start, &end)) 191 + if (damon_set_region_biggest_system_ram_default(target, &start, &end, 192 + ctx->min_sz_region)) 192 193 goto free_out; 193 194 return ctx; 194 195 free_out: