summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/damon.h6
-rw-r--r--mm/damon/core.c22
2 files changed, 22 insertions, 6 deletions
diff --git a/include/linux/damon.h b/include/linux/damon.h
index 476f37a883a4..ae2664d1d5f1 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -227,6 +227,7 @@ struct damos_stat {
* @DAMOS_FILTER_TYPE_ANON: Anonymous pages.
* @DAMOS_FILTER_TYPE_MEMCG: Specific memcg's pages.
* @DAMOS_FILTER_TYPE_ADDR: Address range.
+ * @DAMOS_FILTER_TYPE_TARGET: Data Access Monitoring target.
* @NR_DAMOS_FILTER_TYPES: Number of filter types.
*
* The anon pages type and memcg type filters are handled by underlying
@@ -244,6 +245,7 @@ enum damos_filter_type {
DAMOS_FILTER_TYPE_ANON,
DAMOS_FILTER_TYPE_MEMCG,
DAMOS_FILTER_TYPE_ADDR,
+ DAMOS_FILTER_TYPE_TARGET,
NR_DAMOS_FILTER_TYPES,
};
@@ -253,6 +255,9 @@ enum damos_filter_type {
* @matching: If the matching page should filtered out or in.
* @memcg_id: Memcg id of the question if @type is DAMOS_FILTER_MEMCG.
* @addr_range: Address range if @type is DAMOS_FILTER_TYPE_ADDR.
+ * @target_idx: Index of the &struct damon_target of
+ * &damon_ctx->adaptive_targets if @type is
+ * DAMOS_FILTER_TYPE_TARGET.
* @list: List head for siblings.
*
* Before applying the &damos->action to a memory region, DAMOS checks if each
@@ -266,6 +271,7 @@ struct damos_filter {
union {
unsigned short memcg_id;
struct damon_addr_range addr_range;
+ int target_idx;
};
struct list_head list;
};
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)