DAMON development mailing list
 help / color / mirror / Atom feed
* [PATCH v2 0/4] mm/damon: repost non-hotfix reviewed patches in damon/next tree
@ 2026-04-26 23:16 SeongJae Park
  2026-04-26 23:16 ` [PATCH v2 1/4] mm/damon/ops-common: optimize damon_hot_score() using ilog2() SeongJae Park
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: SeongJae Park @ 2026-04-26 23:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: SeongJae Park, Liam R. Howlett, David Hildenbrand,
	Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
	Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
	linux-kernel, linux-kselftest, linux-mm

Re-posting non-hotfix DAMON patches that reviewed by DAMON maintainer
but not yet merged into mm.git.

The first patch from Liew Rui Yan add a minor performance optimization
using ilog2() instead of inefficient manual implementation of the
functionality.

The second patch from Cheng-Han Wu fixes a minor typo:
s/parametrs/parameters/.

The third patch from Liew Rui Yan make commit_inputs operation of
DAMON_RECLAIM and DAMON_LRU_SORT synchronous to improve the user
experience.

The fourth patch from Asier Gutierrez adds a new DAMOS action,
DAMOS_COLLAPSE for deterministic DAMOS-based access-aware THP system.

Changes from v1
- v1: https://lore.kernel.org/20260402155733.77050-1-sj@kernel.org
- Add DAMOS_COLLAPSE patch.
- Rebase to latest mm-new.

Asier Gutierrez (1):
  mm/damon: support MADV_COLLAPSE via DAMOS_COLLAPSE scheme action

Cheng-Han Wu (1):
  Docs/admin-guide/mm/damon: fix 'parametrs' typo

Liew Rui Yan (2):
  mm/damon/ops-common: optimize damon_hot_score() using ilog2()
  mm/damon: add synchronous commit for commit_inputs

 .../admin-guide/mm/damon/lru_sort.rst         |  2 +-
 .../admin-guide/mm/damon/reclaim.rst          |  2 +-
 Documentation/mm/damon/design.rst             |  4 ++
 include/linux/damon.h                         |  2 +
 mm/damon/lru_sort.c                           | 46 ++++++++++++++++---
 mm/damon/ops-common.c                         |  9 ++--
 mm/damon/reclaim.c                            | 46 ++++++++++++++++---
 mm/damon/sysfs-schemes.c                      |  4 ++
 mm/damon/vaddr.c                              |  3 ++
 tools/testing/selftests/damon/sysfs.py        | 11 +++--
 10 files changed, 105 insertions(+), 24 deletions(-)


base-commit: 1e24f85d7a997307185d5345c1711f485570a123
-- 
2.47.3

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 1/4] mm/damon/ops-common: optimize damon_hot_score() using ilog2()
  2026-04-26 23:16 [PATCH v2 0/4] mm/damon: repost non-hotfix reviewed patches in damon/next tree SeongJae Park
@ 2026-04-26 23:16 ` SeongJae Park
  2026-04-26 23:28   ` sashiko-bot
  2026-04-27 15:09   ` SeongJae Park
  2026-04-26 23:16 ` [PATCH v2 2/4] Docs/admin-guide/mm/damon: fix 'parametrs' typo SeongJae Park
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 14+ messages in thread
From: SeongJae Park @ 2026-04-26 23:16 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Liew Rui Yan, SeongJae Park, damon, linux-kernel, linux-mm

From: Liew Rui Yan <aethernet65535@gmail.com>

The current implementation of damon_hot_score() uses a manual for-loop
to calculate the value of 'age_in_log'. This can be efficiently replaced
by ilog2(), which is semantically more appropriate for calculating the
logarithmic value of age.

In a simulated-kernel-module performance test with 10,000,000 iterations,
this optimization showed a significant reduction in latency (average
latency reduced from ~12ns to ~1ns).

Test results from the simulated-kernel-module:
- ilog2:
    DAMON Perf Test: Starting 10000000 iterations
    =============================================
     Total Iterations : 10000000
     Average Latency  : 1 ns
     P95 Latency      : 41 ns
     P99 Latency      : 41 ns
    ---------------------------------------------
     Range (ns)      | Count        | Percent
    ---------------------------------------------
     0-19            | 0            |      0%
     20-39           | 2625000      |     26%
     40-59           | 7374000      |     73%
     60-79           | 0            |      0%
     80-99           | 0            |      0%
     100+            | 1000         |      0%
    =============================================

- for-loop:
    DAMON Perf Test: Starting 10000000 iterations
    =============================================
     Total Iterations : 10000000
     Average Latency  : 12 ns
     P95 Latency      : 51 ns
     P99 Latency      : 60 ns
    ---------------------------------------------
     Range (ns)      | Count        | Percent
    ---------------------------------------------
     0-19            | 0            |      0%
     20-39           | 0            |      0%
     40-59           | 9862000      |     98%
     60-79           | 135000       |      1%
     80-99           | 1000         |      0%
     100+            | 2000         |      0%
    =============================================

Full raw benchmark results can be found at [1].

[1] https://github.com/aethernet65535/damon-hot-score-fls-optimize/tree/master/result-raw

Signed-off-by: Liew Rui Yan <aethernet65535@gmail.com>
Reviewed-by: SeongJae Park <sj@kernel.org>
Signed-off-by: SeongJae Park <sj@kernel.org>
---
Changes from v2
(https://lore.kernel.org/20260320192020.33004-1-aethernet65535@gmail.com)
- Rebase to latest mm-new.
Changes from v1 (actually it was RFC)
(https://lore.kernel.org/20260320072431.248235-1-aethernet65535@gmail.com)
- Replace fls() with ilog2() per SeongJae Park's suggestion for better
  semantic clarity.
- Move performance benchmark results into the commit message and add
  comparison between for-loop and ilog2.

 mm/damon/ops-common.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c
index 8c6d613425c13..3a0ddc3ac7196 100644
--- a/mm/damon/ops-common.c
+++ b/mm/damon/ops-common.c
@@ -117,9 +117,12 @@ int damon_hot_score(struct damon_ctx *c, struct damon_region *r,
 		damon_max_nr_accesses(&c->attrs);
 
 	age_in_sec = (unsigned long)r->age * c->attrs.aggr_interval / 1000000;
-	for (age_in_log = 0; age_in_log < DAMON_MAX_AGE_IN_LOG && age_in_sec;
-			age_in_log++, age_in_sec >>= 1)
-		;
+	if (age_in_sec)
+		age_in_log = min_t(int, ilog2(age_in_sec) + 1,
+				DAMON_MAX_AGE_IN_LOG);
+	else
+		age_in_log = 0;
+
 
 	/* If frequency is 0, higher age means it's colder */
 	if (freq_subscore == 0)
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 2/4] Docs/admin-guide/mm/damon: fix 'parametrs' typo
  2026-04-26 23:16 [PATCH v2 0/4] mm/damon: repost non-hotfix reviewed patches in damon/next tree SeongJae Park
  2026-04-26 23:16 ` [PATCH v2 1/4] mm/damon/ops-common: optimize damon_hot_score() using ilog2() SeongJae Park
@ 2026-04-26 23:16 ` SeongJae Park
  2026-04-27 23:39   ` SeongJae Park
  2026-04-26 23:16 ` [PATCH v2 3/4] mm/damon: add synchronous commit for commit_inputs SeongJae Park
  2026-04-26 23:16 ` [PATCH v2 4/4] mm/damon: support MADV_COLLAPSE via DAMOS_COLLAPSE scheme action SeongJae Park
  3 siblings, 1 reply; 14+ messages in thread
