From nobody Tue Jun 16 11:27:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF76A35F165; Sat, 18 Apr 2026 22:28:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776551289; cv=none; b=CCEJNQF54UqLOtK6bXROHRVLQB2hVqph9DiMKKKy++EjGOmxTv8oiLjbjUj0Qw89Ff/5bkUTXrgSW7KrF38Aodo8wZvwLh3g90G5nHqMfljZ1e/WdmZmDiVwqSSZZFZPt9GniUBjZZEWeX/P19j22eM30laWEsHR2lAxeqXIO0I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776551289; c=relaxed/simple; bh=xmi8JFCfIfNv/dt7D/wNwu1xStprbRBK6+QIpOf/ZP0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bGZ1ZhMUYgUWWRH3s8OIe9JULXulz7ofiI5cypc4gzosJOgS7u/gORgZXTA2/0mfyl2wWIQOzbO0LbMqEsBO5nWDr5ScFZ9LMQHfXeNd6+LdYbc5BZYvR3WUkTzHOEy7wNq9CwwNth2ql2sUmbo8SK4NAMzZpMFG1ZDMTAN3Jts= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RgJulB/Q; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RgJulB/Q" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 38C27C2BCB4; Sat, 18 Apr 2026 22:28:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1776551289; bh=xmi8JFCfIfNv/dt7D/wNwu1xStprbRBK6+QIpOf/ZP0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RgJulB/QlVPZkbcLBOsOt8Gm/b/BJl4fPldMonDkzGJyPtRLCjznipVXYgjA7rafp WTAh25UctVfgM56yDu3RseKl5rv3IUHbZdIfOf9zlcKqJNU3VklpplXBkeE2XkZhjR 13fgU/opF9piYEEAgfAaWcPis4U1r8oJKX8uclVXa4ttFUkT1TqD5KHJQ/UG9wRcnC Iw+BAdj8P/y7idK1zFeJLz1TTGKz5ZjJ3XaSVlxtsCUNm0346BlJIuB4Af3h3XllgZ U52mH2rZZLQ7bKVdTU8fJfELQSnXR2b0MAeUkj3IBaQYyHy0EQppORbmzLu+ywYoUy NiDJS87qrW8nQ== From: SeongJae Park To: Cc: SeongJae Park , "# 5 . 19 . x" , Andrew Morton , damon@lists.linux.dev, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Liew Rui Yan Subject: [RFC PATCH v2.1 1/3] mm/damon/reclaim: detect and use fresh enabled and kdamond_pid values Date: Sat, 18 Apr 2026 15:27:54 -0700 Message-ID: <20260418222758.39795-2-sj@kernel.org> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260418222758.39795-1-sj@kernel.org> References: <20260418222758.39795-1-sj@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 kdamond The 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. Fixes: e035c280f6df ("mm/damon/reclaim: support online inputs update") Cc: # 5.19.x Co-developed-by: Liew Rui Yan Signed-off-by: Liew Rui Yan Signed-off-by: SeongJae Park --- mm/damon/reclaim.c | 85 ++++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 30 deletions(-) diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c index 86da147786583..fe7fce26cf6ce 100644 --- a/mm/damon/reclaim.c +++ b/mm/damon/reclaim.c @@ -144,15 +144,6 @@ static unsigned long addr_unit __read_mostly =3D 1; static bool skip_anon __read_mostly; module_param(skip_anon, bool, 0600); =20 -/* - * 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 =3D -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; =20 - if (!on) { - err =3D damon_stop(&ctx, 1); - if (!err) - kdamond_pid =3D -1; - return err; - } + if (!on) + return damon_stop(&ctx, 1); =20 err =3D damon_reclaim_apply_parameters(); if (err) @@ -302,9 +289,6 @@ static int damon_reclaim_turn(bool on) err =3D damon_start(&ctx, 1, true); if (err) return err; - kdamond_pid =3D damon_kdamond_pid(ctx); - if (kdamond_pid < 0) - return kdamond_pid; return damon_call(ctx, &call_control); } =20 @@ -332,42 +316,83 @@ module_param_cb(addr_unit, &addr_unit_param_ops, &add= r_unit, 0600); MODULE_PARM_DESC(addr_unit, "Scale factor for DAMON_RECLAIM to ops address conversion (default: 1)"); =20 +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 =3D enabled; - bool enable; int err; =20 - err =3D kstrtobool(val, &enable); + err =3D kstrtobool(val, &enabled); if (err) return err; =20 - if (is_enabled =3D=3D enable) + if (damon_reclaim_enabled() =3D=3D enabled) return 0; =20 /* Called before init function. The function will handle this. */ if (!damon_initialized()) - goto set_param_out; + return 0; =20 - err =3D damon_reclaim_turn(enable); - if (err) - return err; + return damon_reclaim_turn(enabled); +} =20 -set_param_out: - enabled =3D 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'); } =20 static const struct kernel_param_ops enabled_param_ops =3D { .set =3D damon_reclaim_enabled_store, - .get =3D param_get_bool, + .get =3D damon_reclaim_enabled_load, }; =20 module_param_cb(enabled, &enabled_param_ops, &enabled, 0600); MODULE_PARM_DESC(enabled, "Enable or disable DAMON_RECLAIM (default: disabled)"); =20 +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 =3D -1; + + if (ctx) { + kdamond_pid =3D damon_kdamond_pid(ctx); + if (kdamond_pid < 0) + kdamond_pid =3D -1; + } + return sprintf(buffer, "%d\n", kdamond_pid); +} + +static const struct kernel_param_ops kdamond_pid_param_ops =3D { + .set =3D damon_reclaim_kdamond_pid_store, + .get =3D 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; --=20 2.47.3 From nobody Tue Jun 16 11:27:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ECE6435F185; Sat, 18 Apr 2026 22:28:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776551290; cv=none; b=CNqaQGYhnLhshsj3GI7YIGFgNFooKuCjj4UBcbaAXiJsT9Dciv7lDTyYxBF/Tl1z/vvOnxtIdDT4rUk6c84lUzSe8RRAduG701jPDFbLekdxktJEMjevzhepA34jQYNhaZaD4l4prUnwWR7IPFq+USbBkhriU7tXYY0ZkuDmHA8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776551290; c=relaxed/simple; bh=XJiKgBwZzik0HajbjdzAq1QjDE73mSEjEwzICB3I8pM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rtGRjYZv/wV8TvWjxBmy0XnfR9APiVnuhw91YyOCNXfwnSrc0SpNtMe9N3lKRxyZbm13JkvZbG33ynfwPBa9lt61tXWve+6hb+NVnIuR5hAa3oqvAW4GCOwWxRcZbCdUmy8LuEji7vVZ77JRTqu1J+KxuuFfV+F5JbzfL8S1HjY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DMigrX91; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DMigrX91" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 993ECC2BCB7; Sat, 18 Apr 2026 22:28:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1776551289; bh=XJiKgBwZzik0HajbjdzAq1QjDE73mSEjEwzICB3I8pM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DMigrX91xhjmcOjZhLtHX01ErlAI212fH3bUjd0Nhtonn3pEWCSfOGZFQWFe5L18e 379/S5E3V1kV6nupnKzIbVRdif6vwHjM1/2USMRTf3BX6RbN1vhQVt+0Zc2GrC8YxM 2cDjuY94lhGJiD1YRJOb8MTCQV3UMXwX5409V2jJwwm6Z3BUh9+W1WhTAIauUWme9z g0G6k1tWL+6WDTFPg2GC+Dx0rqC4LtzrgrPNLCYSF2B/Q9ZBFT1sKFahVxIGeF/9jc wNOLKH+edH56WvvB4L7d1HrbxUQkEM3I1+n5sPJ+0YnBE/EnLs4SMWeMIQFvkU1jb9 Iu54s9XsBUuYQ== From: SeongJae Park To: Cc: SeongJae Park , "# 6 . 0 . x" , Andrew Morton , damon@lists.linux.dev, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Liew Rui Yan Subject: [RFC PATCH v2.1 2/3] mm/damon/lru_sort: detect and use fresh enabled and kdamond_pid values Date: Sat, 18 Apr 2026 15:27:55 -0700 Message-ID: <20260418222758.39795-3-sj@kernel.org> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260418222758.39795-1-sj@kernel.org> References: <20260418222758.39795-1-sj@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 kdamond The 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. Fixes: 40e983cca927 ("mm/damon: introduce DAMON-based LRU-lists Sorting") Cc: # 6.0.x Co-developed-by: Liew Rui Yan Signed-off-by: Liew Rui Yan Signed-off-by: SeongJae Park --- mm/damon/lru_sort.c | 85 +++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 30 deletions(-) diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c index 554559d729760..8494040b1ee48 100644 --- a/mm/damon/lru_sort.c +++ b/mm/damon/lru_sort.c @@ -161,15 +161,6 @@ module_param(monitor_region_end, ulong, 0600); */ static unsigned long addr_unit __read_mostly =3D 1; =20 -/* - * PID of the DAMON thread - * - * If DAMON_LRU_SORT is enabled, this becomes the PID of the worker thread. - * Else, -1. - */ -static int kdamond_pid __read_mostly =3D -1; -module_param(kdamond_pid, int, 0400); - static struct damos_stat damon_lru_sort_hot_stat; DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(damon_lru_sort_hot_stat, lru_sort_tried_hot_regions, lru_sorted_hot_regions, @@ -386,12 +377,8 @@ static int damon_lru_sort_turn(bool on) { int err; =20 - if (!on) { - err =3D damon_stop(&ctx, 1); - if (!err) - kdamond_pid =3D -1; - return err; - } + if (!on) + return damon_stop(&ctx, 1); =20 err =3D damon_lru_sort_apply_parameters(); if (err) @@ -400,9 +387,6 @@ static int damon_lru_sort_turn(bool on) err =3D damon_start(&ctx, 1, true); if (err) return err; - kdamond_pid =3D damon_kdamond_pid(ctx); - if (kdamond_pid < 0) - return kdamond_pid; return damon_call(ctx, &call_control); } =20 @@ -430,42 +414,83 @@ module_param_cb(addr_unit, &addr_unit_param_ops, &add= r_unit, 0600); MODULE_PARM_DESC(addr_unit, "Scale factor for DAMON_LRU_SORT to ops address conversion (default: 1)"); =20 +static bool damon_lru_sort_enabled(void) +{ + if (!ctx) + return false; + return damon_is_running(ctx); +} + static int damon_lru_sort_enabled_store(const char *val, const struct kernel_param *kp) { - bool is_enabled =3D enabled; - bool enable; int err; =20 - err =3D kstrtobool(val, &enable); + err =3D kstrtobool(val, &enabled); if (err) return err; =20 - if (is_enabled =3D=3D enable) + if (damon_lru_sort_enabled() =3D=3D enabled) return 0; =20 /* Called before init function. The function will handle this. */ if (!damon_initialized()) - goto set_param_out; + return 0; =20 - err =3D damon_lru_sort_turn(enable); - if (err) - return err; + return damon_lru_sort_turn(enabled); +} =20 -set_param_out: - enabled =3D enable; - return err; +static int damon_lru_sort_enabled_load(char *buffer, + const struct kernel_param *kp) +{ + return sprintf(buffer, "%c\n", damon_lru_sort_enabled() ? 'Y' : 'N'); } =20 static const struct kernel_param_ops enabled_param_ops =3D { .set =3D damon_lru_sort_enabled_store, - .get =3D param_get_bool, + .get =3D damon_lru_sort_enabled_load, }; =20 module_param_cb(enabled, &enabled_param_ops, &enabled, 0600); MODULE_PARM_DESC(enabled, "Enable or disable DAMON_LRU_SORT (default: disabled)"); =20 +static int damon_lru_sort_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_lru_sort_kdamond_pid_load(char *buffer, + const struct kernel_param *kp) +{ + int kdamond_pid =3D -1; + + if (ctx) { + kdamond_pid =3D damon_kdamond_pid(ctx); + if (kdamond_pid < 0) + kdamond_pid =3D -1; + } + return sprintf(buffer, "%d\n", kdamond_pid); +} + +static const struct kernel_param_ops kdamond_pid_param_ops =3D { + .set =3D damon_lru_sort_kdamond_pid_store, + .get =3D damon_lru_sort_kdamond_pid_load, +}; + +/* + * PID of the DAMON thread + * + * If DAMON_LRU_SORT 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_lru_sort_init(void) { int err; --=20 2.47.3 From nobody Tue Jun 16 11:27:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E48B362153; Sat, 18 Apr 2026 22:28:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776551290; cv=none; b=R48mwInrKRuHvhb+Zb7mK88gFCpi9Y+AOqPhVCrMNZDHYvOYfSPZzkiucxsFdMEIO3vnOVi8xQxMf9BoTYxfoMINoNN8utv7ZPwFCJG43yKPw+m6nCCr1RkVzy0iiDNBRbBT8uIUMyoNZ2SZhgGBXj2P39dgdV3ALE3Cequ8nO0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776551290; c=relaxed/simple; bh=rIOaDq/KHXQ6SzD1AFFL4LR91YKZhChannZeLdJ236k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=P2AlRKxWy+UbtdmwrRkZBKV4hledpg8DuOJwiPDU54VcdzlRc88FjPbic/E7awEFMn2rNGm4Q0jgFawHo9j6NXhF5j+S1zQsJ+lu0rARgOK1KzooU9YVQN9B/cimekBqtTNN8CThCT9R092Th4FFVx0NxBeob7ijQhGyA0E86+c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jgzeQhsg; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jgzeQhsg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 04F1CC2BCB4; Sat, 18 Apr 2026 22:28:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1776551290; bh=rIOaDq/KHXQ6SzD1AFFL4LR91YKZhChannZeLdJ236k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jgzeQhsgwKIuFRBvvHZolXJF/06P/JDgwT3aJST88LE7fcVv1eKQYKncqNr42bhml BzOIp00zv3NQHb210ksIQY/TPGaI24eFwHZ32uV3AHjUk1wK/D5Lm24Z89IM1SRAs/ /Brp8h71+ItRBHnFgTikuflLqQq9EahrkX3n8lYWwKSsU5yJ25gNTkf/Y1zqD5Q4Tf 1YSk5fPdFKOgdIrD5GlvrEGzFaKS+goYxdhxKY7kryG0f6csSaFV8ikL7Uu1WTul9Z 6CDnHzdqd4FNNk2truBk0SZ51xS8k76kxVde4aA8WRPvAGqOCvRduXoeNr6CuyagBW adXiCi1qWjpTQ== From: SeongJae Park To: Cc: SeongJae Park , "# 6 . 17 . x" , Andrew Morton , damon@lists.linux.dev, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [RFC PATCH v2.1 3/3] mm/damon/stat: detect and use fresh enabled value Date: Sat, 18 Apr 2026 15:27:56 -0700 Message-ID: <20260418222758.39795-4-sj@kernel.org> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260418222758.39795-1-sj@kernel.org> References: <20260418222758.39795-1-sj@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" DAMON_STAT updates 'enabled' parameter value, which represents the running status of its kdamond, when the user explicitly requests start/stop of the kdamond. The kdamond can, however, be stopped even if the user explicitly requested the stop, if ctx->regions_score_histogram allocation failure at beginning of the execution of the kdamond. Hence, if the kdamond is stopped by the allocation failure, the value of the parameter can be stale. Users could show the stale value and be confused. The problem will only rarely happen in real and common setups because the allocation is arguably too small to fail. Also, unlike the similar bugs that are now fixed in DAMON_RECLAIM and DAMON_LRU_SORT, kdamond can be restarted in this case, because DAMON_STAT force-updates the enabled parameter value for user inputs. The bug is a bug, though. 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. The issue was dicovered [1] by Sashiko. [1] https://lore.kernel.org/20260416040602.88665-1-sj@kernel.org Fixes: 369c415e6073 ("mm/damon: introduce DAMON_STAT module") Cc: # 6.17.x Signed-off-by: SeongJae Park --- mm/damon/stat.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/mm/damon/stat.c b/mm/damon/stat.c index 99ba346f9e325..3951b762cbddf 100644 --- a/mm/damon/stat.c +++ b/mm/damon/stat.c @@ -19,14 +19,17 @@ static int damon_stat_enabled_store( const char *val, const struct kernel_param *kp); =20 +static int damon_stat_enabled_load(char *buffer, + const struct kernel_param *kp); + static const struct kernel_param_ops enabled_param_ops =3D { .set =3D damon_stat_enabled_store, - .get =3D param_get_bool, + .get =3D damon_stat_enabled_load, }; =20 static bool enabled __read_mostly =3D IS_ENABLED( CONFIG_DAMON_STAT_ENABLED_DEFAULT); -module_param_cb(enabled, &enabled_param_ops, &enabled, 0600); +module_param_cb(enabled, &enabled_param_ops, NULL, 0600); MODULE_PARM_DESC(enabled, "Enable of disable DAMON_STAT"); =20 static unsigned long estimated_memory_bandwidth __read_mostly; @@ -273,17 +276,23 @@ static void damon_stat_stop(void) damon_stat_context =3D NULL; } =20 +static bool damon_stat_enabled(void) +{ + if (!damon_stat_context) + return false; + return damon_is_running(damon_stat_context); +} + static int damon_stat_enabled_store( const char *val, const struct kernel_param *kp) { - bool is_enabled =3D enabled; int err; =20 err =3D kstrtobool(val, &enabled); if (err) return err; =20 - if (is_enabled =3D=3D enabled) + if (damon_stat_enabled() =3D=3D enabled) return 0; =20 if (!damon_initialized()) @@ -293,16 +302,17 @@ static int damon_stat_enabled_store( */ return 0; =20 - if (enabled) { - err =3D damon_stat_start(); - if (err) - enabled =3D false; - return err; - } + if (enabled) + return damon_stat_start(); damon_stat_stop(); return 0; } =20 +static int damon_stat_enabled_load(char *buffer, const struct kernel_param= *kp) +{ + return sprintf(buffer, "%c\n", damon_stat_enabled() ? 'Y' : 'N'); +} + static int __init damon_stat_init(void) { int err =3D 0; --=20 2.47.3