* [RFC PATCH v2.1 01/17] mm/damon/core: introduce DAMON_FILTER_TYPE_PGIDLE_UNSET
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:47 ` sashiko-bot
2026-07-27 14:38 ` [RFC PATCH v2.1 02/17] mm/damon/paddr: support PGIDLE_UNSET probe filter type SJ Park
` (15 subsequent siblings)
16 siblings, 1 reply; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, damon, linux-kernel, linux-mm
Introduce a new DAMON filter type, pgidle_unset. It will match pages
that have their PG_Idle flag unset, or the page table accessed bit set.
In other words, it says if the page is accessed.
Signed-off-by: SJ Park <sj@kernel.org>
---
include/linux/damon.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/linux/damon.h b/include/linux/damon.h
index 8ad6ef2e063de..cee4b74761081 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -744,12 +744,14 @@ struct damon_intervals_goal {
/**
* enum damon_filter_type - Type of &struct damon_filter
*
- * @DAMON_FILTER_TYPE_ANON: Anonymous pages.
- * @DAMON_FILTER_TYPE_MEMCG: Specific memcg's pages.
+ * @DAMON_FILTER_TYPE_ANON: Anonymous pages.
+ * @DAMON_FILTER_TYPE_MEMCG: Specific memcg's pages.
+ * @DAMON_FILTER_TYPE_PGIDLE_UNSET: Pgidle is unset.
*/
enum damon_filter_type {
DAMON_FILTER_TYPE_ANON,
DAMON_FILTER_TYPE_MEMCG,
+ DAMON_FILTER_TYPE_PGIDLE_UNSET,
};
/**
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* Re: [RFC PATCH v2.1 01/17] mm/damon/core: introduce DAMON_FILTER_TYPE_PGIDLE_UNSET
2026-07-27 14:38 ` [RFC PATCH v2.1 01/17] mm/damon/core: introduce DAMON_FILTER_TYPE_PGIDLE_UNSET SJ Park
@ 2026-07-27 14:47 ` sashiko-bot
2026-07-27 14:58 ` SJ Park
0 siblings, 1 reply; 26+ messages in thread
From: sashiko-bot @ 2026-07-27 14:47 UTC (permalink / raw)
To: SJ Park; +Cc: damon
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The patch introduces `DAMON_FILTER_TYPE_PGIDLE_UNSET` but fails to implement its matching logic or expose it via sysfs.
--
--- Patch [1]: [RFC PATCH v2.1 01/17] mm/damon/core: introduce DAMON_FILTER_TYPE_PGIDLE_UNSET ---
commit 713d89253715d0f67d20248547ddafe132444f89
Author: SJ Park <sj@kernel.org>
mm/damon/core: introduce DAMON_FILTER_TYPE_PGIDLE_UNSET
This commit introduces a new DAMON filter type, pgidle_unset. It is intended
to match pages that have their PG_Idle flag unset or the page table accessed
bit set.
> diff --git a/include/linux/damon.h b/include/linux/damon.h
> index 0c8b7ddef9abb..a8bb9ee6979e3 100644
> --- a/include/linux/damon.h
> +++ b/include/linux/damon.h
> @@ -742,12 +742,14 @@ struct damon_intervals_goal {
> /**
> * enum damon_filter_type - Type of &struct damon_filter
> *
> - * @DAMON_FILTER_TYPE_ANON: Anonymous pages.
> - * @DAMON_FILTER_TYPE_MEMCG: Specific memcg's pages.
> + * @DAMON_FILTER_TYPE_ANON: Anonymous pages.
> + * @DAMON_FILTER_TYPE_MEMCG: Specific memcg's pages.
> + * @DAMON_FILTER_TYPE_PGIDLE_UNSET: Pgidle is unset.
> */
> enum damon_filter_type {
> DAMON_FILTER_TYPE_ANON,
> DAMON_FILTER_TYPE_MEMCG,
> + DAMON_FILTER_TYPE_PGIDLE_UNSET,
[Severity: Medium]
Are the corresponding implementation details for this new filter type missing
from this patch?
The commit message states this will match pages that have their PG_Idle flag
unset, but the new DAMON_FILTER_TYPE_PGIDLE_UNSET variant doesn't appear to
be handled in the switch block evaluating filter types within
damon_pa_filter_match() in mm/damon/paddr.c.
Additionally, should this be exposed to userspace? The new filter type is
not mapped in damon_sysfs_filter_type_names in mm/damon/sysfs.c, which would
prevent it from being configured via sysfs.
> };
>
> /**
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727143829.86236-1-sj@kernel.org?part=1
^ permalink raw reply [flat|nested] 26+ messages in thread* Re: [RFC PATCH v2.1 01/17] mm/damon/core: introduce DAMON_FILTER_TYPE_PGIDLE_UNSET
2026-07-27 14:47 ` sashiko-bot
@ 2026-07-27 14:58 ` SJ Park
0 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:58 UTC (permalink / raw)
To: sashiko-bot; +Cc: SJ Park, damon
On Mon, 27 Jul 2026 14:47:13 +0000 sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] The patch introduces `DAMON_FILTER_TYPE_PGIDLE_UNSET` but fails to implement its matching logic or expose it via sysfs.
> --
>
> --- Patch [1]: [RFC PATCH v2.1 01/17] mm/damon/core: introduce DAMON_FILTER_TYPE_PGIDLE_UNSET ---
> commit 713d89253715d0f67d20248547ddafe132444f89
> Author: SJ Park <sj@kernel.org>
>
> mm/damon/core: introduce DAMON_FILTER_TYPE_PGIDLE_UNSET
>
> This commit introduces a new DAMON filter type, pgidle_unset. It is intended
> to match pages that have their PG_Idle flag unset or the page table accessed
> bit set.
>
> > diff --git a/include/linux/damon.h b/include/linux/damon.h
> > index 0c8b7ddef9abb..a8bb9ee6979e3 100644
> > --- a/include/linux/damon.h
> > +++ b/include/linux/damon.h
> > @@ -742,12 +742,14 @@ struct damon_intervals_goal {
> > /**
> > * enum damon_filter_type - Type of &struct damon_filter
> > *
> > - * @DAMON_FILTER_TYPE_ANON: Anonymous pages.
> > - * @DAMON_FILTER_TYPE_MEMCG: Specific memcg's pages.
> > + * @DAMON_FILTER_TYPE_ANON: Anonymous pages.
> > + * @DAMON_FILTER_TYPE_MEMCG: Specific memcg's pages.
> > + * @DAMON_FILTER_TYPE_PGIDLE_UNSET: Pgidle is unset.
> > */
> > enum damon_filter_type {
> > DAMON_FILTER_TYPE_ANON,
> > DAMON_FILTER_TYPE_MEMCG,
> > + DAMON_FILTER_TYPE_PGIDLE_UNSET,
>
> [Severity: Medium]
> Are the corresponding implementation details for this new filter type missing
> from this patch?
>
> The commit message states this will match pages that have their PG_Idle flag
> unset, but the new DAMON_FILTER_TYPE_PGIDLE_UNSET variant doesn't appear to
> be handled in the switch block evaluating filter types within
> damon_pa_filter_match() in mm/damon/paddr.c.
>
> Additionally, should this be exposed to userspace? The new filter type is
> not mapped in damon_sysfs_filter_type_names in mm/damon/sysfs.c, which would
> prevent it from being configured via sysfs.
Later patches of this series do those.
>
> > };
> >
> > /**
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260727143829.86236-1-sj@kernel.org?part=1
Thanks,
SJ
^ permalink raw reply [flat|nested] 26+ messages in thread
* [RFC PATCH v2.1 02/17] mm/damon/paddr: support PGIDLE_UNSET probe filter type
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 01/17] mm/damon/core: introduce DAMON_FILTER_TYPE_PGIDLE_UNSET SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:52 ` sashiko-bot
2026-07-27 14:38 ` [RFC PATCH v2.1 03/17] mm/damon/sysfs: support pgidle_unset " SJ Park
` (14 subsequent siblings)
16 siblings, 1 reply; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm
Implement support of DAMON_FILTER_TYPE_PGIDLE_UNSET in the physical
address space DAMON operations set. It reuses damon_folio_young(),
which was being used for access monitoring.
Signed-off-by: SJ Park <sj@kernel.org>
---
mm/damon/paddr.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/mm/damon/paddr.c b/mm/damon/paddr.c
index 5c6c3a597fd0b..5b307dcbb2a50 100644
--- a/mm/damon/paddr.c
+++ b/mm/damon/paddr.c
@@ -132,6 +132,12 @@ static bool damon_pa_filter_match(struct damon_filter *filter,
matched = filter->memcg_id == mem_cgroup_id(memcg);
rcu_read_unlock();
break;
+ case DAMON_FILTER_TYPE_PGIDLE_UNSET:
+ if (!folio)
+ matched = false;
+ else
+ matched = damon_folio_young(folio);
+ break;
default:
break;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* Re: [RFC PATCH v2.1 02/17] mm/damon/paddr: support PGIDLE_UNSET probe filter type
2026-07-27 14:38 ` [RFC PATCH v2.1 02/17] mm/damon/paddr: support PGIDLE_UNSET probe filter type SJ Park
@ 2026-07-27 14:52 ` sashiko-bot
2026-07-27 14:59 ` SJ Park
0 siblings, 1 reply; 26+ messages in thread
From: sashiko-bot @ 2026-07-27 14:52 UTC (permalink / raw)
To: SJ Park; +Cc: damon
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The newly added DAMON probe filter type DAMON_FILTER_TYPE_PGIDLE_UNSET is not exposed in the sysfs interface.
--
--- Patch [2]: [RFC PATCH v2.1 02/17] mm/damon/paddr: support PGIDLE_UNSET probe filter type ---
commit 67629d6971ecadd1e1c345f911e353e76f34b34f
Author: SJ Park <sj@kernel.org>
mm/damon/paddr: support PGIDLE_UNSET probe filter type
This commit implements support for the DAMON_FILTER_TYPE_PGIDLE_UNSET probe
filter type in the physical address space DAMON operations set.
> diff --git a/mm/damon/paddr.c b/mm/damon/paddr.c
> index 5a6a78054784a..199de1463fa06 100644
> --- a/mm/damon/paddr.c
> +++ b/mm/damon/paddr.c
> @@ -132,6 +132,12 @@ static bool damon_pa_filter_match(struct damon_filter *filter,
> matched = filter->memcg_id == mem_cgroup_id(memcg);
> rcu_read_unlock();
> break;
> + case DAMON_FILTER_TYPE_PGIDLE_UNSET:
> + if (!folio)
> + matched = false;
> + else
> + matched = damon_folio_young(folio);
> + break;
[Severity: Medium]
Should this new filter type also be exposed in the sysfs interface?
Looking at damon_sysfs_filter_type_names in mm/damon/sysfs.c, it maps sysfs
string inputs to DAMON probe filter types, but it doesn't seem to include
an entry for DAMON_FILTER_TYPE_PGIDLE_UNSET:
mm/damon/sysfs.c:damon_sysfs_filter_type_names[] = {
{
.type = DAMON_FILTER_TYPE_ANON,
.name = "anon",
},
{
.type = DAMON_FILTER_TYPE_MEMCG,
.name = "memcg",
},
};
Without this mapping, does this prevent userspace from accessing the newly
added feature, since any attempt to configure it through sysfs would be
rejected?
> default:
> break;
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727143829.86236-1-sj@kernel.org?part=2
^ permalink raw reply [flat|nested] 26+ messages in thread* Re: [RFC PATCH v2.1 02/17] mm/damon/paddr: support PGIDLE_UNSET probe filter type
2026-07-27 14:52 ` sashiko-bot
@ 2026-07-27 14:59 ` SJ Park
0 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:59 UTC (permalink / raw)
To: sashiko-bot; +Cc: SJ Park, damon
On Mon, 27 Jul 2026 14:52:42 +0000 sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] The newly added DAMON probe filter type DAMON_FILTER_TYPE_PGIDLE_UNSET is not exposed in the sysfs interface.
> --
>
> --- Patch [2]: [RFC PATCH v2.1 02/17] mm/damon/paddr: support PGIDLE_UNSET probe filter type ---
> commit 67629d6971ecadd1e1c345f911e353e76f34b34f
> Author: SJ Park <sj@kernel.org>
>
> mm/damon/paddr: support PGIDLE_UNSET probe filter type
>
> This commit implements support for the DAMON_FILTER_TYPE_PGIDLE_UNSET probe
> filter type in the physical address space DAMON operations set.
>
> > diff --git a/mm/damon/paddr.c b/mm/damon/paddr.c
> > index 5a6a78054784a..199de1463fa06 100644
> > --- a/mm/damon/paddr.c
> > +++ b/mm/damon/paddr.c
> > @@ -132,6 +132,12 @@ static bool damon_pa_filter_match(struct damon_filter *filter,
> > matched = filter->memcg_id == mem_cgroup_id(memcg);
> > rcu_read_unlock();
> > break;
> > + case DAMON_FILTER_TYPE_PGIDLE_UNSET:
> > + if (!folio)
> > + matched = false;
> > + else
> > + matched = damon_folio_young(folio);
> > + break;
>
> [Severity: Medium]
> Should this new filter type also be exposed in the sysfs interface?
>
> Looking at damon_sysfs_filter_type_names in mm/damon/sysfs.c, it maps sysfs
> string inputs to DAMON probe filter types, but it doesn't seem to include
> an entry for DAMON_FILTER_TYPE_PGIDLE_UNSET:
>
> mm/damon/sysfs.c:damon_sysfs_filter_type_names[] = {
> {
> .type = DAMON_FILTER_TYPE_ANON,
> .name = "anon",
> },
> {
> .type = DAMON_FILTER_TYPE_MEMCG,
> .name = "memcg",
> },
> };
>
> Without this mapping, does this prevent userspace from accessing the newly
> added feature, since any attempt to configure it through sysfs would be
> rejected?
A later patch of this series does that.
>
> > default:
> > break;
> > }
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260727143829.86236-1-sj@kernel.org?part=2
Thanks,
SJ
^ permalink raw reply [flat|nested] 26+ messages in thread
* [RFC PATCH v2.1 03/17] mm/damon/sysfs: support pgidle_unset probe filter type
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 01/17] mm/damon/core: introduce DAMON_FILTER_TYPE_PGIDLE_UNSET SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 02/17] mm/damon/paddr: support PGIDLE_UNSET probe filter type SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 04/17] Docs/mm/damon/design: document " SJ Park
` (13 subsequent siblings)
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm
Extend DAMON sysfs interface to allow users to set
DAMON_FILTER_TYPE_PGIDLE_UNSET by writing 'pgidle_unset' to the probe
filter type file.
Signed-off-by: SJ Park <sj@kernel.org>
---
mm/damon/sysfs.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index 053ba2e53b969..376c6ecbd4bf3 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -782,6 +782,10 @@ damon_sysfs_filter_type_names[] = {
.type = DAMON_FILTER_TYPE_MEMCG,
.name = "memcg",
},
+ {
+ .type = DAMON_FILTER_TYPE_PGIDLE_UNSET,
+ .name = "pgidle_unset",
+ },
};
static ssize_t type_show(struct kobject *kobj,
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* [RFC PATCH v2.1 04/17] Docs/mm/damon/design: document pgidle_unset probe filter type
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (2 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 03/17] mm/damon/sysfs: support pgidle_unset " SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 05/17] mm/damon/core: introduce damon_prep struct SJ Park
` (12 subsequent siblings)
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Liam R. Howlett, Andrew Morton, David Hildenbrand,
Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
linux-kernel, linux-mm
Update DAMON design document for the newly added pgidle_unset probe
filter type. Also use a list for the types, as it becomes not very easy
to read the whole types in a simple sentence.
Signed-off-by: SJ Park <sj@kernel.org>
---
Documentation/mm/damon/design.rst | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Documentation/mm/damon/design.rst b/Documentation/mm/damon/design.rst
index a8c163475ef2b..c4830bd09498d 100644
--- a/Documentation/mm/damon/design.rst
+++ b/Documentation/mm/damon/design.rst
@@ -293,8 +293,12 @@ registration is made by specifying a probe per attribute. Each of the probe
specifies a rule to determine if a given memory region has the related
attribute. The rule is constructed with multiple filters. The filters work
same to :ref:`DAMOS filters <damon_design_damos_filters>` except the supported
-filter types. Currently only ``anon`` and ``memcg`` filter types are supported
-for data attributes monitoring.
+filter types. Currently below filter types are supported.
+
+- ``anon``: Same to that for DAMOS filters.
+- ``memcg``: Same to that for DAMOS filters.
+- ``pgidle_unset``: Matches if the page for the memory is marked as not
+ access-idle.
If such probes are registered, DAMON executes the probes for each region's
sampling memory when it does the access :ref:`sampling
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* [RFC PATCH v2.1 05/17] mm/damon/core: introduce damon_prep struct
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (3 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 04/17] Docs/mm/damon/design: document " SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:48 ` sashiko-bot
2026-07-27 14:38 ` [RFC PATCH v2.1 06/17] mm/damon/core: commit preps SJ Park
` (11 subsequent siblings)
16 siblings, 1 reply; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm
Some DAMON probe filter types require preparatory actions. For example,
pgilde_unset probe filter can say if the page was accessed but when. To
answer the second question, the PG_Idle flag should be set at a specific
time. It can make life much easier if DAMON can do such preparatory
actions. Introduce a new data type called damon_prep. It specifies
each of the preparation actions for each probe. DAMON will execute the
action for each region per sampling interval, like it clears page table
accessed bits and unsets PG_Idle flag for access monitoring.
Also introduce DAMON_PREP_SET_PGIDLE as the initial prep action. As the
name says, it will do exactly what DAMON was doing as the preparation
action for the access monitoring.
Signed-off-by: SJ Park <sj@kernel.org>
---
include/linux/damon.h | 32 ++++++++++++++++++++++++++++++++
mm/damon/core.c | 26 ++++++++++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/include/linux/damon.h b/include/linux/damon.h
index cee4b74761081..b86744642c9d3 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -741,6 +741,27 @@ struct damon_intervals_goal {
unsigned long max_sample_us;
};
+/**
+ * enum damon_prep_action - DAMON probing preparation action.
+ *
+ * @DAMON_PREP_SET_PGIDLE: Set the probing memory as idle page.
+ */
+enum damon_prep_action {
+ DAMON_PREP_SET_PGIDLE,
+};
+
+/**
+ * struct damon_prep - DAMON probing preparation request.
+ *
+ * @action: Action to do to the probing memory for the preparation.
+ */
+struct damon_prep {
+ enum damon_prep_action action;
+/* private: */
+ /* siblings list. */
+ struct list_head list;
+};
+
/**
* enum damon_filter_type - Type of &struct damon_filter
*
@@ -782,6 +803,8 @@ struct damon_filter {
struct damon_probe {
unsigned int weight;
/* private: */
+ /* Preparation actions to apply to each probing memory. */
+ struct list_head preps;
/* Filters for assessing if a given region is for this probe. */
struct list_head filters;
/* Siblings list. */
@@ -961,6 +984,12 @@ static inline unsigned long damon_sz_region(struct damon_region *r)
return r->ar.end - r->ar.start;
}
+#define damon_for_each_prep(p, probe) \
+ list_for_each_entry(p, &(probe)->preps, list)
+
+#define damon_for_each_prep_safe(p, next, probe) \
+ list_for_each_entry_safe(p, next, &(probe)->preps, list)
+
#define damon_for_each_filter(f, p) \
list_for_each_entry(f, &(p)->filters, list)
@@ -1014,6 +1043,9 @@ static inline unsigned long damon_sz_region(struct damon_region *r)
#ifdef CONFIG_DAMON
+struct damon_prep *damon_new_prep(enum damon_prep_action action);
+void damon_add_prep(struct damon_probe *p, struct damon_prep *prep);
+
struct damon_filter *damon_new_filter(enum damon_filter_type type,
bool matching, bool allow);
void damon_add_filter(struct damon_probe *probe, struct damon_filter *f);
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 5eb0400d5ce16..bda61f9ec0266 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -111,6 +111,28 @@ int damon_select_ops(struct damon_ctx *ctx, enum damon_ops_id id)
return err;
}
+struct damon_prep *damon_new_prep(enum damon_prep_action action)
+{
+ struct damon_prep *prep;
+
+ prep = kmalloc_obj(*prep);
+ if (!prep)
+ return NULL;
+ prep->action = action;
+ INIT_LIST_HEAD(&prep->list);
+ return prep;
+}
+
+void damon_add_prep(struct damon_probe *p, struct damon_prep *prep)
+{
+ list_add_tail(&prep->list, &p->preps);
+}
+
+static void damon_free_prep(struct damon_prep *p)
+{
+ kfree(p);
+}
+
struct damon_filter *damon_new_filter(enum damon_filter_type type,
bool matching, bool allow)
{
@@ -167,6 +189,7 @@ struct damon_probe *damon_new_probe(void)
if (!p)
return NULL;
p->weight = 0;
+ INIT_LIST_HEAD(&p->preps);
INIT_LIST_HEAD(&p->filters);
INIT_LIST_HEAD(&p->list);
return p;
@@ -184,8 +207,11 @@ static void damon_del_probe(struct damon_probe *p)
static void damon_free_probe(struct damon_probe *p)
{
+ struct damon_prep *prep, *prep_next;
struct damon_filter *f, *next;
+ damon_for_each_prep_safe(prep, prep_next, p)
+ damon_free_prep(prep);
damon_for_each_filter_safe(f, next, p)
damon_free_filter(f);
kfree(p);
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* Re: [RFC PATCH v2.1 05/17] mm/damon/core: introduce damon_prep struct
2026-07-27 14:38 ` [RFC PATCH v2.1 05/17] mm/damon/core: introduce damon_prep struct SJ Park
@ 2026-07-27 14:48 ` sashiko-bot
2026-07-27 15:00 ` SJ Park
0 siblings, 1 reply; 26+ messages in thread
From: sashiko-bot @ 2026-07-27 14:48 UTC (permalink / raw)
To: SJ Park; +Cc: damon
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] damon_commit_probes() does not synchronize the newly added 'preps' list, leading to lost preparation actions during context updates.
--
--- Patch [5]: [RFC PATCH v2.1 05/17] mm/damon/core: introduce damon_prep struct ---
commit 560f806438365d13be862eb2266c647b1d981d0b
Author: SJ Park <sj@kernel.org>
mm/damon/core: introduce damon_prep struct
Some DAMON probe filter types require preparatory actions, like setting
the PG_Idle flag at a specific time. This commit introduces a new data
type called damon_prep to specify preparation actions for each probe.
It also adds DAMON_PREP_SET_PGIDLE as the initial prep action.
> diff --git a/include/linux/damon.h b/include/linux/damon.h
> index a8bb9ee6979e3..1a8de735f955b 100644
> --- a/include/linux/damon.h
> +++ b/include/linux/damon.h
[ ... ]
> @@ -780,6 +801,8 @@ struct damon_filter {
> struct damon_probe {
> unsigned int weight;
> /* private: */
> + /* Preparation actions to apply to each probing memory. */
> + struct list_head preps;
> /* Filters for assessing if a given region is for this probe. */
> struct list_head filters;
> /* Siblings list. */
[Severity: Medium]
Does this change also require an update to damon_commit_probes() to copy the
new preps list?
Currently, when updating a running context, damon_commit_probes() only copies
the weight and filters from the source probe to the destination probe:
mm/damon/core.c:damon_commit_probes() {
...
damon_for_each_probe_safe(dst_probe, next, dst) {
src_probe = damon_nth_probe(i++, src);
if (src_probe) {
dst_probe->weight = src_probe->weight;
err = damon_commit_filters(dst_probe, src_probe);
...
}
This applies both when synchronizing existing probes and when creating new
ones to match the source context.
Without a corresponding damon_commit_preps() mechanism to synchronize these
lists, it appears any preparation actions configured on a source context could
be silently lost when committed to a running destination context.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727143829.86236-1-sj@kernel.org?part=5
^ permalink raw reply [flat|nested] 26+ messages in thread* Re: [RFC PATCH v2.1 05/17] mm/damon/core: introduce damon_prep struct
2026-07-27 14:48 ` sashiko-bot
@ 2026-07-27 15:00 ` SJ Park
0 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 15:00 UTC (permalink / raw)
To: sashiko-bot; +Cc: SJ Park, damon
On Mon, 27 Jul 2026 14:48:42 +0000 sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] damon_commit_probes() does not synchronize the newly added 'preps' list, leading to lost preparation actions during context updates.
> --
>
> --- Patch [5]: [RFC PATCH v2.1 05/17] mm/damon/core: introduce damon_prep struct ---
> commit 560f806438365d13be862eb2266c647b1d981d0b
> Author: SJ Park <sj@kernel.org>
>
> mm/damon/core: introduce damon_prep struct
>
> Some DAMON probe filter types require preparatory actions, like setting
> the PG_Idle flag at a specific time. This commit introduces a new data
> type called damon_prep to specify preparation actions for each probe.
> It also adds DAMON_PREP_SET_PGIDLE as the initial prep action.
>
> > diff --git a/include/linux/damon.h b/include/linux/damon.h
> > index a8bb9ee6979e3..1a8de735f955b 100644
> > --- a/include/linux/damon.h
> > +++ b/include/linux/damon.h
>
> [ ... ]
>
> > @@ -780,6 +801,8 @@ struct damon_filter {
> > struct damon_probe {
> > unsigned int weight;
> > /* private: */
> > + /* Preparation actions to apply to each probing memory. */
> > + struct list_head preps;
> > /* Filters for assessing if a given region is for this probe. */
> > struct list_head filters;
> > /* Siblings list. */
>
> [Severity: Medium]
> Does this change also require an update to damon_commit_probes() to copy the
> new preps list?
>
> Currently, when updating a running context, damon_commit_probes() only copies
> the weight and filters from the source probe to the destination probe:
>
> mm/damon/core.c:damon_commit_probes() {
> ...
> damon_for_each_probe_safe(dst_probe, next, dst) {
> src_probe = damon_nth_probe(i++, src);
> if (src_probe) {
> dst_probe->weight = src_probe->weight;
> err = damon_commit_filters(dst_probe, src_probe);
> ...
> }
>
> This applies both when synchronizing existing probes and when creating new
> ones to match the source context.
>
> Without a corresponding damon_commit_preps() mechanism to synchronize these
> lists, it appears any preparation actions configured on a source context could
> be silently lost when committed to a running destination context.
A later patch in this series does that.
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260727143829.86236-1-sj@kernel.org?part=5
Thanks,
SJ
^ permalink raw reply [flat|nested] 26+ messages in thread
* [RFC PATCH v2.1 06/17] mm/damon/core: commit preps
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (4 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 05/17] mm/damon/core: introduce damon_prep struct SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 07/17] mm/damon/core: introduce damon_operations->prep_probes() SJ Park
` (10 subsequent siblings)
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm
damon_commit_probes() is ignoring damon_prep. Commit the prep actions,
too.
Signed-off-by: SJ Park <sj@kernel.org>
---
mm/damon/core.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index bda61f9ec0266..c74dee56efee8 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -128,11 +128,34 @@ void damon_add_prep(struct damon_probe *p, struct damon_prep *prep)
list_add_tail(&prep->list, &p->preps);
}
+static void damon_del_prep(struct damon_prep *p)
+{
+ list_del(&p->list);
+}
+
static void damon_free_prep(struct damon_prep *p)
{
kfree(p);
}
+static void damon_destroy_prep(struct damon_prep *p)
+{
+ damon_del_prep(p);
+ damon_free_prep(p);
+}
+
+static struct damon_prep *damon_nth_prep(int n, struct damon_probe *p)
+{
+ struct damon_prep *prep;
+ int i = 0;
+
+ damon_for_each_prep(prep, p) {
+ if (i++ == n)
+ return prep;
+ }
+ return NULL;
+}
+
struct damon_filter *damon_new_filter(enum damon_filter_type type,
bool matching, bool allow)
{
@@ -1694,6 +1717,36 @@ static int damon_commit_targets(
return err;
}
+static void damon_commit_prep(struct damon_prep *dst, struct damon_prep *src)
+{
+ dst->action = src->action;
+}
+
+static int damon_commit_preps(struct damon_probe *dst, struct damon_probe *src)
+{
+ struct damon_prep *dst_prep, *next, *src_prep, *new_prep;
+ int i = 0, j = 0;
+
+ damon_for_each_prep_safe(dst_prep, next, dst) {
+ src_prep = damon_nth_prep(i++, src);
+ if (src_prep)
+ damon_commit_prep(dst_prep, src_prep);
+ else
+ damon_destroy_prep(dst_prep);
+ }
+
+ damon_for_each_prep_safe(src_prep, next, src) {
+ if (j++ < i)
+ continue;
+
+ new_prep = damon_new_prep(src_prep->action);
+ if (!new_prep)
+ return -ENOMEM;
+ damon_add_prep(dst, new_prep);
+ }
+ return 0;
+}
+
static void damon_commit_filter(struct damon_filter *dst,
struct damon_filter *src)
{
@@ -1752,6 +1805,9 @@ static int damon_commit_probes(struct damon_ctx *dst, struct damon_ctx *src)
src_probe = damon_nth_probe(i++, src);
if (src_probe) {
dst_probe->weight = src_probe->weight;
+ err = damon_commit_preps(dst_probe, src_probe);
+ if (err)
+ return err;
err = damon_commit_filters(dst_probe, src_probe);
if (err)
return err;
@@ -1769,6 +1825,9 @@ static int damon_commit_probes(struct damon_ctx *dst, struct damon_ctx *src)
return -ENOMEM;
damon_add_probe(dst, new_probe);
new_probe->weight = src_probe->weight;
+ err = damon_commit_preps(new_probe, src_probe);
+ if (err)
+ return err;
err = damon_commit_filters(new_probe, src_probe);
if (err)
return err;
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* [RFC PATCH v2.1 07/17] mm/damon/core: introduce damon_operations->prep_probes()
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (5 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 06/17] mm/damon/core: commit preps SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:44 ` sashiko-bot
2026-07-27 14:38 ` [RFC PATCH v2.1 08/17] mm/damon/paddr: support damon_prep SJ Park
` (9 subsequent siblings)
16 siblings, 1 reply; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm
damon_prep needs to be executed by the underlying DAMON operation set.
Extend the operation set callback list for the execution of damon_prep
actions. If the underlying operation set implements the callback, DAMON
core executes it in the monitoring preparation time.
Signed-off-by: SJ Park <sj@kernel.org>
---
include/linux/damon.h | 5 +++++
mm/damon/core.c | 20 +++++++++++++++++++-
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/include/linux/damon.h b/include/linux/damon.h
index b86744642c9d3..c6cbf1edf331a 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -629,6 +629,7 @@ enum damon_ops_id {
* @update: Update operations-related data structures.
* @prepare_access_checks: Prepare next access check of target regions.
* @check_accesses: Check the accesses to target regions.
+ * @prep_probes: Prepare applying probes for each region.
* @apply_probes: Apply probes for each region.
* @get_scheme_score: Get the score of a region for a scheme.
* @apply_scheme: Apply a DAMON-based operation scheme.
@@ -656,6 +657,9 @@ enum damon_ops_id {
* last preparation and update the number of observed accesses of each region.
* It should also return max number of observed accesses that made as a result
* of its update. The value will be used for regions adjustment threshold.
+ * @prep_probes should execute required &struct damon_prep for next &struct
+ * damon_probe applications to each region. It should also set
+ * &damon_region->sampling_addr of each region if ``set_samples`` is true.
* @apply_probes should apply the data attribute probes to each region and
* accordingly update the probe hits counter of the region. It should also
* set &damon_region->sampling_addr of each region if ``set_samples`` is true.
@@ -678,6 +682,7 @@ struct damon_operations {
void (*update)(struct damon_ctx *context);
void (*prepare_access_checks)(struct damon_ctx *context);
unsigned int (*check_accesses)(struct damon_ctx *context);
+ void (*prep_probes)(struct damon_ctx *context, bool set_samples);
unsigned int (*apply_probes)(struct damon_ctx *context,
bool set_samples, bool return_max_wsum);
int (*get_scheme_score)(struct damon_ctx *context,
diff --git a/mm/damon/core.c b/mm/damon/core.c
index c74dee56efee8..bbc3f231c1616 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -156,6 +156,18 @@ static struct damon_prep *damon_nth_prep(int n, struct damon_probe *p)
return NULL;
}
+static bool damon_has_prep(struct damon_ctx *c)
+{
+ struct damon_prep *prep;
+ struct damon_probe *probe;
+
+ damon_for_each_probe(probe, c) {
+ damon_for_each_prep(prep, probe)
+ return true;
+ }
+ return false;
+}
+
struct damon_filter *damon_new_filter(enum damon_filter_type type,
bool matching, bool allow)
{
@@ -3868,14 +3880,19 @@ static int kdamond_fn(void *data)
unsigned long next_ops_update_sis = ctx->next_ops_update_sis;
unsigned long sample_interval = ctx->attrs.sample_interval;
bool access_check_disabled = damon_has_probe_weights(ctx);
+ bool do_prep;
unsigned int max_merge_score = 0, max_wsum;
bool get_max_wsum;
if (kdamond_wait_activation(ctx))
break;
+ do_prep = damon_has_prep(ctx) && ctx->ops.prep_probes;
+
if (!access_check_disabled && ctx->ops.prepare_access_checks)
ctx->ops.prepare_access_checks(ctx);
+ if (do_prep)
+ ctx->ops.prep_probes(ctx, access_check_disabled);
kdamond_usleep(sample_interval);
ctx->passed_sample_intervals++;
@@ -3890,7 +3907,8 @@ static int kdamond_fn(void *data)
else
get_max_wsum = false;
max_wsum = ctx->ops.apply_probes(ctx,
- access_check_disabled, get_max_wsum);
+ access_check_disabled && !do_prep,
+ get_max_wsum);
if (get_max_wsum)
max_merge_score = max_wsum;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* Re: [RFC PATCH v2.1 07/17] mm/damon/core: introduce damon_operations->prep_probes()
2026-07-27 14:38 ` [RFC PATCH v2.1 07/17] mm/damon/core: introduce damon_operations->prep_probes() SJ Park
@ 2026-07-27 14:44 ` sashiko-bot
2026-07-27 15:02 ` SJ Park
0 siblings, 1 reply; 26+ messages in thread
From: sashiko-bot @ 2026-07-27 14:44 UTC (permalink / raw)
To: SJ Park; +Cc: damon
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Suboptimal short-circuit order in `kdamond_fn` causes unnecessary list traversals when `prep_probes` is not implemented.
--
--- Patch [7]: [RFC PATCH v2.1 07/17] mm/damon/core: introduce damon_operations->prep_probes() ---
commit 6cf31e4df3b58637535e88cd2f6425680fdfa9e6
Author: SJ Park <sj@kernel.org>
mm/damon/core: introduce damon_operations->prep_probes()
This commit introduces a new prep_probes callback to the DAMON operations
set to execute damon_prep actions during monitoring preparation time. It
extends the core to check for and execute this callback if provided by the
underlying operation set.
> diff --git a/mm/damon/core.c b/mm/damon/core.c
> index 127d3a7c27280..19ab80f50bc4b 100644
> --- a/mm/damon/core.c
> +++ b/mm/damon/core.c
[ ... ]
> @@ -3870,14 +3882,19 @@ static int kdamond_fn(void *data)
> unsigned long next_ops_update_sis = ctx->next_ops_update_sis;
> unsigned long sample_interval = ctx->attrs.sample_interval;
> bool access_check_disabled = damon_has_probe_weights(ctx);
> + bool do_prep;
> unsigned int max_merge_score = 0, max_wsum;
> bool get_max_wsum;
>
> if (kdamond_wait_activation(ctx))
> break;
>
> + do_prep = damon_has_prep(ctx) && ctx->ops.prep_probes;
[Severity: Low]
Could this short-circuit logic be reordered to check ctx->ops.prep_probes
before damon_has_prep(ctx)?
If the underlying operation set does not implement the prep_probes callback,
evaluating damon_has_prep() first will result in unnecessary list traversals
during every sample interval in the kdamond hot loop.
While the probe lists are typically short, evaluating ctx->ops.prep_probes
first would cleanly avoid this overhead when the callback is unused.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727143829.86236-1-sj@kernel.org?part=7
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [RFC PATCH v2.1 07/17] mm/damon/core: introduce damon_operations->prep_probes()
2026-07-27 14:44 ` sashiko-bot
@ 2026-07-27 15:02 ` SJ Park
0 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 15:02 UTC (permalink / raw)
To: sashiko-bot; +Cc: SJ Park, damon
On Mon, 27 Jul 2026 14:44:21 +0000 sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Low] Suboptimal short-circuit order in `kdamond_fn` causes unnecessary list traversals when `prep_probes` is not implemented.
> --
>
> --- Patch [7]: [RFC PATCH v2.1 07/17] mm/damon/core: introduce damon_operations->prep_probes() ---
> commit 6cf31e4df3b58637535e88cd2f6425680fdfa9e6
> Author: SJ Park <sj@kernel.org>
>
> mm/damon/core: introduce damon_operations->prep_probes()
>
> This commit introduces a new prep_probes callback to the DAMON operations
> set to execute damon_prep actions during monitoring preparation time. It
> extends the core to check for and execute this callback if provided by the
> underlying operation set.
>
> > diff --git a/mm/damon/core.c b/mm/damon/core.c
> > index 127d3a7c27280..19ab80f50bc4b 100644
> > --- a/mm/damon/core.c
> > +++ b/mm/damon/core.c
>
> [ ... ]
>
> > @@ -3870,14 +3882,19 @@ static int kdamond_fn(void *data)
> > unsigned long next_ops_update_sis = ctx->next_ops_update_sis;
> > unsigned long sample_interval = ctx->attrs.sample_interval;
> > bool access_check_disabled = damon_has_probe_weights(ctx);
> > + bool do_prep;
> > unsigned int max_merge_score = 0, max_wsum;
> > bool get_max_wsum;
> >
> > if (kdamond_wait_activation(ctx))
> > break;
> >
> > + do_prep = damon_has_prep(ctx) && ctx->ops.prep_probes;
>
> [Severity: Low]
> Could this short-circuit logic be reordered to check ctx->ops.prep_probes
> before damon_has_prep(ctx)?
>
> If the underlying operation set does not implement the prep_probes callback,
> evaluating damon_has_prep() first will result in unnecessary list traversals
> during every sample interval in the kdamond hot loop.
>
> While the probe lists are typically short, evaluating ctx->ops.prep_probes
> first would cleanly avoid this overhead when the callback is unused.
Good suggestion, I will do so.
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260727143829.86236-1-sj@kernel.org?part=7
Thanks,
SJ
^ permalink raw reply [flat|nested] 26+ messages in thread
* [RFC PATCH v2.1 08/17] mm/damon/paddr: support damon_prep
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (6 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 07/17] mm/damon/core: introduce damon_operations->prep_probes() SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 09/17] mm/damon/sysfs: implement preps directory SJ Park
` (8 subsequent siblings)
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm
Implement damon_operations->prep_probes() callback. Support the only
existing prep action, DAMON_PREP_SET_PGIDLE in a way similar to what it
was doing for the access check preparation: unset page table accessed
bits and set PG_Idle flag. Reuse the function for the access check
preparation.
Signed-off-by: SJ Park <sj@kernel.org>
---
mm/damon/paddr.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/mm/damon/paddr.c b/mm/damon/paddr.c
index 5b307dcbb2a50..8fb71183b76c0 100644
--- a/mm/damon/paddr.c
+++ b/mm/damon/paddr.c
@@ -105,6 +105,40 @@ static unsigned int damon_pa_check_accesses(struct damon_ctx *ctx)
return max_nr_accesses;
}
+static void damon_pa_prep_probes_region(struct damon_region *r,
+ struct damon_probe *probe, struct damon_ctx *ctx)
+{
+ struct damon_prep *p;
+
+ damon_for_each_prep(p, probe) {
+ switch (p->action) {
+ case DAMON_PREP_SET_PGIDLE:
+ damon_pa_mkold(damon_pa_phys_addr(r->sampling_addr,
+ ctx->addr_unit));
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void damon_pa_prep_probes(struct damon_ctx *ctx, bool set_samples)
+{
+ struct damon_target *t;
+ struct damon_region *r;
+ struct damon_probe *p;
+
+ damon_for_each_target(t, ctx) {
+ damon_for_each_region(r, t) {
+ if (set_samples)
+ r->sampling_addr = damon_rand(ctx, r->ar.start,
+ r->ar.end);
+ damon_for_each_probe(p, ctx)
+ damon_pa_prep_probes_region(r, p, ctx);
+ }
+ }
+}
+
static bool damon_pa_filter_match(struct damon_filter *filter,
struct folio *folio)
{
@@ -448,6 +482,7 @@ static int __init damon_pa_initcall(void)
.update = NULL,
.prepare_access_checks = damon_pa_prepare_access_checks,
.check_accesses = damon_pa_check_accesses,
+ .prep_probes = damon_pa_prep_probes,
.apply_probes = damon_pa_apply_probes,
.target_valid = NULL,
.apply_scheme = damon_pa_apply_scheme,
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* [RFC PATCH v2.1 09/17] mm/damon/sysfs: implement preps directory
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (7 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 08/17] mm/damon/paddr: support damon_prep SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 10/17] mm/damon/sysfs: implement preps/nr_preps file SJ Park
` (7 subsequent siblings)
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm
Implement a sysfs directory named 'preps' under the probe directory. It
will be evolved to be used for specifying probe preps.
Signed-off-by: SJ Park <sj@kernel.org>
---
mm/damon/sysfs.c | 65 +++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 59 insertions(+), 6 deletions(-)
diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index 376c6ecbd4bf3..e33070d2cbcc6 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -750,6 +750,35 @@ static const struct kobj_type damon_sysfs_intervals_ktype = {
.default_groups = damon_sysfs_intervals_groups,
};
+/*
+ * preps directory
+ */
+
+struct damon_sysfs_preps {
+ struct kobject kobj;
+};
+
+static struct damon_sysfs_preps *damon_sysfs_preps_alloc(void)
+{
+ return kzalloc_obj(struct damon_sysfs_preps);
+}
+
+static void damon_sysfs_preps_release(struct kobject *kobj)
+{
+ kfree(container_of(kobj, struct damon_sysfs_preps, kobj));
+}
+
+static struct attribute *damon_sysfs_preps_attrs[] = {
+ NULL,
+};
+ATTRIBUTE_GROUPS(damon_sysfs_preps);
+
+static const struct kobj_type damon_sysfs_preps_ktype = {
+ .release = damon_sysfs_preps_release,
+ .sysfs_ops = &kobj_sysfs_ops,
+ .default_groups = damon_sysfs_preps_groups,
+};
+
/*
* filter directory
*/
@@ -1070,6 +1099,7 @@ static const struct kobj_type damon_sysfs_filters_ktype = {
struct damon_sysfs_probe {
struct kobject kobj;
unsigned int weight;
+ struct damon_sysfs_preps *preps;
struct damon_sysfs_filters *filters;
};
@@ -1080,25 +1110,48 @@ static struct damon_sysfs_probe *damon_sysfs_probe_alloc(void)
static int damon_sysfs_probe_add_dirs(struct damon_sysfs_probe *probe)
{
+ struct damon_sysfs_preps *preps;
struct damon_sysfs_filters *filters;
int err;
- filters = damon_sysfs_filters_alloc();
- if (!filters)
+ preps = damon_sysfs_preps_alloc();
+ if (!preps)
return -ENOMEM;
+ probe->preps = preps;
+
+ err = kobject_init_and_add(&preps->kobj, &damon_sysfs_preps_ktype,
+ &probe->kobj, "preps");
+ if (err)
+ goto put_preps_out;
+
+ filters = damon_sysfs_filters_alloc();
+ if (!filters) {
+ err = -ENOMEM;
+ goto del_preps_out;
+ }
probe->filters = filters;
err = kobject_init_and_add(&filters->kobj, &damon_sysfs_filters_ktype,
&probe->kobj, "filters");
- if (err) {
- kobject_put(&filters->kobj);
- probe->filters = NULL;
- }
+ if (err)
+ goto put_filters_out;
+ return err;
+
+put_filters_out:
+ kobject_put(&filters->kobj);
+ probe->filters = NULL;
+del_preps_out:
+ kobject_del(&preps->kobj);
+put_preps_out:
+ kobject_put(&preps->kobj);
+ probe->preps = NULL;
return err;
}
static void damon_sysfs_probe_rm_dirs(struct damon_sysfs_probe *probe)
{
+ if (probe->preps)
+ kobject_put(&probe->preps->kobj);
if (probe->filters) {
damon_sysfs_filters_rm_dirs(probe->filters);
kobject_put(&probe->filters->kobj);
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* [RFC PATCH v2.1 10/17] mm/damon/sysfs: implement preps/nr_preps file
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (8 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 09/17] mm/damon/sysfs: implement preps directory SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 11/17] mm/damon/sysfs: create directories for nr_preps writes SJ Park
` (6 subsequent siblings)
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm
Implement nr_preps file under the preps directory. It will be evolved
to be used for generating sub directories that will represent each probe
preparation action.
Signed-off-by: SJ Park <sj@kernel.org>
---
mm/damon/sysfs.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 52 insertions(+), 1 deletion(-)
diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index e33070d2cbcc6..6d3ed80fb2eb1 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -756,6 +756,7 @@ static const struct kobj_type damon_sysfs_intervals_ktype = {
struct damon_sysfs_preps {
struct kobject kobj;
+ int nr;
};
static struct damon_sysfs_preps *damon_sysfs_preps_alloc(void)
@@ -763,12 +764,60 @@ static struct damon_sysfs_preps *damon_sysfs_preps_alloc(void)
return kzalloc_obj(struct damon_sysfs_preps);
}
+static void damon_sysfs_preps_rm_dirs(struct damon_sysfs_preps *preps)
+{
+ preps->nr = 0;
+}
+
+static int damon_sysfs_preps_add_dirs(struct damon_sysfs_preps *preps,
+ int nr_preps)
+{
+ preps->nr = nr_preps;
+ return 0;
+}
+
+static ssize_t nr_preps_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ struct damon_sysfs_preps *preps = container_of(kobj,
+ struct damon_sysfs_preps, kobj);
+
+ return sysfs_emit(buf, "%d\n", preps->nr);
+}
+
+static ssize_t nr_preps_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_preps *preps;
+ int nr, err = kstrtoint(buf, 0, &nr);
+
+ if (err)
+ return err;
+ if (nr < 0)
+ return -EINVAL;
+
+ preps = container_of(kobj, struct damon_sysfs_preps, kobj);
+
+ if (!mutex_trylock(&damon_sysfs_lock))
+ return -EBUSY;
+ err = damon_sysfs_preps_add_dirs(preps, nr);
+ mutex_unlock(&damon_sysfs_lock);
+ if (err)
+ return err;
+
+ return count;
+}
+
static void damon_sysfs_preps_release(struct kobject *kobj)
{
kfree(container_of(kobj, struct damon_sysfs_preps, kobj));
}
+static struct kobj_attribute damon_sysfs_preps_nr_attr =
+ __ATTR_RW_MODE(nr_preps, 0600);
+
static struct attribute *damon_sysfs_preps_attrs[] = {
+ &damon_sysfs_preps_nr_attr.attr,
NULL,
};
ATTRIBUTE_GROUPS(damon_sysfs_preps);
@@ -1150,8 +1199,10 @@ static int damon_sysfs_probe_add_dirs(struct damon_sysfs_probe *probe)
static void damon_sysfs_probe_rm_dirs(struct damon_sysfs_probe *probe)
{
- if (probe->preps)
+ if (probe->preps) {
+ damon_sysfs_preps_rm_dirs(probe->preps);
kobject_put(&probe->preps->kobj);
+ }
if (probe->filters) {
damon_sysfs_filters_rm_dirs(probe->filters);
kobject_put(&probe->filters->kobj);
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* [RFC PATCH v2.1 11/17] mm/damon/sysfs: create directories for nr_preps writes
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (9 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 10/17] mm/damon/sysfs: implement preps/nr_preps file SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 12/17] mm/damon/sysfs: implement prep_action file SJ Park
` (5 subsequent siblings)
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm
Implement nr_preps write action to actually create subdirectories of the
number. Each of the directory will be evolved to represent each probe
preparation action.
Signed-off-by: SJ Park <sj@kernel.org>
---
mm/damon/sysfs.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 79 insertions(+), 1 deletion(-)
diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index 6d3ed80fb2eb1..2ec33280a7a83 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -750,12 +750,50 @@ static const struct kobj_type damon_sysfs_intervals_ktype = {
.default_groups = damon_sysfs_intervals_groups,
};
+/*
+ * prep directory
+ */
+
+struct damon_sysfs_prep {
+ struct kobject kobj;
+};
+
+static struct damon_sysfs_prep *damon_sysfs_prep_alloc(void)
+{
+ struct damon_sysfs_prep *prep;
+
+ prep = kzalloc_obj(struct damon_sysfs_prep);
+ if (!prep)
+ return prep;
+ return prep;
+}
+
+static void damon_sysfs_prep_release(struct kobject *kobj)
+{
+ struct damon_sysfs_prep *prep = container_of(kobj,
+ struct damon_sysfs_prep, kobj);
+
+ kfree(prep);
+}
+
+static struct attribute *damon_sysfs_prep_attrs[] = {
+ NULL,
+};
+ATTRIBUTE_GROUPS(damon_sysfs_prep);
+
+static const struct kobj_type damon_sysfs_prep_ktype = {
+ .release = damon_sysfs_prep_release,
+ .sysfs_ops = &kobj_sysfs_ops,
+ .default_groups = damon_sysfs_prep_groups,
+};
+
/*
* preps directory
*/
struct damon_sysfs_preps {
struct kobject kobj;
+ struct damon_sysfs_prep **preps_arr;
int nr;
};
@@ -766,13 +804,53 @@ static struct damon_sysfs_preps *damon_sysfs_preps_alloc(void)
static void damon_sysfs_preps_rm_dirs(struct damon_sysfs_preps *preps)
{
+ struct damon_sysfs_prep **preps_arr = preps->preps_arr;
+ int i;
+
+ for (i = 0; i < preps->nr; i++) {
+ kobject_del(&preps_arr[i]->kobj);
+ kobject_put(&preps_arr[i]->kobj);
+ }
preps->nr = 0;
+ kfree(preps_arr);
+ preps->preps_arr = NULL;
}
static int damon_sysfs_preps_add_dirs(struct damon_sysfs_preps *preps,
int nr_preps)
{
- preps->nr = nr_preps;
+ struct damon_sysfs_prep **preps_arr, *prep;
+ int err, i;
+
+ damon_sysfs_preps_rm_dirs(preps);
+ if (!nr_preps)
+ return 0;
+
+ preps_arr = kmalloc_objs(*preps_arr, nr_preps,
+ GFP_KERNEL | __GFP_NOWARN);
+ if (!preps_arr)
+ return -ENOMEM;
+ preps->preps_arr = preps_arr;
+
+ for (i = 0; i < nr_preps; i++) {
+ prep = damon_sysfs_prep_alloc();
+ if (!prep) {
+ damon_sysfs_preps_rm_dirs(preps);
+ return -ENOMEM;
+ }
+
+ err = kobject_init_and_add(&prep->kobj,
+ &damon_sysfs_prep_ktype, &preps->kobj, "%d",
+ i);
+ if (err) {
+ kobject_put(&prep->kobj);
+ damon_sysfs_preps_rm_dirs(preps);
+ return err;
+ }
+
+ preps_arr[i] = prep;
+ preps->nr++;
+ }
return 0;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* [RFC PATCH v2.1 12/17] mm/damon/sysfs: implement prep_action file
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (10 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 11/17] mm/damon/sysfs: create directories for nr_preps writes SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 13/17] mm/damon/sysfs: pass preps to DAMON core SJ Park
` (4 subsequent siblings)
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm
Add a file named prep_action under the prep directory. It represents
the corresponding probe preparation action.
Signed-off-by: SJ Park <sj@kernel.org>
---
mm/damon/sysfs.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index 2ec33280a7a83..0173f37fdbf3d 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -756,6 +756,7 @@ static const struct kobj_type damon_sysfs_intervals_ktype = {
struct damon_sysfs_prep {
struct kobject kobj;
+ enum damon_prep_action action;
};
static struct damon_sysfs_prep *damon_sysfs_prep_alloc(void)
@@ -765,9 +766,61 @@ static struct damon_sysfs_prep *damon_sysfs_prep_alloc(void)
prep = kzalloc_obj(struct damon_sysfs_prep);
if (!prep)
return prep;
+ prep->action = DAMON_PREP_SET_PGIDLE;
return prep;
}
+struct damon_sysfs_prep_action_name {
+ const enum damon_prep_action action;
+ const char *name;
+};
+
+static const struct damon_sysfs_prep_action_name
+damon_sysfs_prep_action_names[] = {
+ {
+ .action = DAMON_PREP_SET_PGIDLE,
+ .name = "set_pgidle",
+ },
+};
+
+static ssize_t prep_action_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct damon_sysfs_prep *prep = container_of(kobj,
+ struct damon_sysfs_prep, kobj);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(damon_sysfs_prep_action_names); i++) {
+ const struct damon_sysfs_prep_action_name *action_name;
+
+ action_name = &damon_sysfs_prep_action_names[i];
+ if (action_name->action == prep->action)
+ return sysfs_emit(buf, "%s\n", action_name->name);
+ }
+ return -EINVAL;
+}
+
+static ssize_t prep_action_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ struct damon_sysfs_prep *prep = container_of(kobj,
+ struct damon_sysfs_prep, kobj);
+ ssize_t ret = -EINVAL;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(damon_sysfs_prep_action_names); i++) {
+ const struct damon_sysfs_prep_action_name *action_name;
+
+ action_name = &damon_sysfs_prep_action_names[i];
+ if (sysfs_streq(buf, action_name->name)) {
+ prep->action = action_name->action;
+ ret = count;
+ break;
+ }
+ }
+ return ret;
+}
+
static void damon_sysfs_prep_release(struct kobject *kobj)
{
struct damon_sysfs_prep *prep = container_of(kobj,
@@ -776,7 +829,11 @@ static void damon_sysfs_prep_release(struct kobject *kobj)
kfree(prep);
}
+static struct kobj_attribute damon_sysfs_prep_prep_action_attr =
+ __ATTR_RW_MODE(prep_action, 0600);
+
static struct attribute *damon_sysfs_prep_attrs[] = {
+ &damon_sysfs_prep_prep_action_attr.attr,
NULL,
};
ATTRIBUTE_GROUPS(damon_sysfs_prep);
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* [RFC PATCH v2.1 13/17] mm/damon/sysfs: pass preps to DAMON core
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (11 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 12/17] mm/damon/sysfs: implement prep_action file SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 14/17] selftests/damon/sysfs.sh: test probe prep sysfs files SJ Park
` (3 subsequent siblings)
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Andrew Morton, damon, linux-kernel, linux-mm
DAMON sysfs interface provides the files for setting DAMON probe preps.
But the underlying code is not really passing the user-set values to
DAMON core. Pass those.
Signed-off-by: SJ Park <sj@kernel.org>
---
mm/damon/sysfs.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index 0173f37fdbf3d..3ef6b07cdb5fa 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -2174,6 +2174,23 @@ static int damon_sysfs_set_attrs(struct damon_ctx *ctx,
return damon_set_attrs(ctx, &attrs);
}
+static int damon_sysfs_set_preps(struct damon_probe *probe,
+ struct damon_sysfs_preps *sys_preps)
+{
+ int i;
+
+ for (i = 0; i < sys_preps->nr; i++) {
+ struct damon_sysfs_prep *sys_prep = sys_preps->preps_arr[i];
+ struct damon_prep *prep;
+
+ prep = damon_new_prep(sys_prep->action);
+ if (!prep)
+ return -ENOMEM;
+ damon_add_prep(probe, prep);
+ }
+ return 0;
+}
+
static int damon_sysfs_set_filters(struct damon_probe *probe,
struct damon_sysfs_filters *sys_filters)
{
@@ -2209,7 +2226,15 @@ static int damon_sysfs_set_probe(struct damon_probe *probe,
struct damon_sysfs_probe *sys_probe)
{
struct damon_sysfs_filters *sys_filters;
+ struct damon_sysfs_preps *sys_preps;
+ int err;
+ sys_preps = sys_probe->preps;
+ if (sys_preps) {
+ err = damon_sysfs_set_preps(probe, sys_preps);
+ if (err)
+ return err;
+ }
sys_filters = sys_probe->filters;
if (!sys_filters)
return 0;
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* [RFC PATCH v2.1 14/17] selftests/damon/sysfs.sh: test probe prep sysfs files
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (12 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 13/17] mm/damon/sysfs: pass preps to DAMON core SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 15/17] Docs/mm/damon/design: document probe preps SJ Park
` (2 subsequent siblings)
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Shuah Khan, damon, linux-kernel, linux-kselftest,
linux-mm
Add basic file operations test for newly introduced DAMON probe prep
sysfs directories and files.
Signed-off-by: SJ Park <sj@kernel.org>
---
tools/testing/selftests/damon/sysfs.sh | 27 ++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/tools/testing/selftests/damon/sysfs.sh b/tools/testing/selftests/damon/sysfs.sh
index f7fb94b84e716..ddebde6edabe4 100755
--- a/tools/testing/selftests/damon/sysfs.sh
+++ b/tools/testing/selftests/damon/sysfs.sh
@@ -361,6 +361,32 @@ test_intervals()
test_intervals_goal "$intervals_dir/intervals_goal"
}
+test_damon_prep()
+{
+ damon_prep_dir=$1
+ ensure_file "$damon_prep_dir/prep_action" "exist" "600"
+ ensure_write_succ "$damon_prep_dir/prep_action" "set_pgidle" \
+ "valid input"
+ ensure_write_fail "$damon_prep_dir/prep_action" "foo" "invalid input"
+}
+
+test_damon_preps()
+{
+ preps_dir=$1
+ ensure_dir "$preps_dir" "exist"
+ ensure_file "$preps_dir/nr_preps" "exist" "600"
+ ensure_write_succ "$preps_dir/nr_preps" "1" "valid input"
+ test_damon_prep "$preps_dir/0"
+
+ ensure_write_succ "$preps_dir/nr_preps" "2" "valid input"
+ test_damon_prep "$preps_dir/0"
+ test_damon_prep "$preps_dir/1"
+
+ ensure_write_succ "$preps_dir/nr_preps" "0" "valid input"
+ ensure_dir "$preps_dir/0" "not_exist"
+ ensure_dir "$preps_dir/1" "not_exist"
+}
+
test_damon_filter()
{
damon_filter_dir=$1
@@ -392,6 +418,7 @@ test_probe()
{
probe_dir=$1
ensure_dir "$probe_dir" "exist"
+ test_damon_preps "$probe_dir/preps"
test_damon_filters "$probe_dir/filters"
}
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* [RFC PATCH v2.1 15/17] Docs/mm/damon/design: document probe preps
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (13 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 14/17] selftests/damon/sysfs.sh: test probe prep sysfs files SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 16/17] Docs/admin-guide/mm/damon/usage: document probe preps sysfs files SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 17/17] Docs/ABI/damon: document probe prep " SJ Park
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Liam R. Howlett, Andrew Morton, David Hildenbrand,
Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
linux-kernel, linux-mm
Update DAMON design document for the newly added DAMON probe preps
feature.
Signed-off-by: SJ Park <sj@kernel.org>
---
Documentation/mm/damon/design.rst | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/mm/damon/design.rst b/Documentation/mm/damon/design.rst
index c4830bd09498d..7f983e0c39b80 100644
--- a/Documentation/mm/damon/design.rst
+++ b/Documentation/mm/damon/design.rst
@@ -309,6 +309,13 @@ Users can therefore know how much of a given DAMON region has a specific data
attribute by reading the per-region per-probe probe hits counter after each
aggregation interval.
+Users can optionally register probing preparation actions per probe. If such
+actions are registered, DAMON applies the actions to each region's sampling
+memory before starting the next sampling interval. Currently only one action,
+``set_pgidle`` is supported. The action marks the page for the probing target
+memory as access-idle. This can be useful to be used together with
+``pgidle_unset`` probe filter.
+
This is a sampling based mechanism. Hence, it is lightweight but the output
may include some measurement errors. The output should be used with good
understanding of statistics.
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* [RFC PATCH v2.1 16/17] Docs/admin-guide/mm/damon/usage: document probe preps sysfs files
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (14 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 15/17] Docs/mm/damon/design: document probe preps SJ Park
@ 2026-07-27 14:38 ` SJ Park
2026-07-27 14:38 ` [RFC PATCH v2.1 17/17] Docs/ABI/damon: document probe prep " SJ Park
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Liam R. Howlett, Andrew Morton, David Hildenbrand,
Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
linux-kernel, linux-mm
Update DAMON usage document for the newly added DAMON probe preps sysfs
files.
Signed-off-by: SJ Park <sj@kernel.org>
---
Documentation/admin-guide/mm/damon/usage.rst | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/Documentation/admin-guide/mm/damon/usage.rst b/Documentation/admin-guide/mm/damon/usage.rst
index da5f9afd08aef..023c6334024f8 100644
--- a/Documentation/admin-guide/mm/damon/usage.rst
+++ b/Documentation/admin-guide/mm/damon/usage.rst
@@ -74,6 +74,9 @@ comma (",").
│ │ │ │ │ │ nr_regions/min,max
│ │ │ │ │ │ :ref:`probes <damon_usage_sysfs_probes>`/nr_probes
│ │ │ │ │ │ │ 0/weight
+ │ │ │ │ │ │ │ │ preps/nr_preps
+ │ │ │ │ │ │ │ │ │ 0/prep_action
+ │ │ │ │ │ │ │ │ │ ...
│ │ │ │ │ │ │ │ filters/nr_filters
│ │ │ │ │ │ │ │ │ 0/type,matching,allow,path
│ │ │ │ │ │ │ │ │ ...
@@ -283,9 +286,18 @@ In the beginning, this directory has only one file, ``nr_probes``. Writing a
number (``N``) to the file creates the number of child directories named ``0``
to ``N-1``. Each directory represents each monitoring probe.
-In each probe directory, one directory, ``filters`` exists. The directory
-contains files for installing filters for the probe, that is used to determine
-the data attribute for the probe.
+In each probe directory, two directories, ``preps`` and ``filters`` exist. The
+directories contain files for installing probing preparation actions and
+filters for the probe, that are used to determine the data attribute for the
+probe.
+
+In the beginning, ``preps`` directory has only one file, ``nr_preps``.
+Writing a number (``N``) to the file creates the number of child directories
+named ``0`` to ``N-1``. Each directory represents each preparation action.
+Each directory has one file, ``prep_action``. The preparation action can be
+selected by writing the name of the action to the ``prep_action`` file. Refer
+to the :ref:`design doc <damon_design_data_attrs_monitoring>` for the list of
+supported actions.
Each probe directory also contains ``weight`` file. Reading from and writing
to the file gets and sets the :ref:`attributes-only monitoring
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread* [RFC PATCH v2.1 17/17] Docs/ABI/damon: document probe prep sysfs files
2026-07-27 14:38 [RFC PATCH v2.1 00/17] mm/damon: introduce data access-as-a-data attribute SJ Park
` (15 preceding siblings ...)
2026-07-27 14:38 ` [RFC PATCH v2.1 16/17] Docs/admin-guide/mm/damon/usage: document probe preps sysfs files SJ Park
@ 2026-07-27 14:38 ` SJ Park
16 siblings, 0 replies; 26+ messages in thread
From: SJ Park @ 2026-07-27 14:38 UTC (permalink / raw)
Cc: SJ Park, Liam R. Howlett, Andrew Morton, David Hildenbrand,
Lorenzo Stoakes, Michal Hocko, Mike Rapoport, Suren Baghdasaryan,
Vlastimil Babka, damon, linux-kernel, linux-mm
Update DAMON ABI document for the newly added DAMON probe prep sysfs
files.
Signed-off-by: SJ Park <sj@kernel.org>
---
Documentation/ABI/testing/sysfs-kernel-mm-damon | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-kernel-mm-damon b/Documentation/ABI/testing/sysfs-kernel-mm-damon
index e9488bb48d23c..ad21f58f3c912 100644
--- a/Documentation/ABI/testing/sysfs-kernel-mm-damon
+++ b/Documentation/ABI/testing/sysfs-kernel-mm-damon
@@ -173,6 +173,19 @@ Contact: SJ Park <sj@kernel.org>
Description: Writing to and reading from this file sets and gets the
per-probe attribute weight.
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/monitoring_attrs/probes/<P>/preps/nr_preps
+Date: Jun 2026
+Contact: SJ Park <sj@kernel.org>
+Description: Writing a number 'N' to this file creates the number of
+ directories for each DAMON probing preparation action named '0'
+ to 'N-1' under the preps/ directory.
+
+What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/monitoring_attrs/probes/<P>/preps/<R>/prep_action
+Date: Jun 2026
+Contact: SJ Park <sj@kernel.org>
+Description: Writing to and reading from this file sets and gets the probing
+ preparation action.
+
What: /sys/kernel/mm/damon/admin/kdamonds/<K>/contexts/<C>/monitoring_attrs/probes/<P>/filters/nr_filters
Date: May 2026
Contact: SJ Park <sj@kernel.org>
--
2.47.3
^ permalink raw reply related [flat|nested] 26+ messages in thread