From: SeongJae Park @ 2026-04-26 23:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Cheng-Han Wu, Liam R. Howlett, David Hildenbrand, Jonathan Corbet,
	Lorenzo Stoakes, Michal Hocko, Mike Rapoport, SeongJae Park,
	Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
	linux-kernel, linux-mm

From: Cheng-Han Wu <hank20010209@gmail.com>

Fix the misspelling of "parametrs" as "parameters" in
reclaim.rst and lru_sort.rst.

Signed-off-by: Cheng-Han Wu <hank20010209@gmail.com>
Signed-off-by: SeongJae Park <sj@kernel.org>
---
Changes from v1
(https://lore.kernel.org/20260324144851.12883-1-hank20010209@gmail.com)
- Rebase to latest mm-new.

 Documentation/admin-guide/mm/damon/lru_sort.rst | 2 +-
 Documentation/admin-guide/mm/damon/reclaim.rst  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/mm/damon/lru_sort.rst b/Documentation/admin-guide/mm/damon/lru_sort.rst
index 14cc6b2db8973..25e2f042a383f 100644
--- a/Documentation/admin-guide/mm/damon/lru_sort.rst
+++ b/Documentation/admin-guide/mm/damon/lru_sort.rst
@@ -75,7 +75,7 @@ Make DAMON_LRU_SORT reads the input parameters again, except ``enabled``.
 
 Input parameters that updated while DAMON_LRU_SORT is running are not applied
 by default.  Once this parameter is set as ``Y``, DAMON_LRU_SORT reads values
-of parametrs except ``enabled`` again.  Once the re-reading is done, this
+of parameters except ``enabled`` again.  Once the re-reading is done, this
 parameter is set as ``N``.  If invalid parameters are found while the
 re-reading, DAMON_LRU_SORT will be disabled.
 
diff --git a/Documentation/admin-guide/mm/damon/reclaim.rst b/Documentation/admin-guide/mm/damon/reclaim.rst
index d7a0225b49508..01a34c215b66f 100644
--- a/Documentation/admin-guide/mm/damon/reclaim.rst
+++ b/Documentation/admin-guide/mm/damon/reclaim.rst
@@ -67,7 +67,7 @@ Make DAMON_RECLAIM reads the input parameters again, except ``enabled``.
 
 Input parameters that updated while DAMON_RECLAIM is running are not applied
 by default.  Once this parameter is set as ``Y``, DAMON_RECLAIM reads values
-of parametrs except ``enabled`` again.  Once the re-reading is done, this
+of parameters except ``enabled`` again.  Once the re-reading is done, this
 parameter is set as ``N``.  If invalid parameters are found while the
 re-reading, DAMON_RECLAIM will be disabled.
 
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 3/4] mm/damon: add synchronous commit for commit_inputs
  2026-04-26 23:16 [PATCH v2 0/4] mm/damon: repost non-hotfix reviewed patches in damon/next tree SeongJae Park
  2026-04-26 23:16 ` [PATCH v2 1/4] mm/damon/ops-common: optimize damon_hot_score() using ilog2() SeongJae Park
  2026-04-26 23:16 ` [PATCH v2 2/4] Docs/admin-guide/mm/damon: fix 'parametrs' typo SeongJae Park
