diff options
author | Andrew Morton <akpm@linux-foundation.org> | 2024-07-06 11:44:41 -0700 |
---|---|---|
committer | Andrew Morton <akpm@linux-foundation.org> | 2024-07-06 11:44:41 -0700 |
commit | 8ef6fd0e9ea83a792ba53882ddc6e0d38ce0d636 (patch) | |
tree | b119eaeb76c7afb8672d30078ab7061cb7be67fb /mm/damon/core.c | |
parent | 44195d1eba826a8af0afbcfa69ab4cc26f6ead7f (diff) | |
parent | 1e3d28fe03cdac1f58402e4da1e1e59fb70d145f (diff) |
Merge branch 'mm-hotfixes-stable' into mm-stable to pick up "mm: fix
crashes from deferred split racing folio migration", needed by "mm:
migrate: split folio_migrate_mapping()".
Diffstat (limited to 'mm/damon/core.c')
-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 f69250b68bcc..7a87628b76ab 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -1694,14 +1694,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); } /* |