Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Jiayuan Chen <jiayuan.chen@linux.dev>
To: damon@lists.linux.dev
Cc: jiayuan.chen@linux.dev, Jiayuan Chen <jiayuan.chen@shopee.com>,
	SeongJae Park <sj@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	David Hildenbrand <david@kernel.org>,
	Lorenzo Stoakes <ljs@kernel.org>,
	"Liam R. Howlett" <liam@infradead.org>,
	Vlastimil Babka <vbabka@kernel.org>,
	Mike Rapoport <rppt@kernel.org>,
	Suren Baghdasaryan <surenb@google.com>,
	Michal Hocko <mhocko@suse.com>, Jonathan Corbet <corbet@lwn.net>,
	Shuah Khan <skhan@linuxfoundation.org>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	linux-doc@vger.kernel.org
Subject: [PATCH 2/2] mm/damon/sysfs-schemes: report the number of tried regions
Date: Mon, 27 Jul 2026 17:54:23 +0800	[thread overview]
Message-ID: <20260727095429.143527-2-jiayuan.chen@linux.dev> (raw)
In-Reply-To: <20260727095429.143527-1-jiayuan.chen@linux.dev>

From: Jiayuan Chen <jiayuan.chen@shopee.com>

The 'tried_regions' directory of each DAMON sysfs scheme exposes the memory
regions that the scheme's action has been tried to be applied to, as
per-region subdirectories.  It also has a 'total_bytes' file that reports
the total size of those regions without materializing the per-region
subdirectories, so that users can cheaply retrieve the aggregated result.

The number of the tried regions is another useful aggregated metric.  When
the scheme's access pattern is not restrictive, it approximates the number
of the adaptive monitoring regions of the context, which users may want to
watch, e.g., to see how well the monitoring is refined under a given
max_nr_regions, or to feed fleet wide access pattern dashboards.
Retrieving it currently requires materializing all the per-region
subdirectories (via writing 'update_schemes_tried_regions') and counting
them, which is unnecessarily expensive for users that only need the count.

Add a 'nr_regions' file to the 'tried_regions' directory.  Like
'total_bytes', it is updated by both 'update_schemes_tried_bytes' and
'update_schemes_tried_regions', so it can be read as a lightweight counter
without materializing the per-region subdirectories.

Suggested-by: SeongJae Park <sj@kernel.org>
Cc: Jiayuan Chen <jiayuan.chen@linux.dev>
Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>
---
 .../ABI/testing/sysfs-kernel-mm-damon         | 10 +++++++
 Documentation/admin-guide/mm/damon/usage.rst  | 27 ++++++++++---------
 mm/damon/sysfs-schemes.c                      | 23 +++++++++++++---
 3 files changed, 45 insertions(+), 15 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-kernel-mm-damon b/Documentation/ABI/testing/sysfs-kernel-mm-damon
index 786be4537da1..a6e8f5036555 100644
--- a/Documentation/ABI/testing/sysfs-kernel-mm-damon
+++ b/Documentation/ABI/testing/sysfs-kernel-mm-damon
@@ -622,6 +622,16 @@ Description:	Writing a number to this file sets the upper limit of
 		nr_snapshots that deactivates the scheme when the limit is
 		reached or exceeded.
 
+What:		/sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/tried_regions/nr_regions
+Date:		Aug 2026
+Contact:	SJ Park <sj@kernel.org>
+Description:	Reading this file returns the number of regions that
+		corresponding DAMON-based Operation Scheme's action has tried
+		to be applied.  The number is updated together with
+		'.../tried_regions/total_bytes' by writing 'update_schemes_tried_bytes'
+		or 'update_schemes_tried_regions' to the relevant 'state' file, and
+		hence can be read without materializing the per-region directories.
+
 What:		/sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/schemes/<S>/tried_regions/total_bytes
 Date:		Jul 2023
 Contact:	SJ Park <sj@kernel.org>
