mm/damon: add synchronous commit for commit_inputs

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

Link: https://lore.kernel.org/20260426231619.107231-4-sj@kernel.org
Link: https://lore.kernel.org/20260318153731.97470-1-aethernet65535@gmail.com [1]
Signed-off-by: Liew Rui Yan <aethernet65535@gmail.com>
Reviewed-by: SeongJae Park <sj@kernel.org>
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: Asier Gutierrez <gutierrez.asier@huawei-partners.com>
Cc: Cheng-Han Wu <hank20010209@gmail.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Liew Rui Yan 2026-04-26 16:16:16 -07:00 committed by Andrew Morton
parent abdca14655
commit de3c60e1c8
2 changed files with 80 additions and 16 deletions

View File

@ -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)
{
int err;
return damon_lru_sort_apply_parameters();
}
if (!commit_inputs)
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_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 = {

View File

@ -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)
{
int err;
return damon_reclaim_apply_parameters();
}
if (!commit_inputs)
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 (!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 = {