@ 2026-04-26 23:16 ` SeongJae Park
  2026-04-27  0:00   ` sashiko-bot
  2026-04-26 23:16 ` [PATCH v2 4/4] mm/damon: support MADV_COLLAPSE via DAMOS_COLLAPSE scheme action SeongJae Park
  3 siblings, 1 reply; 14+ messages in thread
From: SeongJae Park @ 2026-04-26 23:16 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Liew Rui Yan, SeongJae Park, damon, linux-kernel, linux-mm

From: Liew Rui Yan <aethernet65535@gmail.com>

Problem
=======
Writing invalid parameters to sysfs followed by 'commit_inputs=Y' fails
silently (no error returned to shell), because the validation happens
asynchronously in the kdamond.

Solution
========
To fix this, the commit_inputs_store() callback now uses damon_call() to
synchronously commit parameters in the kdamond thread's safe context.
This ensures that validation errors are returned immediately to
userspace, following the pattern used by DAMON_SYSFS.

Changes
=======
1. Added commit_inputs_store() and commit_inputs_fn() to commit
   synchronously.
2. Removed handle_commit_inputs().

This change is motivated from another discussion [1].

[1] https://lore.kernel.org/20260318153731.97470-1-aethernet65535@gmail.com

Signed-off-by: Liew Rui Yan <aethernet65535@gmail.com>
Reviewed-by: SeongJae Park <sj@kernel.org>
Signed-off-by: SeongJae Park <sj@kernel.org>
---
Changes from v2
(https://lore.kernelorg/20260329075415.36775-1-aethernet65535@gmail.com)
- Rebase to latest mm-new.
Changes from v1:
- Restore the KERNEL_PARAM_OPS_FL_NOARG flag to keep the compatibility.
- Link to V1: https://lore.kernel.org/20260328084524.5451-1-aethernet65535@gmail.com
Changes from RFC-v6
- Removed unnecessary assignment (repeat) in commit_inputs_store().
- Change the return value; if an error occurs, return the error code.
- Removed the RFC tag.
- Link to RFC-v6: https://lore.kernel.org/20260327062558.66392-1-aethernet65535@gmail.com
Changes from RFC-v5:
- Removed unnecessary assignment (data) in commit_inputs_store().
- Return -EINVAL instead of -EBUSY when 'commit_inputs' is triggered
  while kdamond is not running.
- Link to RFC-v5: https://lore.kernel.org/20260325013939.18167-1-aethernet65535@gmail.com
Changes from RFC-v4:
- Rename the 'yes' variable in commit_inputs_store() to the more
  understandable 'commit_inputs_request'.
- Return -EBUSY instead of -EINVAL when 'commit_inputs' is triggered
  while kdamond is not running.
- Link to RFC-v4: https://lore.kernel.org/20260323021648.6590-1-aethernet65535@gmail.com
Changes from RFC-v3:
- Added checks for 'ctx' and 'damon_is_running()' to prevent NULL
  pointer dereference during early boot. (Found by Sashiko.dev)
- Removed handle_commit_inputs() and its associated polling logic as
  they have become dead code after moving to the synchronous damon_call()
  approach.
- Ensure the 'commit_inputs' is properly updated.
Link to RFC-v3: https://lore.kernel.org/20260322231522.32700-1-aethernet65535@gmail.com
Changes from RFC-v2:
- Removed damon_validate_attrs(), now using damon_commit_ctx() for
  synchronous validation in the kdamond context.
- Following DAMON_SYSFS pattern for synchronous commit via damon_call().
- Link to RFC-v2: https://lore.kernel.org/20260321140926.22163-1-aethernet65535@gmail.com
Changes from RFC-v1:
- Remove question from commit message area.
- Added synchronous validation for DAMON_RECLAIM.
- Rename damon_valid_attrs() -> damon_validate_attrs().
- Exported a new function damon_validate_attrs() and declared it in
  damon.h.
- Link to RFC-v1: https://lore.kernel.org/20260321002642.22712-1-aethernet65535@gmail.com

 mm/damon/lru_sort.c | 46 ++++++++++++++++++++++++++++++++++++++-------
 mm/damon/reclaim.c  | 46 ++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 78 insertions(+), 14 deletions(-)

diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
index 8494040b1ee48..7569e471160a0 100644
--- a/mm/damon/lru_sort.c
+++ b/mm/damon/lru_sort.c
@@ -39,7 +39,6 @@ static bool enabled __read_mostly;
  * the re-reading, DAMON_LRU_SORT will be disabled.
  */
 static bool commit_inputs __read_mostly;
-module_param(commit_inputs, bool, 0600);
 
 /*
  * Desired active to [in]active memory ratio in bp (1/10,000).
@@ -340,18 +339,51 @@ static int damon_lru_sort_apply_parameters(void)
 	return err;
 }
 
-static int damon_lru_sort_handle_commit_inputs(void)
+static int damon_lru_sort_commit_inputs_fn(void *arg)
 {
+	return damon_lru_sort_apply_parameters();
+}
+
+static int damon_lru_sort_commit_inputs_store(const char *val,
+					      const struct kernel_param *kp)
+{
+	bool commit_inputs_request;
 	int err;
+	struct damon_call_control control = {
+		.fn = damon_lru_sort_commit_inputs_fn,
+	};
+
+	if (!val) {
+		commit_inputs_request = true;
+	} else {
+		err = kstrtobool(val, &commit_inputs_request);
+		if (err)
+			return err;
+	}
 
-	if (!commit_inputs)
+	if (!commit_inputs_request)
 		return 0;
 
-	err = damon_lru_sort_apply_parameters();
-	commit_inputs = false;
-	return err;
+	/*
+	 * Skip damon_call() if ctx is not initialized to avoid
+	 * NULL pointer dereference.
+	 */
+	if (!ctx)
+		return -EINVAL;
+
+	err = damon_call(ctx, &control);
+
+	return err ? err : control.return_code;
 }
 
+static const struct kernel_param_ops commit_inputs_param_ops = {
+	.flags = KERNEL_PARAM_OPS_FL_NOARG,
+	.set = damon_lru_sort_commit_inputs_store,
+	.get = param_get_bool,
+};
+
+module_param_cb(commit_inputs, &commit_inputs_param_ops, &commit_inputs, 0600);
+
 static int damon_lru_sort_damon_call_fn(void *arg)
 {
 	struct damon_ctx *c = arg;
@@ -365,7 +397,7 @@ static int damon_lru_sort_damon_call_fn(void *arg)
 			damon_lru_sort_cold_stat = s->stat;
 	}
 
-	return damon_lru_sort_handle_commit_inputs();
+	return 0;
 }
 
 static struct damon_call_control call_control = {
diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
index fe7fce26cf6ce..b330ff1695907 100644
--- a/mm/damon/reclaim.c
+++ b/mm/damon/reclaim.c
@@ -39,7 +39,6 @@ static bool enabled __read_mostly;
  * re-reading, DAMON_RECLAIM will be disabled.
  */
 static bool commit_inputs __read_mostly;
-module_param(commit_inputs, bool, 0600);
 
 /*
  * Time threshold for cold memory regions identification in microseconds.
@@ -246,18 +245,51 @@ static int damon_reclaim_apply_parameters(void)
 	return err;
 }
 
-static int damon_reclaim_handle_commit_inputs(void)
+static int damon_reclaim_commit_inputs_fn(void *arg)
 {
+	return damon_reclaim_apply_parameters();
+}
+
+static int damon_reclaim_commit_inputs_store(const char *val,
+					     const struct kernel_param *kp)
+{
+	bool commit_inputs_request;
 	int err;
+	struct damon_call_control control = {
+		.fn = damon_reclaim_commit_inputs_fn,
+	};
 
-	if (!commit_inputs)
+	if (!val) {
+		commit_inputs_request = true;
+	} else {
+		err = kstrtobool(val, &commit_inputs_request);
+		if (err)
+			return err;
+	}
+
+	if (!commit_inputs_request)
 		return 0;
 
-	err = damon_reclaim_apply_parameters();
-	commit_inputs = false;
-	return err;
+	/*
+	 * Skip damon_call() if ctx is not initialized to avoid
+	 * NULL pointer dereference.
+	 */
+	if (!ctx)
+		return -EINVAL;
+
+	err = damon_call(ctx, &control);
+
+	return err ? err : control.return_code;
 }
 
+static const struct kernel_param_ops commit_inputs_param_ops = {
+	.flags = KERNEL_PARAM_OPS_FL_NOARG,
+	.set = damon_reclaim_commit_inputs_store,
+	.get = param_get_bool,
+};
+
+module_param_cb(commit_inputs, &commit_inputs_param_ops, &commit_inputs, 0600);
+
 static int damon_reclaim_damon_call_fn(void *arg)
 {
 	struct damon_ctx *c = arg;
@@ -267,7 +299,7 @@ static int damon_reclaim_damon_call_fn(void *arg)
 	damon_for_each_scheme(s, c)
 		damon_reclaim_stat = s->stat;
 
-	return damon_reclaim_handle_commit_inputs();
+	return 0;
 }
 
 static struct damon_call_control call_control = {
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 4/4] mm/damon: support MADV_COLLAPSE via DAMOS_COLLAPSE scheme action
  2026-04-26 23:16 [PATCH v2 0/4] mm/damon: repost non-hotfix reviewed patches in damon/next tree SeongJae Park
                   ` (2 preceding siblings ...)
  2026-04-26 23:16 ` [PATCH v2 3/4] mm/damon: add synchronous commit for commit_inputs SeongJae Park
@ 2026-04-26 23:16 ` SeongJae Park
  2026-04-27 23:41   ` SeongJae Park
  3 siblings, 1 reply; 14+ messages in thread
From: SeongJae Park @ 2026-04-26 23:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Asier Gutierrez, Liam R. Howlett, David Hildenbrand,
	Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
	SeongJae Park, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
	damon, linux-doc, linux-kernel, linux-kselftest, linux-mm

From: Asier Gutierrez <gutierrez.asier@huawei-partners.com>

This patch set introces a new action:  DAMOS_COLLAPSE.

For DAMOS_HUGEPAGE and DAMOS_NOHUGEPAGE to work, khugepaged should be
working, since it relies on hugepage_madvise to add a new slot. This
slot should be picked up by khugepaged and eventually collapse (or
not, if we are using DAMOS_NOHUGEPAGE) the pages. If THP is not
enabled, khugepaged will not be working, and therefore no collapse
will happen.

DAMOS_COLLAPSE eventually calls madvise_collapse, which will collapse
the address range synchronously. In cases where there is a large VMA
(databases, for example), DAMOS_COLLAPSE allows us to collapse only
the hot region, and not the entire VMA.

This new action may be required to support autotuning with hugepage
as a goal[1].

=========
Benchmarks:
=========

MySQL
=====

Tests were performed in an ARM physical server with MariaDB 10.5 and
sysbench. Read only benchmark was perform with gaussian row hitting,
which follows a normal distribution.

T n, D h: THP set to never, DAMON action set to hugepage
T m, D h: THP set to madvise, DAMON action set to hugepage
T n, D c: THP set to never, DAMON action set to collapse

Memory consumption. Lower is better.

+------------------+----------+----------+----------+
|                  | T n, D h | T m, D h | T n, D c |
+------------------+----------+----------+----------+
| Total memory use | 2.13     | 2.20     | 2.20     |
| Huge pages       | 0        | 1.3      | 1.27     |
+------------------+----------+----------+----------+

Performance in TPS (Transactions Per Second). Higher is better.

T n, D h: 18225.58
T m, D h 18252.93
T n, D c: 18270.21

Performance counter

I got the number of L1 D/I TLB accesses and the number a D/I TLB
accesses that triggered a page walk. I divided the second by the
first to get the percentage of page walkes per TLB access. The
lower the better.

+---------------+--------------+--------------+--------------+
|               | T n, D h     | T m, D h     | T n, D c     |
+---------------+--------------+--------------+--------------+
| L1 DTLB       | 127248242753 | 125431020479 | 125327001821 |
| L1 ITLB       | 80332558619  | 79346759071  | 79298139590  |
| DTLB walk     | 75011087     | 52800418     | 55895794     |
| ITLB walk     | 71577076     | 71505137     | 67262140     |
| DTLB % misses | 0.058948623  | 0.042095183  | 0.044599961  |
| ITLB % misses | 0.089100954  | 0.090117275  | 0.084821839  |
+---------------+--------------+--------------+--------------+

Masim
=====

I used masim with the "demo" configuration, but changing the times
to 100 seconds for the initial phase and 50 seconds for the rest of
the phases.

Memory consumption:

+------------------+----------+----------+----------+
|                  | T n, D h | T m, D h | T n, D c |
+------------------+----------+----------+----------+
| Total memory use | 2.38 GB  | 2.36 GB  | 2.37 GB  |
| Huge pages       | 0        | 190 MB   | 188 MB   |
+------------------+----------+----------+----------+

Performance:

THP never, DAMOS_HUGEPAGE
initial phase:                40,491 accesses/msec, 100001 msecs run
low phase 0:                  39,658 accesses/msec, 50002 msecs run
high phase 0:                 41,678 accesses/msec, 50000 msecs run
low phase 1:                  39,625 accesses/msec, 50003 msecs run
high phase 1:                 41,658 accesses/msec, 50002 msecs run
low phase 2:                  39,642 accesses/msec, 50002 msecs run
high phase 2:                 41,640 accesses/msec, 50001 msecs run

THP madvise, DAMOS_HUGEPAGE
initial phase:                51,977 accesses/msec, 100000 msecs run
low phase 0:                  86,953 accesses/msec, 50000 msecs run
high phase 0:                 94,812 accesses/msec, 50000 msecs run
low phase 1:                 101,017 accesses/msec, 50000 msecs run
high phase 1:                 94,841 accesses/msec, 50000 msecs run
low phase 2:                 100,993 accesses/msec, 50000 msecs run
high phase 2:                 94,791 accesses/msec, 50001 msecs run

THP never, DAMOS_COLLAPSE
initial phase:                93,678 accesses/msec, 100001 msecs run
low phase 0:                 101,475 accesses/msec, 50000 msecs run
high phase 0:                 98,589 accesses/msec, 50000 msecs run
low phase 1:                 101,531 accesses/msec, 50001 msecs run
high phase 1:                 98,506 accesses/msec, 50001 msecs run
low phase 2:                 101,458 accesses/msec, 50001 msecs run
high phase 2:                 98,555 accesses/msec, 50000 msecs run

Memory consumption dynamic (how quickly collapses occur):

It shows in seconds how many huge pages are allocated.

+----+----------+----------+
|    | T m, D h | T n, D c |
+----+----------+----------+
| 5  | 32       | 188      |
| 10 | 48       | 188      |
| 15 | 64       | 188      |
| 20 | 96       | 188      |
| 30 | 112      | 188      |
| 35 | 144      | 188      |
| 40 | 160      | 188      |
| 45 | 190      | 188      |
| 50 | 190      | 188      |
| 55 | 190      | 188      |
| 60 | 190      | 188      |
+----+----------+----------+

=========

- We can see that DAMOS "hugepage" action works only when THP is set
  to madvise. "collapse" action works even when THP is set to never.
- Performance for "collapse" action is slightly lower than "hugepage"
  action and THP madvise. This is due to the fact that collapases
  occur synchronously. With "hugepage" they may occur during page
  faults.
- Memory consumption is slighly lower for "collapse" than "hugepage"
  with THP madvise. This is due to the khugepage collapses all VMAs,
  while "collapse" action only collapses the VMAs in the hot region.
- There is an improvement in TLB utilization when collapse through
  "hugepage" or "collapse" actions are triggered. The amount of
  TLB misses is lower.
- "collapse" action is performance synchronously, which means that
  page collapses happen earlier and more rapidly. This can be
  useful or not, depending on the scenario.
- "hugepage" action may trigger a VMA split in some scenarios, since
  it needs to change the flag of the VMA to THP enabled. This may
  lead to additional overhead.

Collapse action just adds a new option to chose the correct system
balance.

[1]: https://lore.kernel.org/damon/20260313000816.79933-1-sj@kernel.org/

Signed-off-by: Asier Gutierrez <gutierrez.asier@huawei-partners.com>
Signed-off-by: SeongJae Park <sj@kernel.org>
---
Changes from v2:
- v2: https://lore.kernel.org/20260409150128.1566835-1-gutierrez.asier@huawei-partners.com
- Add Reviewed-by: from SJ
- Wordsmith changelog
- Rebase to latest mm-new
Chagens from v1:
- v1: https://lore.kernel.org/20260330145758.2115502-1-gutierrez.asier@huawei-partners.com/
- Added masim benchmark
- Added performance benchmark for MariaDB
Changes from RFC v2:
- RFC v2: https://lore.kernel.org/20260323145646.4165053-1-gutierrez.asier@huawei-partners.com/
- Fixed a missing comma in the selftest python stript
- Added performance benchmarks
Changes from RFC:
- RFC: https://lore.kernel.org/20260316183805.2090297-1-gutierrez.asier@huawei-partners.com
- Added benchmarks
- Added damos_filter_type documentation for new action to fix kernel-doc

 Documentation/mm/damon/design.rst      |  4 ++++
 include/linux/damon.h                  |  2 ++
 mm/damon/sysfs-schemes.c               |  4 ++++
 mm/damon/vaddr.c                       |  3 +++
 tools/testing/selftests/damon/sysfs.py | 11 ++++++-----
 5 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/Documentation/mm/damon/design.rst b/Documentation/mm/damon/design.rst
index afc7d52bda2f7..365e068a8dbe4 100644
--- a/Documentation/mm/damon/design.rst
+++ b/Documentation/mm/damon/design.rst
@@ -474,6 +474,10 @@ that supports each action are as below.
    Supported by ``vaddr`` and ``fvaddr`` operations set. When
    TRANSPARENT_HUGEPAGE is disabled, the application of the action will just
    fail.
+ - ``collapse``: Call ``madvise()`` for the region with ``MADV_COLLAPSE``.
+   Supported by ``vaddr`` and ``fvaddr`` operations set. When
+   TRANSPARENT_HUGEPAGE is disabled, the application of the action will just
+   fail.
  - ``lru_prio``: Prioritize the region on its LRU lists.
    Supported by ``paddr`` operations set.
  - ``lru_deprio``: Deprioritize the region on its LRU lists.
diff --git a/include/linux/damon.h b/include/linux/damon.h
index f2cdb7c3f5e6c..ac71b845bb6e8 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -121,6 +121,7 @@ struct damon_target {
  * @DAMOS_PAGEOUT:	Reclaim the region.
  * @DAMOS_HUGEPAGE:	Call ``madvise()`` for the region with MADV_HUGEPAGE.
  * @DAMOS_NOHUGEPAGE:	Call ``madvise()`` for the region with MADV_NOHUGEPAGE.
+ * @DAMOS_COLLAPSE:	Call ``madvise()`` for the region with MADV_COLLAPSE.
  * @DAMOS_LRU_PRIO:	Prioritize the region on its LRU lists.
  * @DAMOS_LRU_DEPRIO:	Deprioritize the region on its LRU lists.
  * @DAMOS_MIGRATE_HOT:  Migrate the regions prioritizing warmer regions.
@@ -140,6 +141,7 @@ enum damos_action {
 	DAMOS_PAGEOUT,
 	DAMOS_HUGEPAGE,
 	DAMOS_NOHUGEPAGE,
+	DAMOS_COLLAPSE,
 	DAMOS_LRU_PRIO,
 	DAMOS_LRU_DEPRIO,
 	DAMOS_MIGRATE_HOT,
diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c
index 04746cbb33272..c14a564dd8218 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -2061,6 +2061,10 @@ static struct damos_sysfs_action_name damos_sysfs_action_names[] = {
 		.action = DAMOS_NOHUGEPAGE,
 		.name = "nohugepage",
 	},
+	{
+		.action = DAMOS_COLLAPSE,
+		.name = "collapse",
+	},
 	{
 		.action = DAMOS_LRU_PRIO,
 		.name = "lru_prio",
diff --git a/mm/damon/vaddr.c b/mm/damon/vaddr.c
index b069dbc7e3d25..dd5f2d7027ac4 100644
--- a/mm/damon/vaddr.c
+++ b/mm/damon/vaddr.c
@@ -903,6 +903,9 @@ static unsigned long damon_va_apply_scheme(struct damon_ctx *ctx,
 	case DAMOS_NOHUGEPAGE:
 		madv_action = MADV_NOHUGEPAGE;
 		break;
+	case DAMOS_COLLAPSE:
+		madv_action = MADV_COLLAPSE;
+		break;
 	case DAMOS_MIGRATE_HOT:
 	case DAMOS_MIGRATE_COLD:
 		return damos_va_migrate(t, r, scheme, sz_filter_passed);
diff --git a/tools/testing/selftests/damon/sysfs.py b/tools/testing/selftests/damon/sysfs.py
index 3aa5c91548a53..72f53180c6a88 100755
--- a/tools/testing/selftests/damon/sysfs.py
+++ b/tools/testing/selftests/damon/sysfs.py
@@ -123,11 +123,12 @@ def assert_scheme_committed(scheme, dump):
             'pageout': 2,
             'hugepage': 3,
             'nohugeapge': 4,
-            'lru_prio': 5,
-            'lru_deprio': 6,
-            'migrate_hot': 7,
-            'migrate_cold': 8,
-            'stat': 9,
+            'collapse': 5,
+            'lru_prio': 6,
+            'lru_deprio': 7,
+            'migrate_hot': 8,
+            'migrate_cold': 9,
+            'stat': 10,
             }
     assert_true(dump['action'] == action_val[scheme.action], 'action', dump)
     assert_true(dump['apply_interval_us'] == scheme. apply_interval_us,
-- 
2.47.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 1/4] mm/damon/ops-common: optimize damon_hot_score() using ilog2()
  2026-04-26 23:16 ` [PATCH v2 1/4] mm/damon/ops-common: optimize damon_hot_score() using ilog2() SeongJae Park
