]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mm/damon: add synchronous commit for commit_inputs
authorLiew Rui Yan <aethernet65535@gmail.com>
Sun, 26 Apr 2026 23:16:16 +0000 (16:16 -0700)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 29 May 2026 04:04:55 +0000 (21:04 -0700)
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
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>
mm/damon/lru_sort.c
mm/damon/reclaim.c

index 8494040b1ee48feeaca4b16b627d6e28b1a39d91..7569e471160a0dde8560220727cc6c2d68fef91b 100644 (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 @@ out:
        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 = {
index fe7fce26cf6ce3a77b27d0bb2a195a5c065322ac..b330ff1695907404fde5764eaf73c2ca76f3a271 100644 (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 @@ out:
        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 = {