[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251023012535.69625-4-sj@kernel.org>
Date: Wed, 22 Oct 2025 18:25:27 -0700
From: SeongJae Park <sj@...nel.org>
To: Andrew Morton <akpm@...ux-foundation.org>
Cc: SeongJae Park <sj@...nel.org>,
Bijan Tabatabai <bijan311@...il.com>,
damon@...ts.linux.dev,
linux-kernel@...r.kernel.org,
linux-mm@...ck.org
Subject: [PATCH 3/9] mm/damon/sysfs: implement obsolete_target file
There is no good way to remove DAMON targets in the middle of the
existing targets list. It restricts efficient and flexible DAMON use
cases. Improve the usability by implementing a new DAMON sysfs
interface file, namely obsolete_target, under each target directory. It
is connected to the obsolete field of parameters commit-source targets,
so allows removing arbitrary targets in the middle of existing targets
list.
Note that the sysfs files are not automatically updated. For example,
let's suppose there are three targets in the running context, and a user
removes the third target using this feature. If the user writes
'commit' to the kdamond 'state' file again, DAMON sysfs interface will
again try to remove the third target. But because there is no matching
target in the running context, the commit will fail. It is the user's
responsibility to understand resulting DAMON internal targets list
change, and construct sysfs files (using nr_targets and other sysfs
files) to correctly represent it.
Also note that this is arguably an improvement rather than a fix of
broken things.
Reported-by: Bijan Tabatabai <bijan311@...il.com>
Closes: https://github.com/damonitor/damo/issues/36
Signed-off-by: SeongJae Park <sj@...nel.org>
Reviewed-by: Bijan Tabatabai <bijan311@...il.com>
---
mm/damon/sysfs.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index 0fe6ea68d311..43ee9ce4dd84 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -212,6 +212,7 @@ struct damon_sysfs_target {
struct kobject kobj;
struct damon_sysfs_regions *regions;
int pid;
+ bool obsolete;
};
static struct damon_sysfs_target *damon_sysfs_target_alloc(void)
@@ -263,6 +264,29 @@ static ssize_t pid_target_store(struct kobject *kobj,
return count;
}
+static ssize_t obsolete_target_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_target *target = container_of(kobj,
+ struct damon_sysfs_target, kobj);
+
+ return sysfs_emit(buf, "%c\n", target->obsolete ? 'Y' : 'N');
+}
+
+static ssize_t obsolete_target_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_target *target = container_of(kobj,
+ struct damon_sysfs_target, kobj);
+ bool obsolete;
+ int err = kstrtobool(buf, &obsolete);
+
+ if (err)
+ return err;
+ target->obsolete = obsolete;
+ return count;
+}
+
static void damon_sysfs_target_release(struct kobject *kobj)
{
kfree(container_of(kobj, struct damon_sysfs_target, kobj));
@@ -271,8 +295,12 @@ static void damon_sysfs_target_release(struct kobject *kobj)
static struct kobj_attribute damon_sysfs_target_pid_attr =
__ATTR_RW_MODE(pid_target, 0600);
+static struct kobj_attribute damon_sysfs_target_obsolete_attr =
+ __ATTR_RW_MODE(obsolete_target, 0600);
+
static struct attribute *damon_sysfs_target_attrs[] = {
&damon_sysfs_target_pid_attr.attr,
+ &damon_sysfs_target_obsolete_attr.attr,
NULL,
};
ATTRIBUTE_GROUPS(damon_sysfs_target);
@@ -1377,6 +1405,7 @@ static int damon_sysfs_add_target(struct damon_sysfs_target *sys_target,
/* caller will destroy targets */
return -EINVAL;
}
+ t->obsolete = sys_target->obsolete;
return damon_sysfs_set_regions(t, sys_target->regions, ctx->min_sz_region);
}
--
2.47.3
Powered by blists - more mailing lists