@ 2026-04-26 23:28   ` sashiko-bot
  2026-04-27 14:18     ` SeongJae Park
  2026-04-27 15:09   ` SeongJae Park
  1 sibling, 1 reply; 14+ messages in thread
From: sashiko-bot @ 2026-04-26 23:28 UTC (permalink / raw)
  To: SeongJae Park; +Cc: damon

Sashiko AI review found 3 potential issue(s):
- [High] Arithmetic overflow on 32-bit architectures during `age_in_sec` calculation.
- [Low] The logic using `ilog2()` with a zero-check branch can be simplified by directly using `fls()`.
- [Low] Unnecessary double blank line introduced.
--

commit c096ebdf3dd6d7a6e783e2ac65dec1740282929f
Author: Liew Rui Yan <aethernet65535@gmail.com>

    mm/damon/ops-common: optimize damon_hot_score() using ilog2()

This commit replaces the manual for-loop used to calculate age_in_log
in damon_hot_score() with the ilog2() function. This optimization aims to
significantly reduce the latency of the hotness score calculation.

> diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c
> index 8c6d613425c1..3a0ddc3ac719 100644
> --- a/mm/damon/ops-common.c
> +++ b/mm/damon/ops-common.c
> @@ -117,9 +117,12 @@ int damon_hot_score(struct damon_ctx *c, struct damon_region *r,
>  		damon_max_nr_accesses(&c->attrs);
>  
>  	age_in_sec = (unsigned long)r->age * c->attrs.aggr_interval / 1000000;

This isn't a bug in your patch, but does the multiplication of
(unsigned long)r->age * c->attrs.aggr_interval overflow on 32-bit
architectures?

Since both variables evaluate as 32-bit types on 32-bit architectures,
if aggr_interval is 1,000,000 (1 second), the multiplication will wrap
around when r->age exceeds 4294. This wrap-around could result in a very
small age_in_sec value for extremely cold regions, causing them to be
falsely evaluated as young and hot.

Should this calculation be cast to a 64-bit integer prior to multiplication,
perhaps using div_u64()?

> -	for (age_in_log = 0; age_in_log < DAMON_MAX_AGE_IN_LOG && age_in_sec;
> -			age_in_log++, age_in_sec >>= 1)
> -		;
> +	if (age_in_sec)
> +		age_in_log = min_t(int, ilog2(age_in_sec) + 1,
> +				DAMON_MAX_AGE_IN_LOG);
> +	else
> +		age_in_log = 0;

Instead of using ilog2() with a zero-check branch, could this be simplified
by directly using fls()?

The fls() function safely returns 0 when the value is 0 and correctly
calculates the 1-based log2 value for positive numbers, allowing this
branch to be removed entirely while preserving the exact mathematical
result.

> +
>  
>  	/* If frequency is 0, higher age means it's colder */

This isn't a bug, but an extra blank line appears to be introduced here,
creating two consecutive blank lines.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260426231619.107231-1-sj@kernel.org?part=1

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/4] mm/damon: add synchronous commit for commit_inputs
  2026-04-26 23:16 ` [PATCH v2 3/4] mm/damon: add synchronous commit for commit_inputs SeongJae Park
