diff options
author | SeongJae Park <sj@kernel.org> | 2023-08-02 21:43:07 +0000 |
---|---|---|
committer | Andrew Morton <akpm@linux-foundation.org> | 2023-08-21 13:37:37 -0700 |
commit | 17e7c724d3c2e622c4d9969b7a473e8ed1d14ff0 (patch) | |
tree | 475b0a3aed6e47fda06c9ed6fdb3c874f901a56f /mm/damon | |
parent | 375af850385c787fc7115bf304c48b475818e5e4 (diff) | |
download | lwn-17e7c724d3c2e622c4d9969b7a473e8ed1d14ff0.tar.gz lwn-17e7c724d3c2e622c4d9969b7a473e8ed1d14ff0.zip |
mm/damon/core: implement target type damos filter
One DAMON context can have multiple monitoring targets, and DAMOS schemes
are applied to all targets. In some cases, users need to apply different
scheme to different targets. Retrieving monitoring results via DAMON
sysfs interface' 'tried_regions' directory could be one good example.
Also, there could be cases that cgroup DAMOS filter is not enough. All
such use cases can be worked around by having multiple DAMON contexts
having only single target, but it is inefficient in terms of resource
usage, thogh the overhead is not estimated to be huge.
Implement DAMON monitoring target based DAMOS filter for the case. Like
address range target DAMOS filter, handle these filters in the DAMON core
layer, since it is more efficient than doing in operations set layer.
This also means that regions that filtered out by monitoring target type
DAMOS filters are counted as not tried by the scheme. Hence, target
granularity monitoring results retrieval via DAMON sysfs interface becomes
available.
Link: https://lkml.kernel.org/r/20230802214312.110532-9-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Brendan Higgins <brendanhiggins@google.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'mm/damon')
-rw-r--r-- | mm/damon/core.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/mm/damon/core.c b/mm/damon/core.c index 68a5fb1c039d..c1f1483c5082 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -877,13 +877,23 @@ static void damos_update_stat(struct damos *s, s->stat.sz_applied += sz_applied; } -static bool __damos_filter_out(struct damon_target *t, struct damon_region *r, - struct damos_filter *filter) +static bool __damos_filter_out(struct damon_ctx *ctx, struct damon_target *t, + struct damon_region *r, struct damos_filter *filter) { bool matched = false; + struct damon_target *ti; + int target_idx = 0; unsigned long start, end; switch (filter->type) { + case DAMOS_FILTER_TYPE_TARGET: + damon_for_each_target(ti, ctx) { + if (ti == t) + break; + target_idx++; + } + matched = target_idx == filter->target_idx; + break; case DAMOS_FILTER_TYPE_ADDR: start = ALIGN_DOWN(filter->addr_range.start, DAMON_MIN_REGION); end = ALIGN_DOWN(filter->addr_range.end, DAMON_MIN_REGION); @@ -915,13 +925,13 @@ static bool __damos_filter_out(struct damon_target *t, struct damon_region *r, return matched == filter->matching; } -static bool damos_filter_out(struct damon_target *t, struct damon_region *r, - struct damos *s) +static bool damos_filter_out(struct damon_ctx *ctx, struct damon_target *t, + struct damon_region *r, struct damos *s) { struct damos_filter *filter; damos_for_each_filter(filter, s) { - if (__damos_filter_out(t, r, filter)) + if (__damos_filter_out(ctx, t, r, filter)) return true; } return false; @@ -944,7 +954,7 @@ static void damos_apply_scheme(struct damon_ctx *c, struct damon_target *t, goto update_stat; damon_split_region_at(t, r, sz); } - if (damos_filter_out(t, r, s)) + if (damos_filter_out(c, t, r, s)) return; ktime_get_coarse_ts64(&begin); if (c->callback.before_damos_apply) |