[RFC PATCH v2.2 16/28] mm/damon/sysfs-schemes: implement probe dir

From: SeongJae Park

Date: Thu May 14 2026 - 20:56:35 EST


Implement sysfs directory for showing per-probe hits count of each
region.

Signed-off-by: SeongJae Park <sj@xxxxxxxxxx>
---
mm/damon/sysfs-schemes.c | 101 ++++++++++++++++++++++++++++++++++++---
1 file changed, 95 insertions(+), 6 deletions(-)

diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c
index 0bca89217b8fa..a83512f28c022 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -10,12 +10,40 @@

#include "sysfs-common.h"

+/*
+ * probe directory
+ */
+
+struct damos_sysfs_probe {
+ struct kobject kobj;
+};
+
+static struct damos_sysfs_probe *damos_sysfs_probe_alloc(void)
+{
+ return kzalloc_obj(struct damos_sysfs_probe);
+}
+
+static void damos_sysfs_probe_release(struct kobject *kobj)
+{
+ struct damos_sysfs_probe *probe = container_of(kobj,
+ struct damos_sysfs_probe, kobj);
+
+ kfree(probe);
+}
+
+static const struct kobj_type damos_sysfs_probe_ktype = {
+ .release = damos_sysfs_probe_release,
+ .sysfs_ops = &kobj_sysfs_ops,
+};
+
/*
* probes directory
*/

struct damos_sysfs_probes {
struct kobject kobj;
+ struct damos_sysfs_probe **probes_arr;
+ int nr;
};

static struct damos_sysfs_probes *damos_sysfs_probes_alloc(void)
@@ -23,6 +51,60 @@ static struct damos_sysfs_probes *damos_sysfs_probes_alloc(void)
return kzalloc_obj(struct damos_sysfs_probes);
}

+static void damos_sysfs_probes_rm_dirs(struct damos_sysfs_probes *probes)
+{
+ struct damos_sysfs_probe **probes_arr = probes->probes_arr;
+ int i;
+
+ for (i = 0; i < probes->nr; i++)
+ kobject_put(&probes_arr[i]->kobj);
+ probes->nr = 0;
+ kfree(probes_arr);
+ probes->probes_arr = NULL;
+}
+
+static int damos_sysfs_probes_add_dirs(struct damos_sysfs_probes *probes,
+ struct damon_ctx *ctx)
+{
+ struct damon_probe *probe;
+ struct damos_sysfs_probe **probes_arr;
+ int i = 0;
+
+ damon_for_each_probe(probe, ctx)
+ i++;
+
+ if (!i)
+ return 0;
+
+ probes_arr = kmalloc_objs(*probes_arr, i);
+ if (!probes_arr)
+ return -ENOMEM;
+ probes->probes_arr = probes_arr;
+
+ i = 0;
+ damon_for_each_probe(probe, ctx) {
+ struct damos_sysfs_probe *sys_probe;
+ int err;
+
+ sys_probe = damos_sysfs_probe_alloc();
+ if (!sys_probe) {
+ damos_sysfs_probes_rm_dirs(probes);
+ return -ENOMEM;
+ }
+ err = kobject_init_and_add(&sys_probe->kobj,
+ &damos_sysfs_probe_ktype, &probes->kobj, "%d",
+ i);
+ if (err) {
+ kobject_put(&sys_probe->kobj);
+ damos_sysfs_probes_rm_dirs(probes);
+ return err;
+ }
+ probes_arr[i++] = sys_probe;
+ probes->nr++;
+ }
+ return 0;
+}
+
static void damos_sysfs_probes_release(struct kobject *kobj)
{
struct damos_sysfs_probes *probes = container_of(kobj,
@@ -67,7 +149,8 @@ static struct damon_sysfs_scheme_region *damon_sysfs_scheme_region_alloc(
}

static int damos_sysfs_region_add_dirs(
- struct damon_sysfs_scheme_region *region)
+ struct damon_sysfs_scheme_region *region,
+ struct damon_ctx *ctx)
{
struct damos_sysfs_probes *probes = damos_sysfs_probes_alloc();
int err;
@@ -76,18 +159,24 @@ static int damos_sysfs_region_add_dirs(
return -ENOMEM;
err = kobject_init_and_add(&probes->kobj, &damos_sysfs_probes_ktype,
&region->kobj, "probes");
- if (err) {
- kobject_put(&probes->kobj);
- return err;
- }
+ if (err)
+ goto fail;
+ err = damos_sysfs_probes_add_dirs(probes, ctx);
+ if (err)
+ goto fail;

region->probes = probes;
return 0;
+
+fail:
+ kobject_put(&probes->kobj);
+ return err;
}

static void damos_sysfs_region_rm_dirs(
struct damon_sysfs_scheme_region *region)
{
+ damos_sysfs_probes_rm_dirs(region->probes);
kobject_put(&region->probes->kobj);
}

@@ -2988,7 +3077,7 @@ void damos_sysfs_populate_region_dir(struct damon_sysfs_schemes *sysfs_schemes,
&sysfs_regions->kobj, "%d",
sysfs_regions->nr_regions++))
goto out;
- if (damos_sysfs_region_add_dirs(region))
+ if (damos_sysfs_region_add_dirs(region, ctx))
goto out;
return;

--
2.47.3