@ 2026-04-27  0:00   ` sashiko-bot
  2026-04-27 14:30     ` SeongJae Park
  0 siblings, 1 reply; 14+ messages in thread
From: sashiko-bot @ 2026-04-27  0:00 UTC (permalink / raw)
  To: SeongJae Park; +Cc: damon

Sashiko AI review found 1 potential issue(s):
- [High] Writing to the `commit_inputs` sysfs parameter before the DAMON worker thread (`kdamond`) is started causes the writing task to hang indefinitely in an unkillable D-state.
--

commit 43a70e5ab295c21c0b94eddd32d886c9d0eba3fa
Author: Liew Rui Yan <aethernet65535@gmail.com>

mm/damon: add synchronous commit for commit_inputs

This commit changes the commit_inputs_store() callback to use damon_call()
to synchronously commit parameters in the kdamond thread's safe context.
This ensures validation errors are returned immediately to userspace.

Link: https://lore.kernel.org/20260318153731.97470-1-aethernet65535@gmail.com

> diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
> index 554559d72976..641af42cc2d1 100644
> --- a/mm/damon/lru_sort.c
> +++ b/mm/damon/lru_sort.c

[ ... ]

> @@ -349,18 +348,51 @@ static int damon_lru_sort_apply_parameters(void)
>  	return err;
>  }
>  
> -static int damon_lru_sort_handle_commit_inputs(void)
> +static int damon_lru_sort_commit_inputs_fn(void *arg)
>  {
> +	return damon_lru_sort_apply_parameters();
> +}
> +
> +static int damon_lru_sort_commit_inputs_store(const char *val,
> +					      const struct kernel_param *kp)
> +{
> +	bool commit_inputs_request;
>  	int err;
> +	struct damon_call_control control = {
> +		.fn = damon_lru_sort_commit_inputs_fn,
> +	};
>  
> -	if (!commit_inputs)
> +	if (!val) {
> +		commit_inputs_request = true;
> +	} else {
> +		err = kstrtobool(val, &commit_inputs_request);
> +		if (err)
> +			return err;
> +	}
>  
> +	if (!commit_inputs_request)
>  		return 0;
>  
> -	err = damon_lru_sort_apply_parameters();
> -	commit_inputs = false;
> -	return err;
> +	/*
> +	 * Skip damon_call() if ctx is not initialized to avoid
> +	 * NULL pointer dereference.
> +	 */
> +	if (!ctx)
> +		return -EINVAL;
> +
> +	err = damon_call(ctx, &control);

If the module has not yet been enabled (e.g., enabled=N) and the kdamond
thread is not running, does this call to damon_call() block indefinitely?

Since ctx is allocated during initialization, the ctx pointer is not NULL.
damon_call() then queues the control request and calls wait_for_completion().

Without the background thread running to process the queue and signal
completion, it seems the sysfs writer task is placed into an unkillable
D-state forever.

The damon_call() documentation indicates it should only be called after
damon_start() has succeeded, otherwise it could fall into an indefinite wait.

> +
> +	return err ? err : control.return_code;
>  }

