diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:15:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-08-07 13:15:13 +0000 |
commit | 246dcf5ef201b8e7735b0894e18189c712374a0f (patch) | |
tree | 7b48ee473954dea09d91a84bb5bbf5b26c67b201 /mm/damon | |
parent | Adding debian version 6.9.9-1. (diff) | |
download | linux-246dcf5ef201b8e7735b0894e18189c712374a0f.tar.xz linux-246dcf5ef201b8e7735b0894e18189c712374a0f.zip |
Merging upstream version 6.9.10.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mm/damon')
-rw-r--r-- | mm/damon/core.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/mm/damon/core.c b/mm/damon/core.c index 6d503c1c12..d6f7e14abd 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -1357,14 +1357,31 @@ static void damon_merge_regions_of(struct damon_target *t, unsigned int thres, * access frequencies are similar. This is for minimizing the monitoring * overhead under the dynamically changeable access pattern. If a merge was * unnecessarily made, later 'kdamond_split_regions()' will revert it. + * + * The total number of regions could be higher than the user-defined limit, + * max_nr_regions for some cases. For example, the user can update + * max_nr_regions to a number that lower than the current number of regions + * while DAMON is running. For such a case, repeat merging until the limit is + * met while increasing @threshold up to possible maximum level. */ static void kdamond_merge_regions(struct damon_ctx *c, unsigned int threshold, unsigned long sz_limit) { struct damon_target *t; - - damon_for_each_target(t, c) - damon_merge_regions_of(t, threshold, sz_limit); + unsigned int nr_regions; + unsigned int max_thres; + + max_thres = c->attrs.aggr_interval / + (c->attrs.sample_interval ? c->attrs.sample_interval : 1); + do { + nr_regions = 0; + damon_for_each_target(t, c) { + damon_merge_regions_of(t, threshold, sz_limit); + nr_regions += damon_nr_regions(t); + } + threshold = max(1, threshold * 2); + } while (nr_regions > c->attrs.max_nr_regions && + threshold / 2 < max_thres); } /* |