mm/damon/core: introduce damon_filter

Define a data structure for constructing damon_probe's attributes check,
namely damon_filter.  It is very similar to damos_filter but works only
for monitoring purposes.  Also embed that into damon_probe, implement
essential handling of the link, with fundamental helpers.

Link: https://lore.kernel.org/20260518234119.97569-4-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
SeongJae Park 2026-05-18 16:40:51 -07:00 committed by Andrew Morton
parent 18c777859f
commit f557693dd8
2 changed files with 66 additions and 0 deletions

View File

@ -730,12 +730,38 @@ struct damon_intervals_goal {
unsigned long max_sample_us;
};
/**
* enum damon_filter_type - Type of &struct damon_filter
*
* @DAMON_FILTER_TYPE_ANON: Anonymous pages.
*/
enum damon_filter_type {
DAMON_FILTER_TYPE_ANON,
};
/**
* struct damon_filter - DAMON region filter for &struct damon_probe.
*
* @type: Type of the region.
* @matching: Whether this filter is for the type-matching ones.
* @allow: Whether the @type-@matching ones should pass this filter.
* @list: Siblings list.
*/
struct damon_filter {
enum damon_filter_type type;
bool matching;
bool allow;
struct list_head list;
};
/**
* struct damon_probe - Data region attribute probe.
*
* @filters: Filters for assessing if a given region is for this probe.
* @list: Siblings list.
*/
struct damon_probe {
struct list_head filters;
struct list_head list;
};
@ -910,6 +936,12 @@ static inline unsigned long damon_sz_region(struct damon_region *r)
return r->ar.end - r->ar.start;
}
#define damon_for_each_filter(f, p) \
list_for_each_entry(f, &(p)->filters, list)
#define damon_for_each_filter_safe(f, next, p) \
list_for_each_entry_safe(f, next, &(p)->filters, list)
#define damon_for_each_probe(p, ctx) \
list_for_each_entry(p, &(ctx)->probes, list)
@ -957,6 +989,10 @@ static inline unsigned long damon_sz_region(struct damon_region *r)
#ifdef CONFIG_DAMON
struct damon_filter *damon_new_filter(enum damon_filter_type type,
bool matching, bool allow);
void damon_add_filter(struct damon_probe *probe, struct damon_filter *f);
struct damon_probe *damon_new_probe(void);
void damon_add_probe(struct damon_ctx *ctx, struct damon_probe *probe);

View File

@ -113,6 +113,31 @@ int damon_select_ops(struct damon_ctx *ctx, enum damon_ops_id id)
return err;
}
struct damon_filter *damon_new_filter(enum damon_filter_type type,
bool matching, bool allow)
{
struct damon_filter *filter;
filter = kmalloc_obj(*filter);
if (!filter)
return NULL;
filter->type = type;
filter->matching = matching;
filter->allow = allow;
INIT_LIST_HEAD(&filter->list);
return filter;
}
void damon_add_filter(struct damon_probe *p, struct damon_filter *f)
{
list_add_tail(&f->list, &p->filters);
}
static void damon_free_filter(struct damon_filter *f)
{
kfree(f);
}
struct damon_probe *damon_new_probe(void)
{
struct damon_probe *p;
@ -120,6 +145,7 @@ struct damon_probe *damon_new_probe(void)
p = kmalloc_obj(*p);
if (!p)
return NULL;
INIT_LIST_HEAD(&p->filters);
INIT_LIST_HEAD(&p->list);
return p;
}
@ -136,6 +162,10 @@ static void damon_del_probe(struct damon_probe *p)
static void damon_free_probe(struct damon_probe *p)
{
struct damon_filter *f, *next;
damon_for_each_filter_safe(f, next, p)
damon_free_filter(f);
kfree(p);
}