diff --git a/Documentation/admin-guide/mm/damon/usage.rst b/Documentation/admin-guide/mm/damon/usage.rst
index f6048fc04263..9152ce09de9d 100644
--- a/Documentation/admin-guide/mm/damon/usage.rst
+++ b/Documentation/admin-guide/mm/damon/usage.rst
@@ -108,7 +108,7 @@ comma (",").
     │ │ │ │ │ │ │ :ref:`dests <damon_sysfs_dests>`/nr_dests
     │ │ │ │ │ │ │ │ 0/id,weight
     │ │ │ │ │ │ │ :ref:`stats <sysfs_schemes_stats>`/nr_tried,sz_tried,nr_applied,sz_applied,sz_ops_filter_passed,qt_exceeds,nr_snapshots,max_nr_snapshots
-    │ │ │ │ │ │ │ :ref:`tried_regions <sysfs_schemes_tried_regions>`/total_bytes
+    │ │ │ │ │ │ │ :ref:`tried_regions <sysfs_schemes_tried_regions>`/nr_regions,total_bytes
     │ │ │ │ │ │ │ │ 0/start,end,nr_accesses,age,sz_filter_passed
     │ │ │ │ │ │ │ │ │ probes
     │ │ │ │ │ │ │ │ │ │ 0/hits
