[RFC PATCH v2.2 02/28] mm/damon/core: embed damon_probe objects in damon_ctx
From: SeongJae Park
Date: Thu May 14 2026 - 20:45:39 EST
Let damon_probe objects be able to be installed on a given damon_ctx, by
adding a linked list header for storing the objects. Add initialization
and cleanup of the new field with helper functions, too.
Signed-off-by: SeongJae Park <sj@xxxxxxxxxx>
---
include/linux/damon.h | 9 +++++++++
mm/damon/core.c | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/include/linux/damon.h b/include/linux/damon.h
index a8fff5325b010..3ba5a31b51769 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -847,6 +847,7 @@ struct damon_ctx {
/* public: */
struct damon_operations ops;
+ struct list_head probes;
unsigned long addr_unit;
unsigned long min_region_sz;
@@ -879,6 +880,11 @@ static inline unsigned long damon_sz_region(struct damon_region *r)
return r->ar.end - r->ar.start;
}
+#define damon_for_each_probe(p, ctx) \
+ list_for_each_entry(p, &ctx->probes, list)
+
+#define damon_for_each_probe_safe(p, next, ctx) \
+ list_for_each_entry_safe(p, next, &ctx->probes, list)
#define damon_for_each_region(r, t) \
list_for_each_entry(r, &t->regions_list, list)
@@ -921,6 +927,9 @@ static inline unsigned long damon_sz_region(struct damon_region *r)
#ifdef CONFIG_DAMON
+struct damon_probe *damon_new_probe(void);
+void damon_add_probe(struct damon_ctx *ctx, struct damon_probe *probe);
+
struct damon_region *damon_new_region(unsigned long start, unsigned long end);
/*
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 3dbbbfdeff719..0e55fa70fa5b6 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -109,6 +109,38 @@ int damon_select_ops(struct damon_ctx *ctx, enum damon_ops_id id)
return err;
}
+struct damon_probe *damon_new_probe(void)
+{
+ struct damon_probe *p;
+
+ p = kmalloc_obj(*p);
+ if (!p)
+ return NULL;
+ INIT_LIST_HEAD(&p->list);
+ return p;
+}
+
+void damon_add_probe(struct damon_ctx *ctx, struct damon_probe *probe)
+{
+ list_add_tail(&probe->list, &ctx->probes);
+}
+
+static void damon_del_probe(struct damon_probe *p)
+{
+ list_del(&p->list);
+}
+
+static void damon_free_probe(struct damon_probe *p)
+{
+ kfree(p);
+}
+
+static void damon_destroy_probe(struct damon_probe *p)
+{
+ damon_del_probe(p);
+ damon_free_probe(p);
+}
+
#ifdef CONFIG_DAMON_DEBUG_SANITY
static void damon_verify_new_region(unsigned long start, unsigned long end)
{
@@ -601,6 +633,8 @@ struct damon_ctx *damon_new_ctx(void)
ctx->attrs.min_nr_regions = 10;
ctx->attrs.max_nr_regions = 1000;
+ INIT_LIST_HEAD(&ctx->probes);
+
ctx->addr_unit = 1;
ctx->min_region_sz = DAMON_MIN_REGION_SZ;
@@ -621,12 +655,16 @@ static void damon_destroy_targets(struct damon_ctx *ctx)
void damon_destroy_ctx(struct damon_ctx *ctx)
{
struct damos *s, *next_s;
+ struct damon_probe *p, *next_p;
damon_destroy_targets(ctx);
damon_for_each_scheme_safe(s, next_s, ctx)
damon_destroy_scheme(s);
+ damon_for_each_probe_safe(p, next_p, ctx)
+ damon_destroy_probe(p);
+
kfree(ctx);
}
--
2.47.3