[ ... ]

> diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
> index 86da14778658..4fc4a54b5e54 100644
> --- a/mm/damon/reclaim.c
> +++ b/mm/damon/reclaim.c

[ ... ]

> @@ -255,18 +254,51 @@ static int damon_reclaim_apply_parameters(void)
>  	return err;
>  }
>  
> -static int damon_reclaim_handle_commit_inputs(void)
> +static int damon_reclaim_commit_inputs_fn(void *arg)
>  {
> +	return damon_reclaim_apply_parameters();
> +}
> +
> +static int damon_reclaim_commit_inputs_store(const char *val,
> +					     const struct kernel_param *kp)
> +{
> +	bool commit_inputs_request;
>  	int err;
> +	struct damon_call_control control = {
> +		.fn = damon_reclaim_commit_inputs_fn,
> +	};
>  
> -	if (!commit_inputs)
> +	if (!val) {
> +		commit_inputs_request = true;
> +	} else {
> +		err = kstrtobool(val, &commit_inputs_request);
> +		if (err)
> +			return err;
> +	}
> +
> +	if (!commit_inputs_request)
>  		return 0;
>  
> -	err = damon_reclaim_apply_parameters();
> -	commit_inputs = false;
> -	return err;
> +	/*
> +	 * Skip damon_call() if ctx is not initialized to avoid
> +	 * NULL pointer dereference.
> +	 */
> +	if (!ctx)
> +		return -EINVAL;
> +
> +	err = damon_call(ctx, &control);

Could this exhibit the same hang as in damon_lru_sort.c? If the worker
thread has not been started, does writing to commit_inputs block forever?

> +
> +	return err ? err : control.return_code;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260426231619.107231-1-sj@kernel.org?part=3

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 1/4] mm/damon/ops-common: optimize damon_hot_score() using ilog2()
  2026-04-26 23:28   ` sashiko-bot
@ 2026-04-27 14:18     ` SeongJae Park
  0 siblings, 0 replies; 14+ messages in thread
From: SeongJae Park @ 2026-04-27 14:18 UTC (permalink / raw)
  To: sashiko-bot; +Cc: SeongJae Park, damon

On Sun, 26 Apr 2026 23:28:10 +0000 sashiko-bot@kernel.org wrote:

> Sashiko AI review found 3 potential issue(s):
> - [High] Arithmetic overflow on 32-bit architectures during `age_in_sec` calculation.
> - [Low] The logic using `ilog2()` with a zero-check branch can be simplified by directly using `fls()`.
> - [Low] Unnecessary double blank line introduced.
> --
> 
> commit c096ebdf3dd6d7a6e783e2ac65dec1740282929f
> Author: Liew Rui Yan <aethernet65535@gmail.com>
> 
>     mm/damon/ops-common: optimize damon_hot_score() using ilog2()
> 
> This commit replaces the manual for-loop used to calculate age_in_log
> in damon_hot_score() with the ilog2() function. This optimization aims to
> significantly reduce the latency of the hotness score calculation.
> 
> > diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c
> > index 8c6d613425c1..3a0ddc3ac719 100644
> > --- a/mm/damon/ops-common.c
> > +++ b/mm/damon/ops-common.c
> > @@ -117,9 +117,12 @@ int damon_hot_score(struct damon_ctx *c, struct damon_region *r,
> >  		damon_max_nr_accesses(&c->attrs);
> >  
> >  	age_in_sec = (unsigned long)r->age * c->attrs.aggr_interval / 1000000;
> 
> This isn't a bug in your patch, but does the multiplication of
> (unsigned long)r->age * c->attrs.aggr_interval overflow on 32-bit
> architectures?
> 
> Since both variables evaluate as 32-bit types on 32-bit architectures,
> if aggr_interval is 1,000,000 (1 second), the multiplication will wrap
> around when r->age exceeds 4294. This wrap-around could result in a very
> small age_in_sec value for extremely cold regions, causing them to be
> falsely evaluated as young and hot.
> 
> Should this calculation be cast to a 64-bit integer prior to multiplication,
> perhaps using div_u64()?

Good point, but as Sashiko also notes, not a blocker of this patch.  I will add
a todo item for thinking more on this.

> 
> > -	for (age_in_log = 0; age_in_log < DAMON_MAX_AGE_IN_LOG && age_in_sec;
> > -			age_in_log++, age_in_sec >>= 1)
> > -		;
> > +	if (age_in_sec)
> > +		age_in_log = min_t(int, ilog2(age_in_sec) + 1,
> > +				DAMON_MAX_AGE_IN_LOG);
> > +	else
> > +		age_in_log = 0;
> 
> Instead of using ilog2() with a zero-check branch, could this be simplified
> by directly using fls()?
> 
> The fls() function safely returns 0 when the value is 0 and correctly
> calculates the 1-based log2 value for positive numbers, allowing this
> branch to be removed entirely while preserving the exact mathematical
> result.

We believe ilog2() is easier to read.

> 
> > +
> >  
> >  	/* If frequency is 0, higher age means it's colder */
> 
> This isn't a bug, but an extra blank line appears to be introduced here,
> creating two consecutive blank lines.

Good cactch.  As this is a quite minor issue, I will ask Andrew to fix this.

> 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20260426231619.107231-1-sj@kernel.org?part=1


Thanks,
SJ

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/4] mm/damon: add synchronous commit for commit_inputs
  2026-04-27  0:00   ` sashiko-bot
@ 2026-04-27 14:30     ` SeongJae Park
  0 siblings, 0 replies; 14+ messages in thread
From: SeongJae Park @ 2026-04-27 14:30 UTC (permalink / raw)
  To: sashiko-bot; +Cc: SeongJae Park, damon

On Mon, 27 Apr 2026 00:00:11 +0000 sashiko-bot@kernel.org wrote:

> Sashiko AI review found 1 potential issue(s):
> - [High] Writing to the `commit_inputs` sysfs parameter before the DAMON worker thread (`kdamond`) is started causes the writing task to hang indefinitely in an unkillable D-state.

I think this is wrong.