@@ -671,21 +671,24 @@ relevant ``kdamonds/<N>/state`` file.  Refer to :ref:`kdamond directory
 schemes/<N>/tried_regions/
 --------------------------
 
-This directory initially has one file, ``total_bytes``.
+This directory initially has two files, ``nr_regions`` and ``total_bytes``.
 
 When a special keyword, ``update_schemes_tried_regions``, is written to the
-relevant ``kdamonds/<N>/state`` file, DAMON updates the ``total_bytes`` file so
-that reading it returns the total size of the scheme tried regions, and creates
-directories named integer starting from ``0`` under this directory.  Each
-directory contains files exposing detailed information about each of the memory
-region that the corresponding scheme's ``action`` has tried to be applied under
-this directory, during next :ref:`apply interval <damon_design_damos>` of the
-corresponding scheme.  The information includes address range, ``nr_accesses``,
-and ``age`` of the region.
+relevant ``kdamonds/<N>/state`` file, DAMON updates the ``nr_regions`` and
+``total_bytes`` files so that reading them returns the number and the total size
+of the scheme tried regions, respectively, and creates directories named
+integer starting from ``0`` under this directory.  Each directory contains files
+exposing detailed information about each of the memory region that the
+corresponding scheme's ``action`` has tried to be applied under this directory,
+during next :ref:`apply interval <damon_design_damos>` of the corresponding
+scheme.  The information includes address range, ``nr_accesses``, and ``age`` of
+the region.
 
 Writing ``update_schemes_tried_bytes`` to the relevant ``kdamonds/<N>/state``
-file will only update the ``total_bytes`` file, and will not create the
-subdirectories.
+file will only update the ``nr_regions`` and ``total_bytes`` files, and will not
+create the subdirectories.  Hence ``nr_regions`` can be used as a lightweight way
+to read the number of the scheme tried regions without materializing the
+per-region subdirectories.
 
 The directories will be removed when another special keyword,
 ``clear_schemes_tried_regions``, is written to the relevant
diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c
index 54ff196f8e24..b1df9f21c267 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -297,6 +297,7 @@ static const struct kobj_type damon_sysfs_scheme_region_ktype = {
 struct damon_sysfs_scheme_regions {
 	struct kobject kobj;
 	struct list_head regions_list;
+	int nr_region_dirs;
 	int nr_regions;
 	unsigned long total_bytes;
 };
@@ -311,11 +312,21 @@ damon_sysfs_scheme_regions_alloc(void)
 
 	regions->kobj = (struct kobject){};
 	INIT_LIST_HEAD(&regions->regions_list);
+	regions->nr_region_dirs = 0;
 	regions->nr_regions = 0;
 	regions->total_bytes = 0;
 	return regions;
 }
 
+static ssize_t nr_regions_show(struct kobject *kobj,
+			       struct kobj_attribute *attr, char *buf)
+{
+	struct damon_sysfs_scheme_regions *regions = container_of(kobj,
+			struct damon_sysfs_scheme_regions, kobj);
+
+	return sysfs_emit(buf, "%d\n", regions->nr_regions);
+}
+
 static ssize_t total_bytes_show(struct kobject *kobj,
 		struct kobj_attribute *attr, char *buf)
 {
@@ -335,7 +346,7 @@ static void damon_sysfs_scheme_regions_rm_dirs(
 		list_del(&r->list);
 		kobject_del(&r->kobj);
 		kobject_put(&r->kobj);
-		regions->nr_regions--;
+		regions->nr_region_dirs--;
 	}
 }
 
@@ -344,10 +355,14 @@ static void damon_sysfs_scheme_regions_release(struct kobject *kobj)
 	kfree(container_of(kobj, struct damon_sysfs_scheme_regions, kobj));
 }
 
+static struct kobj_attribute damon_sysfs_scheme_regions_nr_regions_attr =
+		__ATTR_RO_MODE(nr_regions, 0400);
+
 static struct kobj_attribute damon_sysfs_scheme_regions_total_bytes_attr =
 		__ATTR_RO_MODE(total_bytes, 0400);
 
 static struct attribute *damon_sysfs_scheme_regions_attrs[] = {
+	&damon_sysfs_scheme_regions_nr_regions_attr.attr,
 	&damon_sysfs_scheme_regions_total_bytes_attr.attr,
 	NULL,
 };
@@ -3133,6 +3148,7 @@ void damos_sysfs_populate_region_dir(struct damon_sysfs_schemes *sysfs_schemes,
 		return;
 
 	sysfs_regions = sysfs_schemes->schemes_arr[schemes_idx]->tried_regions;
+	sysfs_regions->nr_regions++;
 	sysfs_regions->total_bytes += r->ar.end - r->ar.start;
 	if (total_bytes_only)
 		return;
@@ -3144,13 +3160,13 @@ void damos_sysfs_populate_region_dir(struct damon_sysfs_schemes *sysfs_schemes,
 	if (kobject_init_and_add(&region->kobj,
 				&damon_sysfs_scheme_region_ktype,
 				&sysfs_regions->kobj, "%d",
-				sysfs_regions->nr_regions))
+				sysfs_regions->nr_region_dirs))
 		goto out;
 	if (damos_sysfs_region_add_dirs(region, ctx, r))
 		goto del_out;
 
 	list_add_tail(&region->list, &sysfs_regions->regions_list);
-	sysfs_regions->nr_regions++;
+	sysfs_regions->nr_region_dirs++;
 	return;
 
 del_out:
@@ -3170,6 +3186,7 @@ int damon_sysfs_schemes_clear_regions(
 		sysfs_scheme = sysfs_schemes->schemes_arr[i];
 		damon_sysfs_scheme_regions_rm_dirs(
 				sysfs_scheme->tried_regions);
+		sysfs_scheme->tried_regions->nr_regions = 0;
 		sysfs_scheme->tried_regions->total_bytes = 0;
 	}
 	return 0;
-- 
2.43.0



  reply	other threads:[~2026-07-27  9:55 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-27  9:54 [PATCH 1/2] mm/damon/core: cover discrete System RAM areas with per-range regions Jiayuan Chen
2026-07-27  9:54 ` Jiayuan Chen [this message]
2026-07-27 14:34   ` [PATCH 2/2] mm/damon/sysfs-schemes: report the number of tried regions SJ Park
2026-07-27 14:26 ` [PATCH 1/2] mm/damon/core: cover discrete System RAM areas with per-range regions SJ Park

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260727095429.143527-2-jiayuan.chen@linux.dev \
    --to=jiayuan.chen@linux.dev \
    --cc=akpm@linux-foundation.org \
    --cc=corbet@lwn.net \
    --cc=damon@lists.linux.dev \
    --cc=david@kernel.org \
    --cc=jiayuan.chen@shopee.com \
    --cc=liam@infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=mhocko@suse.com \
    --cc=rppt@kernel.org \
    --cc=sj@kernel.org \
    --cc=skhan@linuxfoundation.org \
    --cc=surenb@google.com \
    --cc=vbabka@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox