public inbox for linux-mm@kvack.org
 help / color / mirror / Atom feed
* [PATCH v2] mm/damon: add synchronous commit for commit_inputs
@ 2026-03-29  7:54 Liew Rui Yan
  2026-03-29  9:56 ` Liew Rui Yan
  2026-03-29 15:12 ` SeongJae Park
  0 siblings, 2 replies; 4+ messages in thread
From: Liew Rui Yan @ 2026-03-29  7:54 UTC (permalink / raw)
  To: sj; +Cc: damon, linux-mm, Liew Rui Yan

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>
---
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 554559d72976..641af42cc2d1 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).
@@ -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 (!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;
@@ -374,7 +406,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 86da14778658..31cf3c45dc72 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.
@@ -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);
+
+	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;
@@ -276,7 +308,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.53.0



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

* Re: [PATCH v2] mm/damon: add synchronous commit for commit_inputs
  2026-03-29  7:54 [PATCH v2] mm/damon: add synchronous commit for commit_inputs Liew Rui Yan
@ 2026-03-29  9:56 ` Liew Rui Yan
  2026-03-29 14:53   ` SeongJae Park
  2026-03-29 15:12 ` SeongJae Park
  1 sibling, 1 reply; 4+ messages in thread
From: Liew Rui Yan @ 2026-03-29  9:56 UTC (permalink / raw)
  To: aethernet65535; +Cc: damon, linux-mm, sj

Forwarding Sashiko review for doing discussions via mails.

# review url: https://sashiko.dev/#/patchset/20260329075415.36775-1-aethernet65535@gmail.com
# start of sashiko.dev inline review
commit 2fe50c13aebc88839d89dd3cdd5944c18c25dc9b
Author: Liew Rui Yan <aethernet65535@gmail.com>

mm/damon: add synchronous commit for commit_inputs

This commit modifies the commit_inputs module parameter callback to
synchronously apply parameters using damon_call() instead of relying on
asynchronous validation in the kdamond thread.

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
--- a/mm/damon/lru_sort.c
+++ b/mm/damon/lru_sort.c
[ ... ]
> @@ -349,18 +348,51 @@ static int damon_lru_sort_apply_parameters(void)
[ ... ]
> +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;
> +	}
>  
> -	err = damon_lru_sort_apply_parameters();
> -	commit_inputs = false;
> -	return err;
> +	if (!commit_inputs_request)
>  		return 0;
>  
> +	/*
> +	* Skip damon_call() if ctx is not initialized to avoid
> +	* NULL pointer dereference.
> +	*/
> +	if (!ctx)
> +		return -EINVAL;

Does this break module loading if commit_inputs=Y is provided as a boot
parameter or via a modprobe configuration?

During module initialization, parse_args() executes module parameter
callbacks before the module's init function runs.

Since ctx is initialized in the module's init function, won't ctx be NULL
when this callback fires, causing an -EINVAL return that aborts the
entire module load?

> +
> +	err = damon_call(ctx, &control);

Could this synchronous call break backward compatibility for userspace
scripts?

Previously, writing Y to commit_inputs while the monitor was disabled
(enabled=N) would silently succeed and apply the parameters on the next
start.

If the kdamond thread is not running, won't damon_call() detect
!damon_is_running(ctx) and return -EINVAL, causing writes to fail when
the monitor is off?

Since this is a module parameter callback, the global param_lock mutex is
held during its execution. Does calling damon_call() here cause system-wide
latency spikes?

damon_call() blocks on wait_for_completion() waiting for the kdamond thread,
which only checks its call list once per sample interval.

Will this stall all other tasks attempting to read or write built-in module
parameters for up to the duration of the DAMON sampling interval?

Is there a race condition here with the kdamond thread termination that
could result in a permanent deadlock?

When kdamond_fn() exits, it flushes pending controls and then sets
ctx->kdamond to NULL.

If a concurrent sysfs write triggers damon_call() after the controls are
flushed but before ctx->kdamond is cleared, damon_is_running(ctx) will
return true.

Will damon_call() block indefinitely on wait_for_completion() because the
thread is exiting and will never signal it, leaving the sysfs writer
permanently stuck in D state while holding the system-wide param_lock?

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

[ ... ]
diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
--- a/mm/damon/reclaim.c
+++ b/mm/damon/reclaim.c
[ ... ]
> +static int damon_reclaim_commit_inputs_store(const char *val,
> +					    const struct kernel_param *kp)
> +{
[ ... ]
> +	/*
> +	* 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;
>  }

Are these same regressions present here in damon_reclaim_commit_inputs_store()
as well?


# end of sashiko.dev inline review
# review url: https://sashiko.dev/#/patchset/20260329075415.36775-1-aethernet65535@gmail.com
#
# hkml [1] generated a draft of this mail.  It can be regenerated
# using below command:
#
#     hkml patch sashiko_dev --for_forwarding \
#             20260329075415.36775-1-aethernet65535@gmail.com
#
# [1] https://github.com/sjp38/hackermail


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

* Re: [PATCH v2] mm/damon: add synchronous commit for commit_inputs
  2026-03-29  9:56 ` Liew Rui Yan
@ 2026-03-29 14:53   ` SeongJae Park
  0 siblings, 0 replies; 4+ messages in thread
From: SeongJae Park @ 2026-03-29 14:53 UTC (permalink / raw)
  To: Liew Rui Yan; +Cc: SeongJae Park, damon, linux-mm

On Sun, 29 Mar 2026 17:56:02 +0800 Liew Rui Yan <aethernet65535@gmail.com> wrote:

> Forwarding Sashiko review for doing discussions via mails.

To my understanding, all the comments are same to those for v1, which we
concluded to be no real issues.  Please let me know if I'm missing something.


Thanks,
SJ

[...]


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

* Re: [PATCH v2] mm/damon: add synchronous commit for commit_inputs
  2026-03-29  7:54 [PATCH v2] mm/damon: add synchronous commit for commit_inputs Liew Rui Yan
  2026-03-29  9:56 ` Liew Rui Yan
@ 2026-03-29 15:12 ` SeongJae Park
  1 sibling, 0 replies; 4+ messages in thread
From: SeongJae Park @ 2026-03-29 15:12 UTC (permalink / raw)
  To: Liew Rui Yan; +Cc: SeongJae Park, damon, linux-mm

On Sun, 29 Mar 2026 15:54:15 +0800 Liew Rui Yan <aethernet65535@gmail.com> wrote:

> 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>

Note that mm.git is nearly closed for non-hotfixes until 7.1-rc1 release.  I
will add this to my tree now, and resubmit for mm.git merge after 7.1-rc1
release.


Thanks,
SJ

[...]


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

end of thread, other threads:[~2026-03-29 15:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-29  7:54 [PATCH v2] mm/damon: add synchronous commit for commit_inputs Liew Rui Yan
2026-03-29  9:56 ` Liew Rui Yan
2026-03-29 14:53   ` SeongJae Park
2026-03-29 15:12 ` SeongJae Park

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