> --
> 
> commit 43a70e5ab295c21c0b94eddd32d886c9d0eba3fa
> Author: Liew Rui Yan <aethernet65535@gmail.com>
> 
> mm/damon: add synchronous commit for commit_inputs
> 
> This commit changes the commit_inputs_store() callback to use damon_call()
> to synchronously commit parameters in the kdamond thread's safe context.
> This ensures validation errors are returned immediately to userspace.
> 
> Link: https://lore.kernel.org/20260318153731.97470-1-aethernet65535@gmail.com
> 
> > diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c
> > index 554559d72976..641af42cc2d1 100644
> > --- a/mm/damon/lru_sort.c
> > +++ b/mm/damon/lru_sort.c
> 
> [ ... ]
> 
> > @@ -349,18 +348,51 @@ static int damon_lru_sort_apply_parameters(void)
> >  	return err;
> >  }
> >  
> > -static int damon_lru_sort_handle_commit_inputs(void)
> > +static int damon_lru_sort_commit_inputs_fn(void *arg)
> >  {
> > +	return damon_lru_sort_apply_parameters();
> > +}
> > +
> > +static int damon_lru_sort_commit_inputs_store(const char *val,
> > +					      const struct kernel_param *kp)
> > +{
> > +	bool commit_inputs_request;
> >  	int err;
> > +	struct damon_call_control control = {
> > +		.fn = damon_lru_sort_commit_inputs_fn,
> > +	};
> >  
> > -	if (!commit_inputs)
> > +	if (!val) {
> > +		commit_inputs_request = true;
> > +	} else {
> > +		err = kstrtobool(val, &commit_inputs_request);
> > +		if (err)
> > +			return err;
> > +	}
> >  
> > +	if (!commit_inputs_request)
> >  		return 0;
> >  
> > -	err = damon_lru_sort_apply_parameters();
> > -	commit_inputs = false;
> > -	return err;
> > +	/*
> > +	 * Skip damon_call() if ctx is not initialized to avoid
> > +	 * NULL pointer dereference.
> > +	 */
> > +	if (!ctx)
> > +		return -EINVAL;
> > +
> > +	err = damon_call(ctx, &control);
> 
> If the module has not yet been enabled (e.g., enabled=N) and the kdamond
> thread is not running, does this call to damon_call() block indefinitely?
> 
> Since ctx is allocated during initialization, the ctx pointer is not NULL.
> damon_call() then queues the control request and calls wait_for_completion().
> 
> Without the background thread running to process the queue and signal
> completion, it seems the sysfs writer task is placed into an unkillable
> D-state forever.

No.  ctx is initialized to NULL because it is static.  Once it is set,
kdamond_fn() is started.  If user stops kdamond by writing N to enabled,
ctx->call_controls_obsolete is set.  If user further writes Y to commit_inputs
for invoking damon_call(), it will return -ECANCELED due to
ctx->call_controls_obsolete.

> 
> The damon_call() documentation indicates it should only be called after
> damon_start() has succeeded, otherwise it could fall into an indefinite wait.

Yes, and that's excluded here since the module is not calling damon_call() for
NULL ctx.

> 
> > +
> > +	return err ? err : control.return_code;
> >  }
> 
> [ ... ]
> 
> > diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
> > index 86da14778658..4fc4a54b5e54 100644
> > --- a/mm/damon/reclaim.c
> > +++ b/mm/damon/reclaim.c
> 
> [ ... ]
> 
> > @@ -255,18 +254,51 @@ static int damon_reclaim_apply_parameters(void)
> >  	return err;
> >  }
> >  
> > -static int damon_reclaim_handle_commit_inputs(void)
> > +static int damon_reclaim_commit_inputs_fn(void *arg)
> >  {
> > +	return damon_reclaim_apply_parameters();
> > +}
> > +
> > +static int damon_reclaim_commit_inputs_store(const char *val,
> > +					     const struct kernel_param *kp)
> > +{
> > +	bool commit_inputs_request;
> >  	int err;
> > +	struct damon_call_control control = {
> > +		.fn = damon_reclaim_commit_inputs_fn,
> > +	};
> >  
> > -	if (!commit_inputs)
> > +	if (!val) {
> > +		commit_inputs_request = true;
> > +	} else {
> > +		err = kstrtobool(val, &commit_inputs_request);
> > +		if (err)
> > +			return err;
> > +	}
> > +
> > +	if (!commit_inputs_request)
> >  		return 0;
> >  
> > -	err = damon_reclaim_apply_parameters();
> > -	commit_inputs = false;
> > -	return err;
> > +	/*
> > +	 * Skip damon_call() if ctx is not initialized to avoid
> > +	 * NULL pointer dereference.
> > +	 */
> > +	if (!ctx)
> > +		return -EINVAL;
> > +
> > +	err = damon_call(ctx, &control);
> 
> Could this exhibit the same hang as in damon_lru_sort.c? If the worker
> thread has not been started, does writing to commit_inputs block forever?

Same to the above reply, no.

> 
> > +
> > +	return err ? err : control.return_code;
> >  }
> 
> -- 
> Sashiko AI review · https://sashiko.dev/#/patchset/20260426231619.107231-1-sj@kernel.org?part=3

Sent using hkml (https://github.com/sjp38/hackermail)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 1/4] mm/damon/ops-common: optimize damon_hot_score() using ilog2()
  2026-04-26 23:16 ` [PATCH v2 1/4] mm/damon/ops-common: optimize damon_hot_score() using ilog2() SeongJae Park
  2026-04-26 23:28   ` sashiko-bot
@ 2026-04-27 15:09   ` SeongJae Park
  1 sibling, 0 replies; 14+ messages in thread
From: SeongJae Park @ 2026-04-27 15:09 UTC (permalink / raw)
  To: SeongJae Park; +Cc: Andrew Morton, Liew Rui Yan, damon, linux-kernel, linux-mm

On Sun, 26 Apr 2026 16:16:14 -0700 SeongJae Park <sj@kernel.org> wrote:

> From: Liew Rui Yan <aethernet65535@gmail.com>
[...]
> --- a/mm/damon/ops-common.c
> +++ b/mm/damon/ops-common.c
> @@ -117,9 +117,12 @@ int damon_hot_score(struct damon_ctx *c, struct damon_region *r,
>  		damon_max_nr_accesses(&c->attrs);
>  
>  	age_in_sec = (unsigned long)r->age * c->attrs.aggr_interval / 1000000;
> -	for (age_in_log = 0; age_in_log < DAMON_MAX_AGE_IN_LOG && age_in_sec;
> -			age_in_log++, age_in_sec >>= 1)
> -		;
> +	if (age_in_sec)
> +		age_in_log = min_t(int, ilog2(age_in_sec) + 1,
> +				DAMON_MAX_AGE_IN_LOG);
> +	else
> +		age_in_log = 0;
> +
>  
>  	/* If frequency is 0, higher age means it's colder */
>  	if (freq_subscore == 0)

Sashiko found this patch is introducing two blank lines.  Andrew, I saw you
already added this to mm-new.  Could you please add below attaching fixup?  If
you prefer reposting this patch, please let me know.


Thanks,
SJ

[...]
=== >8 ===
From 1d97945a7c35463d3757df985cf3545bf9d5ed9c Mon Sep 17 00:00:00 2001
From: SeongJae Park <sj@kernel.org>
Date: Mon, 27 Apr 2026 08:05:09 -0700
Subject: [PATCH] mm/damon/ops-common: (fixup) remove unnecessary blank line

Two blank lines are unnecessary.

The issue was discovered [1] by Sashiko.

[1] https://lore.kernel.org/20260426232811.618BFC2BCAF@smtp.kernel.org

Signed-off-by: SeongJae Park <sj@kernel.org>
---
 mm/damon/ops-common.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/mm/damon/ops-common.c b/mm/damon/ops-common.c
index 3a0ddc3ac7196..b2ce817f33c53 100644
--- a/mm/damon/ops-common.c
+++ b/mm/damon/ops-common.c
@@ -123,7 +123,6 @@ int damon_hot_score(struct damon_ctx *c, struct damon_region *r,
 	else
 		age_in_log = 0;
 
-
 	/* If frequency is 0, higher age means it's colder */
 	if (freq_subscore == 0)
 		age_in_log *= -1;
-- 
2.47.3



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 2/4] Docs/admin-guide/mm/damon: fix 'parametrs' typo
  2026-04-26 23:16 ` [PATCH v2 2/4] Docs/admin-guide/mm/damon: fix 'parametrs' typo SeongJae Park
@ 2026-04-27 23:39   ` SeongJae Park
  2026-04-28  7:38     ` Vlastimil Babka (SUSE)
  0 siblings, 1 reply; 14+ messages in thread
From: SeongJae Park @ 2026-04-27 23:39 UTC (permalink / raw)
  To: SeongJae Park
  Cc: Andrew Morton, Cheng-Han Wu, Liam R. Howlett, David Hildenbrand,
	Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
	Shuah Khan, Suren Baghdasaryan, Vlastimil Babka, damon, linux-doc,
	linux-kernel, linux-mm

On Sun, 26 Apr 2026 16:16:15 -0700 SeongJae Park <sj@kernel.org> wrote:

> From: Cheng-Han Wu <hank20010209@gmail.com>
> 
> Fix the misspelling of "parametrs" as "parameters" in
> reclaim.rst and lru_sort.rst.
> 
> Signed-off-by: Cheng-Han Wu <hank20010209@gmail.com>

Oops, I forgot adding my Reviewed-by: tag.

Reviewed-by: SeongJae Park <sj@kernel.org>

Andrew, could you please add the above my Reviewed-by: tag?


Thanks,
SJ

[...]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 4/4] mm/damon: support MADV_COLLAPSE via DAMOS_COLLAPSE scheme action
  2026-04-26 23:16 ` [PATCH v2 4/4] mm/damon: support MADV_COLLAPSE via DAMOS_COLLAPSE scheme action SeongJae Park
@ 2026-04-27 23:41   ` SeongJae Park
  0 siblings, 0 replies; 14+ messages in thread
