FAILED: patch "[PATCH] mm/damon/reclaim: detect and use fresh enabled and" failed to apply to 6.12-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 64a140afa5ed1c6f5ba6d451512cbdbbab1ba339
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026051255-roundup-crushing-4344@gregkh' --subject-prefix 'PATCH 6.12.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 64a140afa5ed1c6f5ba6d451512cbdbbab1ba339 Mon Sep 17 00:00:00 2001
From: SeongJae Park <[email protected]>
Date: Sun, 19 Apr 2026 09:10:00 -0700
Subject: [PATCH] mm/damon/reclaim: detect and use fresh enabled and
kdamond_pid values
Patch series "mm/damon/modules: detect and use fresh status", v3.
DAMON modules including DAMON_RECLAIM, DAMON_LRU_SORT and DAMON_STAT commonly expose the kdamond running status via their parameters. Under certain scenarios including wrong user inputs and memory allocation failures, those parameter values can be stale. It can confuse users. For DAMON_RECLAIM and DAMON_LRU_SORT, it even makes the kdamond unable to be restarted before the system reboot.
The problem comes from the fact that there are multiple events for the status changes and it is difficult to follow up all the scenarios. Fix the issue by detecting and using the status on demand, instead of using a cached status that is difficult to be updated.
Patches 1-3 fix the bugs in DAMON_RECLAIM, DAMON_LRU_SORT and DAMON_STAT in the order.
This patch (of 3):
DAMON_RECLAIM updates 'enabled' and 'kdamond_pid' parameter values, which represents the running status of its kdamond, when the user explicitly requests start/stop of the kdamond. The kdamond can, however, be stopped in events other than the explicit user request in the following three events.
1. ctx->regions_score_histogram allocation failure at beginning of the execution,
2. damon_commit_ctx() failure due to invalid user input, and
3. damon_commit_ctx() failure due to its internal allocation failures.
Hence, if the kdamond is stopped by the above three events, the values of the status parameters can be stale. Users could show the stale values and be confused. This is already bad, but the real consequence is worse. DAMON_RECLAIM avoids unnecessary damon_start() and damon_stop() calls based on the 'enabled' parameter value. And the update of 'enabled' parameter value depends on the damon_start() and damon_stop() call results. Hence, once the kdamond has stopped by the unintentional events, the user cannot restart the kdamond before the system reboot. For example, the issue can be reproduced via below steps.
# cd /sys/module/damon_reclaim/parameters
#
# # start DAMON_RECLAIM
# echo Y > enabled
# ps -ef | grep kdamond
root 806 2 0 17:53 ? 00:00:00 [kdamond.0]
root 808 803 0 17:53 pts/4 00:00:00 grep kdamond
#
# # commit wrong input to stop kdamond withou explicit stop request
# echo 3 > addr_unit
# echo Y > commit_inputs
bash: echo: write error: Invalid argument
#
# # confirm kdamond is stopped
# ps -ef | grep kdamond
root 811 803 0 17:53 pts/4 00:00:00 grep kdamond
#
# # users casn now show stable status
# cat enabled
Y
# cat kdamond_pid
806
#
# # even after fixing the wrong parameter,
# # kdamond cannot be restarted.
# echo 1 > addr_unit
# echo Y > enabled
# ps -ef | grep kdamond
root 815 803 0 17:54 pts/4 00:00:00 grep kdamondThe problem will only rarely happen in real and common setups for the following reasons. The allocation failures are unlikely in such setups since those allocations are arguably too small to fail. Also sane users on real production environments may not commit wrong input parameters. But once it happens, the consequence is quite bad. And the bug is a bug.
The issue stems from the fact that there are multiple events that can change the status, and following all the events is challenging. Dynamically detect and use the fresh status for the parameters when those are requested.
mm/damon/reclaim.c +55 -30
@@ -144,15 +144,6 @@ static unsigned long addr_unit __read_mostly = 1;static bool skip_anon__read_mostly ;module_param (skip_anon, bool,0600 ); -/* -* PID of the DAMON thread -* -* If DAMON_RECLAIM is enabled, this becomes the PID of the worker thread. -* Else, -1. -*/ -static int kdamond_pid__read_mostly =-1 ; -module_param (kdamond_pid, int,0400 ); -static struct damos_stat damon_reclaim_stat;DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS (damon_reclaim_stat, reclaim_tried_regions, reclaimed_regions, quota_exceeds);
@@ -288,12 +279,8 @@ static int damon_reclaim_turn(bool on) {int err; -if (!on) { - err =damon_stop (&ctx,1 ); -if (!err) - kdamond_pid =-1 ; -return err; - } +if (!on) +return damon_stop (&ctx,1 ); err =damon_reclaim_apply_parameters ();if (err)
@@ -302,9 +289,6 @@ static int damon_reclaim_turn(bool on) err =damon_start (&ctx,1 , true);if (err)return err; - kdamond_pid =damon_kdamond_pid (ctx); -if (kdamond_pid <0 ) -return kdamond_pid;return damon_call (ctx, &call_control); }
@@ -332,42 +316,83 @@ module_param_cb(addr_unit, &addr_unit_param_ops, &addr_unit, 0600);MODULE_PARM_DESC (addr_unit,"Scale factor for DAMON_RECLAIM to ops address conversion (default: 1)" ); +static bool damon_reclaim_enabled (void ) +{ +if (!ctx) +return false; +return damon_is_running (ctx); +} +static int damon_reclaim_enabled_store (const char *val,const struct kernel_param *kp) { -bool is_enabled = enabled; -bool enable;int err; - err =kstrtobool (val, &enable); + err =kstrtobool (val, &enabled);if (err)return err; -if (is_enabled == enable) +if (damon_reclaim_enabled () == enabled)return 0 ;/* Called before init function. The function will handle this. */ if (!damon_initialized ()) - goto set_param_out; +return 0 ; - err =damon_reclaim_turn (enable); -if (err) -return err; +return damon_reclaim_turn (enabled); +} -set_param_out: - enabled = enable; -return err; +static int damon_reclaim_enabled_load (char *buffer, +const struct kernel_param *kp) +{ +return sprintf (buffer,"%c\n" ,damon_reclaim_enabled () ?'Y' :'N' ); }static const struct kernel_param_ops enabled_param_ops = { .set = damon_reclaim_enabled_store, - .get = param_get_bool, + .get = damon_reclaim_enabled_load, };module_param_cb (enabled, &enabled_param_ops, &enabled,0600 );MODULE_PARM_DESC (enabled,"Enable or disable DAMON_RECLAIM (default: disabled)" ); +static int damon_reclaim_kdamond_pid_store (const char *val, +const struct kernel_param *kp) +{ +/* +* kdamond_pid is read-only, but kernel command line could write it. +* Do nothing here. +*/ +return 0 ; +} + +static int damon_reclaim_kdamond_pid_load (char *buffer, +const struct kernel_param *kp) +{ +int kdamond_pid =-1 ; + +if (ctx) { + kdamond_pid =damon_kdamond_pid (ctx); +if (kdamond_pid <0 ) + kdamond_pid =-1 ; + } +return sprintf (buffer,"%d\n" , kdamond_pid); +} + +static const struct kernel_param_ops kdamond_pid_param_ops = { + .set = damon_reclaim_kdamond_pid_store, + .get = damon_reclaim_kdamond_pid_load, +}; + +/* +* PID of the DAMON thread +* +* If DAMON_RECLAIM is enabled, this becomes the PID of the worker thread. +* Else, -1. +*/ +module_param_cb (kdamond_pid, &kdamond_pid_param_ops,NULL ,0400 ); +static int __init damon_reclaim_init (void ) {int err;
SeongJae Park
maintainerPATCH 1/1 mm/damon/lru_sort: detect and use fresh enabled and kdamond_pid values
DAMON_LRU_SORT updates 'enabled' and 'kdamond_pid' parameter values, which represents the running status of its kdamond, when the user explicitly requests start/stop of the kdamond. The kdamond can, however, be stopped in events other than the explicit user request in the following three events.
1. ctx->regions_score_histogram allocation failure at beginning of the execution,
2. damon_commit_ctx() failure due to invalid user input, and
3. damon_commit_ctx() failure due to its internal allocation failures.
Hence, if the kdamond is stopped by the above three events, the values of the status parameters can be stale. Users could show the stale values and be confused. This is already bad, but the real consequence is worse. DAMON_LRU_SORT avoids unnecessary damon_start() and damon_stop() calls based on the 'enabled' parameter value. And the update of 'enabled' parameter value depends on the damon_start() and damon_stop() call results. Hence, once the kdamond has stopped by the unintentional events, the user cannot restart the kdamond before the system reboot. For example, the issue can be reproduced via below steps.
# cd /sys/module/damon_lru_sort/parameters
#
# # start DAMON_LRU_SORT
# echo Y > enabled
# ps -ef | grep kdamond
root 806 2 0 17:53 ? 00:00:00 [kdamond.0]
root 808 803 0 17:53 pts/4 00:00:00 grep kdamond
#
# # commit wrong input to stop kdamond withou explicit stop request
# echo 3 > addr_unit
# echo Y > commit_inputs
bash: echo: write error: Invalid argument
#
# # confirm kdamond is stopped
# ps -ef | grep kdamond
root 811 803 0 17:53 pts/4 00:00:00 grep kdamond
#
# # users casn now show stable status
# cat enabled
Y
# cat kdamond_pid
806
#
# # even after fixing the wrong parameter,
# # kdamond cannot be restarted.
# echo 1 > addr_unit
# echo Y > enabled
# ps -ef | grep kdamond
root 815 803 0 17:54 pts/4 00:00:00 grep kdamondThe problem will only rarely happen in real and common setups for the following reasons. The allocation failures are unlikely in such setups since those allocations are arguably too small to fail. Also sane users on real production environments may not commit wrong input parameters. But once it happens, the consequence is quite bad. And the bug is a bug.
The issue stems from the fact that there are multiple events that can change the status, and following all the events is challenging. Dynamically detect and use the fresh status for the parameters when those are requested.
(port parts of 42b7491af14c ("mm/damon/core: introduce damon_call()") and d2b5be741a50 ("mm/damon/sysfs: use DAMON core API damon_is_running()") for damon_is_running() dependency)
Cc: Liew Rui Yan <[email protected]>
Cc: Andrew Morton <[email protected]>
---
This depends on other two backported patches [1,2]. Please apply this after those.
[1] https://lore.kernel.org/[email protected]
[2] https://lore.kernel.org/[email protected]
include/linux/damon.h | 1 + mm/damon/core.c | 16 ++++++++ mm/damon/lru_sort.c | 88 +++++++++++++++++++++++++++---------------- 3 files changed, 73 insertions(+), 32 deletions(-)
include/linux/damon.h +1 -0
@@ -778,6 +778,7 @@ static inline unsigned int damon_max_nr_accesses(const struct damon_attrs *attrsint damon_start (struct damon_ctx **ctxs,int nr_ctxs,bool exclusive);int damon_stop (struct damon_ctx **ctxs,int nr_ctxs); +bool damon_is_running (struct damon_ctx *ctx);int damon_kdamond_pid (struct damon_ctx *ctx); int damon_set_region_biggest_system_ram_default(struct damon_target *t,
mm/damon/core.c +16 -0
@@ -1163,6 +1163,22 @@ int damon_stop(struct damon_ctx **ctxs, int nr_ctxs)return err; } +/** +* damon_is_running() - Returns if a given DAMON context is running. +* @ctx: The DAMON context to see if running. +* +* Return: true if @ctx is running, false otherwise. +*/ +bool damon_is_running (struct damon_ctx *ctx) +{ +bool running; + +mutex_lock (&ctx->kdamond_lock); + running = ctx->kdamond !=NULL ; +mutex_unlock (&ctx->kdamond_lock); +return running; +} +/** * damon_kdamond_pid() - Return pid of a given DAMON context's worker thread. * @ctx: The DAMON context of the question.
mm/damon/lru_sort.c +56 -32
131 lines not on this page · raw message
Signature · 1 line
2.47.3
SeongJae Park
maintainerRe: [PATCH 6.12.y] mm/damon/lru_sort: detect and use fresh enabled and kdamond_pid values
On Tue, 12 May 2026 21:46:58 -0700 SeongJae Park <[email protected]> wrote:
This is a wrong patch that mistakenly sent. Please ignore.
Thanks,
SJ
[...]
SeongJae Park
maintainerPATCH 1/1 mm/damon/reclaim: detect and use fresh enabled and kdamond_pid values
In reply to [email protected]Patch series "mm/damon/modules: detect and use fresh status", v3.
DAMON modules including DAMON_RECLAIM, DAMON_LRU_SORT and DAMON_STAT commonly expose the kdamond running status via their parameters. Under certain scenarios including wrong user inputs and memory allocation failures, those parameter values can be stale. It can confuse users. For DAMON_RECLAIM and DAMON_LRU_SORT, it even makes the kdamond unable to be restarted before the system reboot.
The problem comes from the fact that there are multiple events for the status changes and it is difficult to follow up all the scenarios. Fix the issue by detecting and using the status on demand, instead of using a cached status that is difficult to be updated.
Patches 1-3 fix the bugs in DAMON_RECLAIM, DAMON_LRU_SORT and DAMON_STAT in the order.
This patch (of 3):
DAMON_RECLAIM updates 'enabled' and 'kdamond_pid' parameter values, which represents the running status of its kdamond, when the user explicitly requests start/stop of the kdamond. The kdamond can, however, be stopped in events other than the explicit user request in the following three events.
1. ctx->regions_score_histogram allocation failure at beginning of the execution,
2. damon_commit_ctx() failure due to invalid user input, and
3. damon_commit_ctx() failure due to its internal allocation failures.
Hence, if the kdamond is stopped by the above three events, the values of the status parameters can be stale. Users could show the stale values and be confused. This is already bad, but the real consequence is worse. DAMON_RECLAIM avoids unnecessary damon_start() and damon_stop() calls based on the 'enabled' parameter value. And the update of 'enabled' parameter value depends on the damon_start() and damon_stop() call results. Hence, once the kdamond has stopped by the unintentional events, the user cannot restart the kdamond before the system reboot. For example, the issue can be reproduced via below steps.
# cd /sys/module/damon_reclaim/parameters
#
# # start DAMON_RECLAIM
# echo Y > enabled
# ps -ef | grep kdamond
root 806 2 0 17:53 ? 00:00:00 [kdamond.0]
root 808 803 0 17:53 pts/4 00:00:00 grep kdamond
#
# # commit wrong input to stop kdamond withou explicit stop request
# echo 3 > addr_unit
# echo Y > commit_inputs
bash: echo: write error: Invalid argument
#
# # confirm kdamond is stopped
# ps -ef | grep kdamond
root 811 803 0 17:53 pts/4 00:00:00 grep kdamond
#
# # users casn now show stable status
# cat enabled
Y
# cat kdamond_pid
806
#
# # even after fixing the wrong parameter,
# # kdamond cannot be restarted.
# echo 1 > addr_unit
# echo Y > enabled
# ps -ef | grep kdamond
root 815 803 0 17:54 pts/4 00:00:00 grep kdamondThe problem will only rarely happen in real and common setups for the following reasons. The allocation failures are unlikely in such setups since those allocations are arguably too small to fail. Also sane users on real production environments may not commit wrong input parameters. But once it happens, the consequence is quite bad. And the bug is a bug.
The issue stems from the fact that there are multiple events that can change the status, and following all the events is challenging. Dynamically detect and use the fresh status for the parameters when those are requested.
---
This depends on other two backported patches [1,2]. Please apply this after those.
[1] https://lore.kernel.org/[email protected]
[2] https://lore.kernel.org/[email protected]
mm/damon/reclaim.c | 88 +++++++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 32 deletions(-)
mm/damon/reclaim.c +56 -32
@@ -137,15 +137,6 @@ module_param(monitor_region_end, ulong, 0600);static bool skip_anon__read_mostly ;module_param (skip_anon, bool,0600 ); -/* -* PID of the DAMON thread -* -* If DAMON_RECLAIM is enabled, this becomes the PID of the worker thread. -* Else, -1. -*/ -static int kdamond_pid__read_mostly =-1 ; -module_param (kdamond_pid, int,0400 ); -static struct damos_stat damon_reclaim_stat;DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS (damon_reclaim_stat, reclaim_tried_regions, reclaimed_regions, quota_exceeds);
@@ -247,60 +238,93 @@ static int damon_reclaim_turn(bool on) {int err; -if (!on) { - err =damon_stop (&ctx,1 ); -if (!err) - kdamond_pid =-1 ; -return err; - } +if (!on) +return damon_stop (&ctx,1 ); err =damon_reclaim_apply_parameters ();if (err)return err; - err =damon_start (&ctx,1 , true); -if (err) -return err; - kdamond_pid = ctx->kdamond->pid; -return 0 ; +return damon_start (&ctx,1 , true); +} + +static bool damon_reclaim_enabled (void ) +{ +if (!ctx) +return false; +return damon_is_running (ctx); }static int damon_reclaim_enabled_store (const char *val,const struct kernel_param *kp) { -bool is_enabled = enabled; -bool enable;int err; - err =kstrtobool (val, &enable); + err =kstrtobool (val, &enabled);if (err)return err; -if (is_enabled == enable) +if (damon_reclaim_enabled () == enabled)return 0 ;/* Called before init function. The function will handle this. */ if (!ctx) - goto set_param_out; +return 0 ; - err =damon_reclaim_turn (enable); -if (err) -return err; +return damon_reclaim_turn (enabled); +} -set_param_out: - enabled = enable; -return err; +static int damon_reclaim_enabled_load (char *buffer, +const struct kernel_param *kp) +{ +return sprintf (buffer,"%c\n" ,damon_reclaim_enabled () ?'Y' :'N' ); }static const struct kernel_param_ops enabled_param_ops = { .set = damon_reclaim_enabled_store, - .get = param_get_bool, + .get = damon_reclaim_enabled_load, };module_param_cb (enabled, &enabled_param_ops, &enabled,0600 );MODULE_PARM_DESC (enabled,"Enable or disable DAMON_RECLAIM (default: disabled)" ); +static int damon_reclaim_kdamond_pid_store (const char *val, +const struct kernel_param *kp) +{ +/* +* kdamond_pid is read-only, but kernel command line could write it. +* Do nothing here. +*/ +return 0 ; +} + +static int damon_reclaim_kdamond_pid_load (char *buffer, +const struct kernel_param *kp) +{ +int kdamond_pid =-1 ; + +if (ctx) { + kdamond_pid =damon_kdamond_pid (ctx); +if (kdamond_pid <0 ) + kdamond_pid =-1 ; + } +return sprintf (buffer,"%d\n" , kdamond_pid); +} + +static const struct kernel_param_ops kdamond_pid_param_ops = { + .set = damon_reclaim_kdamond_pid_store, + .get = damon_reclaim_kdamond_pid_load, +}; + +/* +* PID of the DAMON thread +* +* If DAMON_RECLAIM is enabled, this becomes the PID of the worker thread. +* Else, -1. +*/ +module_param_cb (kdamond_pid, &kdamond_pid_param_ops,NULL ,0400 ); +static int damon_reclaim_handle_commit_inputs (void ) {int err;
Signature · 1 line
2.47.3
[email protected]
AI reviewRe: [PATCH 6.12.y] mm/damon/reclaim: detect and use fresh enabled and kdamond_pid values
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: - [High] A race condition during module initialization allows userspace to trigger a use-after-free kernel…
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] A race condition during module initialization allows userspace to trigger a use-after-free kernel panic via the enabled sysfs parameter.
- [High] damon_reclaim_apply_parameters() incorrectly applies schemes and attributes to the global ctx instead of param_ctx, causing them to be destroyed by damon_commit_ctx().
- [Low] The patch introduces calls to undeclared functions damon_is_running() and damon_kdamond_pid(), causing a build failure.
--
commit e5b3e77c68d72139966a3f423a04c39c6310ef66
Author: SeongJae Park <[email protected]>
mm/damon/reclaim: detect and use fresh enabled and kdamond_pid values
This commit updates DAMON_RECLAIM to dynamically detect and use the fresh running status and process id for the enabled and kdamond_pid parameters. It avoids caching the status, which can become stale when the thread stops unexpectedly.
Quoted 8 lines
mm/damon/reclaim.c +0
-0@@ -247,60 +238,93 @@ static int damon_reclaim_turn(bool on) {int err;
mm/damon/reclaim.c static int damon_reclaim_turn(bool on) · line 244
Quoted 10 lines
mm/damon/reclaim.c +2
-6-if (!on) { - err =damon_stop (&ctx,1 ); -if (!err) - kdamond_pid =-1 ; -return err; - } +if (!on) +return damon_stop (&ctx,1 ); err =damon_reclaim_apply_parameters ();
Does damon_reclaim_apply_parameters() correctly configure the scheme?
Looking at its implementation in mm/damon/reclaim.c:
err = damon_modules_new_paddr_ctx_target(¶m_ctx, ¶m_target);
...
err = damon_set_attrs(ctx, &damon_reclaim_mon_attrs);
...
scheme = damon_reclaim_new_scheme();
...
damon_set_schemes(ctx, &scheme, 1);
...
err = damon_commit_ctx(ctx, param_ctx);It seems damon_set_attrs() and damon_set_schemes() are called on the global ctx rather than param_ctx.
Since param_ctx has zero schemes when damon_commit_ctx(ctx, param_ctx) is called, will this aggressively destroy the schemes that were just added to ctx, leaving DAMON_RECLAIM non-functional?
Quoted 7 lines
mm/damon/reclaim.c +0
-4if (err)return err; - err =damon_start (&ctx,1 , true); -if (err) -return err; - kdamond_pid = ctx->kdamond->pid;
mm/damon/reclaim.c static int damon_reclaim_turn(bool on) · line 275
Quoted 10 lines
mm/damon/reclaim.c +9
-1-return 0 ; +return damon_start (&ctx,1 , true); +} + +static bool damon_reclaim_enabled (void ) +{ +if (!ctx) +return false; +return damon_is_running (ctx); +}
Does this code compile?
It appears that damon_is_running() was introduced in a newer kernel version. Because this is a cherry-pick, are we missing a prerequisite refactoring patch that provides this function?
Quoted 17 lines
mm/damon/reclaim.c +2
-4static int damon_reclaim_enabled_store (const char *val,const struct kernel_param *kp) { -bool is_enabled = enabled; -bool enable;int err; - err =kstrtobool (val, &enable); + err =kstrtobool (val, &enabled);if (err)return err; -if (is_enabled == enable) +if (damon_reclaim_enabled () == enabled)return 0 ;
mm/damon/reclaim.c static int damon_reclaim_turn(bool on) · line 275
Quoted 10 lines
mm/damon/reclaim.c +3
-4/* Called before init function. The function will handle this. */ if (!ctx) - goto set_param_out; +return 0 ; - err =damon_reclaim_turn (enable); -if (err) -return err; +return damon_reclaim_turn (enabled); +}
Is there a race condition between module initialization and this sysfs parameter store?
The sysfs file for enabled is exposed to userspace by load_module() before damon_reclaim_init() completes. damon_reclaim_init() allocates ctx early.
If userspace writes to enabled after ctx is allocated but before initialization finishes, this function will start the kdamond thread.
When damon_reclaim_init() resumes, it will see enabled is true and attempt to start the thread again, resulting in -EBUSY.
If initialization fails and the module memory is freed, could the already-running kdamond thread execute unmapped memory and cause a use-after-free regression?
[ ... ]
mm/damon/reclaim.c static int damon_reclaim_turn(bool on) · line 313
Quoted 12 lines
mm/damon/reclaim.c +12
-0+static int damon_reclaim_kdamond_pid_load (char *buffer, +const struct kernel_param *kp) +{ +int kdamond_pid =-1 ; + +if (ctx) { + kdamond_pid =damon_kdamond_pid (ctx); +if (kdamond_pid <0 ) + kdamond_pid =-1 ; + } +return sprintf (buffer,"%d\n" , kdamond_pid); +}
Likewise, is damon_kdamond_pid() available in this kernel tree, or will this result in an implicit function declaration error?
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
SeongJae Park
maintainerRe: [PATCH 6.12.y] mm/damon/reclaim: detect and use fresh enabled and kdamond_pid values
Quoted 4 lines · On Thu, 14 May 2026 02:18:36 +0000 [email protected] wrote:
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] A race condition during module initialization allows userspace to trigger a use-after-free kernel panic via theenabledsysfs parameter.
- [High]damon_reclaim_apply_parameters()incorrectly applies schemes and attributes to the globalctxinstead ofparam_ctx, causing them to be destroyed bydamon_commit_ctx().
- [Low] The patch introduces calls to undeclared functionsdamon_is_running()anddamon_kdamond_pid(), causing a build failure.
TL; DR: Sashiko found upstream commit fed48693bdfe ("mm/damon/reclaim: use parameter context correctly") is required for 6.12.y regardless of this patch, but not yet picked by stable kernel maintainers. Stable kernel maintainers, could you please add the patch to 6.12.y?
Other Sashiko-found issues are no issue in my opinion.
Please read below if you are interested in more details.
Quoted 48 lines
--
commit
e5b3e77c68d72139966a3f423a04c39c6310ef66
Author: SeongJae Park <[email protected]>
mm/damon/reclaim: detect and use fresh enabled andkdamond_pidvaluesThis commit updates
DAMON_RECLAIMto dynamically detect and use the fresh running status and process id for the enabled andkdamond_pidparameters. It avoids caching the status, which can become stale when the thread stops unexpectedly.Quoted 8 lines
mm/damon/reclaim.c +0
-0@@ -247,60 +238,93 @@ static int damon_reclaim_turn(bool on) {int err;mm/damon/reclaim.c static int damon_reclaim_turn(bool on) · line 244
Quoted 10 lines
mm/damon/reclaim.c +2
-6-if (!on) { - err =damon_stop (&ctx,1 ); -if (!err) - kdamond_pid =-1 ; -return err; - } +if (!on) +return damon_stop (&ctx,1 ); err =damon_reclaim_apply_parameters ();Does
damon_reclaim_apply_parameters()correctly configure the scheme?Looking at its implementation in
mm/damon/reclaim.c:err = damon_modules_new_paddr_ctx_target(¶m_ctx, ¶m_target); ... err = damon_set_attrs(ctx, &damon_reclaim_mon_attrs); ... scheme = damon_reclaim_new_scheme(); ... damon_set_schemes(ctx, &scheme, 1); ... err = damon_commit_ctx(ctx, param_ctx);
Quoted 6 lines
It seems
damon_set_attrs()anddamon_set_schemes()are called on the global ctx rather thanparam_ctx.Since
param_ctxhas zero schemes whendamon_commit_ctx(ctx, param_ctx)is called, will this aggressively destroy the schemes that were just added to ctx, leavingDAMON_RECLAIMnon-functional?
The bug is introduced by commit 11ddcfc257a3 ("mm/damon/reclaim: use damon_commit_ctx()"), which was merged into the mainline by 6.11. So the broken commit is in 6.12.y.
The fix was made by commit fed48693bdfe ("mm/damon/reclaim: use parameter context correctly") which was merged into the mainline by 6.17. And the fix commit has correct Fixes: tag, but somehow didn't picked by stable kernel maintainers.
Stable kernel maintainers, could you please backport the fix commit to 6.12.y? Let me know if any different action from my side is needed.
Quoted 21 lines
Quoted 8 lines
mm/damon/reclaim.c +0
-4if (err)return err; - err =damon_start (&ctx,1 , true); -if (err) -return err; - kdamond_pid = ctx->kdamond->pid;mm/damon/reclaim.c static int damon_reclaim_turn(bool on) · line 275
Quoted 10 lines
mm/damon/reclaim.c +9
-1-return 0 ; +return damon_start (&ctx,1 , true); +} + +static bool damon_reclaim_enabled (void ) +{ +if (!ctx) +return false; +return damon_is_running (ctx); +}Does this code compile?
Quoted 3 lines
It appears that
damon_is_running()was introduced in a newer kernel version. Because this is a cherry-pick, are we missing a prerequisite refactoring patch that provides this function?
I informed this and where the dependent patches can be found, on the commentary area of the patch.
Quoted 38 lines
Quoted 18 lines
mm/damon/reclaim.c +2
-4static int damon_reclaim_enabled_store (const char *val,const struct kernel_param *kp) { -bool is_enabled = enabled; -bool enable;int err; - err =kstrtobool (val, &enable); + err =kstrtobool (val, &enabled);if (err)return err; -if (is_enabled == enable) +if (damon_reclaim_enabled () == enabled)return 0 ;mm/damon/reclaim.c static int damon_reclaim_turn(bool on) · line 275
Quoted 10 lines
mm/damon/reclaim.c +3
-4/* Called before init function. The function will handle this. */ if (!ctx) - goto set_param_out; +return 0 ; - err =damon_reclaim_turn (enable); -if (err) -return err; +return damon_reclaim_turn (enabled); +}Is there a race condition between module initialization and this sysfs parameter store?
The sysfs file for enabled is exposed to userspace by
load_module()beforedamon_reclaim_init()completes.damon_reclaim_init()allocates ctx early.If userspace writes to enabled after ctx is allocated but before initialization finishes, this function will start the kdamond thread.
Quoted 6 lines
When
damon_reclaim_init()resumes, it will see enabled is true and attempt to start the thread again, resulting in-EBUSY.If initialization fails and the module memory is freed, could the already-running kdamond thread execute unmapped memory and cause a use-after-free regression?
DAMON_RECLAIM is a static module. Userspace cannot write sysfs files before the static module initializations are finished to my understanding. So this kind of race cannot happen. Please let me know if I'm wrong.
Quoted 18 lines
[ ... ]
mm/damon/reclaim.c static int damon_reclaim_turn(bool on) · line 313
Quoted 12 lines
mm/damon/reclaim.c +12
-0+static int damon_reclaim_kdamond_pid_load (char *buffer, +const struct kernel_param *kp) +{ +int kdamond_pid =-1 ; + +if (ctx) { + kdamond_pid =damon_kdamond_pid (ctx); +if (kdamond_pid <0 ) + kdamond_pid =-1 ; + } +return sprintf (buffer,"%d\n" , kdamond_pid); +}Likewise, is
damon_kdamond_pid()available in this kernel tree, or will this result in an implicit function declaration error?
I informed this and where the dependent patches can be found on the commentary area of this patch.
Quoted 3 lines
Signature · 2 lines
-- Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
Thanks,
SJ