]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mm/damon/core: add damon_target->obsolete for pin-point removal
authorSeongJae Park <sj@kernel.org>
Thu, 23 Oct 2025 01:25:25 +0000 (18:25 -0700)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 17 Nov 2025 01:28:23 +0000 (17:28 -0800)
Patch series "mm/damon: support pin-point targets removal".

DAMON maintains the targets in a list, and allows committing only an
entire list of targets having the new parameters.  Targets having same
index on the lists are treated as matching source and destination
targets.  If an existing target cannot find a matching one in the
sources list, the target is removed.  This means that there is no way to
remove only a specific monitoring target in the middle of the current
targets list.

Such pin-point target removal is really needed in some use cases,
though.  Monitoring access patterns on virtual address spaces of
processes that spawned from the same ancestor is one example.  If a
process of the group is terminated, the user may want to remove the
matching DAMON target as soon as possible, to save in-kernel memory
usage for the unnecessary target data.  The user may also want to do
that without turning DAMON off or removing unnecessary targets, to keep
the current monitoring results for other active processes.

Extend DAMON kernel API and sysfs ABI to support the pin-point removal
in the following way.  For API, add a new damon_target field, namely
'obsolete'.  If the field on parameters commit source target is set, it
means the matching destination target is obsolete.  Then the parameters
commit logic removes the destination target from the existing targets
list.  For sysfs ABI, add a new file under the target directory, namely
'obsolete_target'.  It is connected with the 'obsolete' field of the
commit source targets, so internally using the new API.

Also add a selftest for the new feature.  The related helper scripts for
manipulating the sysfs interface and dumping in-kernel DAMON status are
also extended for this.  Note that the selftest part was initially
posted as an individual RFC series [1], but now merged into this one.

Bijan Tabatabai has originally reported this issue, and participated in
this solution design on a GitHub issue [1] for DAMON user-space tool.

This patch (of 9):

DAMON's monitoring targets parameters update function,
damon_commit_targets(), is not providing a way to remove a target in the
middle of the existing targets list.  Extend the API by adding a field to
struct damon_target.  If the field of a damon_commit_targets() source
target is set, it indicates the matching target on the existing targets
list is obsolete.  damon_commit_targets() understands that and removes
those from the list, while respecting the index based matching for other
non-obsolete targets.

Link: https://lkml.kernel.org/r/20251023012535.69625-1-sj@kernel.org
Link: https://lkml.kernel.org/r/20251023012535.69625-2-sj@kernel.org
Link: https://github.com/damonitor/damo/issues/36
Signed-off-by: SeongJae Park <sj@kernel.org>
Reviewed-by: Bijan Tabatabai <bijan311@gmail.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
include/linux/damon.h
mm/damon/core.c

index 9ee026c2db53e2ec46476a8684aab9500b246051..f3566b978cdf3ae2dc22bebb3dd392f10b2ac2b5 100644 (file)
@@ -91,17 +91,23 @@ struct damon_region {
  * @nr_regions:                Number of monitoring target regions of this target.
  * @regions_list:      Head of the monitoring target regions of this target.
  * @list:              List head for siblings.
+ * @obsolete:          Whether the commit destination target is obsolete.
  *
  * Each monitoring context could have multiple targets.  For example, a context
  * for virtual memory address spaces could have multiple target processes.  The
  * @pid should be set for appropriate &struct damon_operations including the
  * virtual address spaces monitoring operations.
+ *
+ * @obsolete is used only for damon_commit_targets() source targets, to specify
+ * the matching destination targets are obsolete.  Read damon_commit_targets()
+ * to see how it is handled.
  */
 struct damon_target {
        struct pid *pid;
        unsigned int nr_regions;
        struct list_head regions_list;
        struct list_head list;
+       bool obsolete;
 };
 
 /**
index 769da97fcb260c3bf5171aa7c76bfef6127eee42..06ad359024ad621993c55a0c90a06f5c2c4c6363 100644 (file)
@@ -479,6 +479,7 @@ struct damon_target *damon_new_target(void)
        t->nr_regions = 0;
        INIT_LIST_HEAD(&t->regions_list);
        INIT_LIST_HEAD(&t->list);
+       t->obsolete = false;
 
        return t;
 }
@@ -1187,7 +1188,11 @@ static int damon_commit_targets(
 
        damon_for_each_target_safe(dst_target, next, dst) {
                src_target = damon_nth_target(i++, src);
-               if (src_target) {
+               /*
+                * If src target is obsolete, do not commit the parameters to
+                * the dst target, and further remove the dst target.
+                */
+               if (src_target && !src_target->obsolete) {
                        err = damon_commit_target(
                                        dst_target, damon_target_has_pid(dst),
                                        src_target, damon_target_has_pid(src),
@@ -1210,6 +1215,9 @@ static int damon_commit_targets(
        damon_for_each_target_safe(src_target, next, src) {
                if (j++ < i)
                        continue;
+               /* target to remove has no matching dst */
+               if (src_target->obsolete)
+                       return -EINVAL;
                new_target = damon_new_target();
                if (!new_target)
                        return -ENOMEM;