From: SeongJae Park @ 2026-04-27 23:41 UTC (permalink / raw)
  To: SeongJae Park
  Cc: Andrew Morton, Asier Gutierrez, Liam R. Howlett,
	David Hildenbrand, Jonathan Corbet, Lorenzo Stoakes, Michal Hocko,
	Mike Rapoport, Shuah Khan, Suren Baghdasaryan, Vlastimil Babka,
	damon, linux-doc, linux-kernel, linux-kselftest, linux-mm

On Sun, 26 Apr 2026 16:16:17 -0700 SeongJae Park <sj@kernel.org> wrote:

> From: Asier Gutierrez <gutierrez.asier@huawei-partners.com>
> 
> This patch set introces a new action:  DAMOS_COLLAPSE.
[...]
> 
> Signed-off-by: Asier Gutierrez <gutierrez.asier@huawei-partners.com>

I forgot adding my Reviewed-by: tag here.

Reviewed-by: SeongJae Park <sj@kernel.org>

Andrew, could you please add the above Reviewed-by: for me?


Thanks,
SJ

[...]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 2/4] Docs/admin-guide/mm/damon: fix 'parametrs' typo
  2026-04-27 23:39   ` SeongJae Park
@ 2026-04-28  7:38     ` Vlastimil Babka (SUSE)
  2026-04-28 14:21       ` SeongJae Park
  0 siblings, 1 reply; 14+ messages in thread
From: Vlastimil Babka (SUSE) @ 2026-04-28  7:38 UTC (permalink / raw)
  To: SeongJae Park
  Cc: Andrew Morton, Cheng-Han Wu, Liam R. Howlett, David Hildenbrand,
	Jonathan Corbet, Lorenzo Stoakes, Michal Hocko, Mike Rapoport,
	Shuah Khan, Suren Baghdasaryan, damon, linux-doc, linux-kernel,
	linux-mm

On 4/28/26 01:39, SeongJae Park wrote:
> On Sun, 26 Apr 2026 16:16:15 -0700 SeongJae Park <sj@kernel.org> wrote:
> 
>> From: Cheng-Han Wu <hank20010209@gmail.com>
>> 
>> Fix the misspelling of "parametrs" as "parameters" in
>> reclaim.rst and lru_sort.rst.
>> 
>> Signed-off-by: Cheng-Han Wu <hank20010209@gmail.com>
> 
> Oops, I forgot adding my Reviewed-by: tag.
> 
> Reviewed-by: SeongJae Park <sj@kernel.org>
> 
> Andrew, could you please add the above my Reviewed-by: tag?

Since you were sending that patch along in you series, there was (as it
must) already your S-o-b tag and that's stronger responsibility than a
Reviewed-by, so it's redundant to add it :)


> Thanks,
> SJ
> 
> [...]


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 2/4] Docs/admin-guide/mm/damon: fix 'parametrs' typo
  2026-04-28  7:38     ` Vlastimil Babka (SUSE)
@ 2026-04-28 14:21       ` SeongJae Park
  0 siblings, 0 replies; 14+ messages in thread
From: SeongJae Park @ 2026-04-28 14:21 UTC (permalink / raw)
  To: Vlastimil Babka (SUSE)
  Cc: SeongJae Park, Andrew Morton, Cheng-Han Wu, Liam R. Howlett,
	David Hildenbrand, Jonathan Corbet, Lorenzo Stoakes, Michal Hocko,
	Mike Rapoport, Shuah Khan, Suren Baghdasaryan, damon, linux-doc,
	linux-kernel, linux-mm

On Tue, 28 Apr 2026 09:38:02 +0200 "Vlastimil Babka (SUSE)" <vbabka@kernel.org> wrote:

> On 4/28/26 01:39, SeongJae Park wrote:
> > On Sun, 26 Apr 2026 16:16:15 -0700 SeongJae Park <sj@kernel.org> wrote:
> > 
> >> From: Cheng-Han Wu <hank20010209@gmail.com>
> >> 
> >> Fix the misspelling of "parametrs" as "parameters" in
> >> reclaim.rst and lru_sort.rst.
> >> 
> >> Signed-off-by: Cheng-Han Wu <hank20010209@gmail.com>
> > 
> > Oops, I forgot adding my Reviewed-by: tag.
> > 
> > Reviewed-by: SeongJae Park <sj@kernel.org>
> > 
> > Andrew, could you please add the above my Reviewed-by: tag?
> 
> Since you were sending that patch along in you series, there was (as it
> must) already your S-o-b tag and that's stronger responsibility than a
> Reviewed-by, so it's redundant to add it :)

You are right.  But, not having R-b tags that I provided on the review stage of
patches gone makes me feel odd and bit confusing.  Also I made a weird tool for
checking DAMON patch review status that doesn't understand this situation
well...  Maybe I should fix my brain and tool, but if it doesn't bother Andrew,
I'd still hope to have the R-b tags on the patches.


Thanks,
SJ

[...]

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-04-28 14:21 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-26 23:16 [PATCH v2 0/4] mm/damon: repost non-hotfix reviewed patches in damon/next tree SeongJae Park
2026-04-26 23:16 ` [PATCH v2 1/4] mm/damon/ops-common: optimize damon_hot_score() using ilog2() SeongJae Park
2026-04-26 23:28   ` sashiko-bot
2026-04-27 14:18     ` SeongJae Park
2026-04-27 15:09   ` SeongJae Park
2026-04-26 23:16 ` [PATCH v2 2/4] Docs/admin-guide/mm/damon: fix 'parametrs' typo SeongJae Park
2026-04-27 23:39   ` SeongJae Park
2026-04-28  7:38     ` Vlastimil Babka (SUSE)
2026-04-28 14:21       ` SeongJae Park
2026-04-26 23:16 ` [PATCH v2 3/4] mm/damon: add synchronous commit for commit_inputs SeongJae Park
2026-04-27  0:00   ` sashiko-bot
2026-04-27 14:30     ` SeongJae Park
2026-04-26 23:16 ` [PATCH v2 4/4] mm/damon: support MADV_COLLAPSE via DAMOS_COLLAPSE scheme action SeongJae Park
2026-04-27 23:41   ` SeongJae Park

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox