From: Liew Rui Yan <aethernet65535@gmail.com>
To: SeongJae Park <sj@kernel.org>
Cc: damon@lists.linux.dev, linux-mm@kvack.org,
Liew Rui Yan <aethernet65535@gmail.com>
Subject: [RFC PATCH] mm/damon/reclaim: add 'available' memory as an optional watermarks metric
Date: Fri, 26 Jun 2026 16:10:38 +0800 [thread overview]
Message-ID: <20260626081038.46569-1-aethernet65535@gmail.com> (raw)
Problem
=======
Currently, DAMON's watermarks metric is calculated based on the
proportion of the system's free memory.
However, on devices like Android, the system typically maintains a very
low amount of free memory, even when the available memory is abundant.
This causes DAMON_RECLAIM to prematurely or aggressive trigger memory
reclamation, thereby increasing the risk of page refaults.
Solution
========
Introduce a new sysfs parameter 'memrate_type' to DAMON_RECLAIM. Users
can switch DAMON's watermark metric evaluation to be based on available
memory by writing 'available' to this parameter and commit the change.
Signed-off-by: Liew Rui Yan <aethernet65535@gmail.com>
---
include/linux/damon.h | 9 ++++---
mm/damon/core.c | 6 +++++
mm/damon/reclaim.c | 56 ++++++++++++++++++++++++++++++++++++++++
mm/damon/sysfs-schemes.c | 4 +++
4 files changed, 72 insertions(+), 3 deletions(-)
diff --git a/include/linux/damon.h b/include/linux/damon.h
index 6f7edb3590ef..0006e3a25317 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -314,13 +314,16 @@ struct damos_quota {
/**
* enum damos_wmark_metric - Represents the watermark metric.
*
- * @DAMOS_WMARK_NONE: Ignore the watermarks of the given scheme.
- * @DAMOS_WMARK_FREE_MEM_RATE: Free memory rate of the system in [0,1000].
- * @NR_DAMOS_WMARK_METRICS: Total number of DAMOS watermark metrics
+ * @DAMOS_WMARK_NONE: Ignore the watermarks of the given scheme.
+ * @DAMOS_WMARK_FREE_MEM_RATE: Free memory rate of the system in [0,1000].
+ * @DAMOS_WMARK_AVAILABLE_MEM_RATE: Available memory rate of the system in
+ * [0,1000].
+ * @NR_DAMOS_WMARK_METRICS: Total number of DAMOS watermark metrics
*/
enum damos_wmark_metric {
DAMOS_WMARK_NONE,
DAMOS_WMARK_FREE_MEM_RATE,
+ DAMOS_WMARK_AVAILABLE_MEM_RATE,
NR_DAMOS_WMARK_METRICS,
};
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 7e4b9affc5b0..f12d06081d70 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -3300,11 +3300,17 @@ static bool kdamond_need_stop(struct damon_ctx *ctx)
static int damos_get_wmark_metric_value(enum damos_wmark_metric metric,
unsigned long *metric_value)
{
+ long available_pages;
+
switch (metric) {
case DAMOS_WMARK_FREE_MEM_RATE:
*metric_value = global_zone_page_state(NR_FREE_PAGES) * 1000 /
totalram_pages();
return 0;
+ case DAMOS_WMARK_AVAILABLE_MEM_RATE:
+ available_pages = si_mem_available();
+ *metric_value = available_pages * 1000 / totalram_pages();
+ return 0;
default:
break;
}
diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c
index ce4499cf4b8b..229bc68bb1ad 100644
--- a/mm/damon/reclaim.c
+++ b/mm/damon/reclaim.c
@@ -159,6 +159,17 @@ static unsigned long addr_unit __read_mostly = 1;
static bool skip_anon __read_mostly;
module_param(skip_anon, bool, 0600);
+/*
+ * Watermarks metric options.
+ *
+ * If this parameter is set as ``free``, DAMON_RECLAIM calculates the watermark
+ * metric based on the system's free memory rate. If set as ``available``, it
+ * calculates the metric based on the system's available memory rate.
+ *
+ * Default is ``free``.
+ */
+static enum damos_wmark_metric memrate_type = DAMOS_WMARK_FREE_MEM_RATE;
+
static struct damos_stat damon_reclaim_stat;
DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(damon_reclaim_stat,
reclaim_tried_regions, reclaimed_regions, quota_exceeds);
@@ -220,6 +231,8 @@ static int damon_reclaim_apply_parameters(void)
goto out;
}
+ damon_reclaim_wmarks.metric = memrate_type;
+
attrs = damon_reclaim_mon_attrs;
if (autotune_monitoring_intervals) {
attrs.sample_interval = 5000;
@@ -376,6 +389,49 @@ 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 int damon_reclaim_memrate_type_store(const char *val,
+ const struct kernel_param *kp)
+{
+ if (sysfs_streq(val, "free"))
+ memrate_type = DAMOS_WMARK_FREE_MEM_RATE;
+ else if (sysfs_streq(val, "available"))
+ memrate_type = DAMOS_WMARK_AVAILABLE_MEM_RATE;
+ else
+ return -EINVAL;
+
+ return 0;
+}
+
+static int damon_reclaim_memrate_type_load(char *buffer,
+ const struct kernel_param *kp)
+{
+ int type = READ_ONCE(memrate_type);
+ int len = 0;
+
+ if (type == DAMOS_WMARK_FREE_MEM_RATE)
+ len += sysfs_emit_at(buffer, len, "[free] ");
+ else
+ len += sysfs_emit_at(buffer, len, "free ");
+
+ if (type == DAMOS_WMARK_AVAILABLE_MEM_RATE)
+ len += sysfs_emit_at(buffer, len, "[available] ");
+ else
+ len += sysfs_emit_at(buffer, len, "available ");
+
+ len += sysfs_emit_at(buffer, len, "\n");
+
+ return len;
+}
+
+static const struct kernel_param_ops memrate_type_param_ops = {
+ .set = damon_reclaim_memrate_type_store,
+ .get = damon_reclaim_memrate_type_load,
+};
+module_param_cb(memrate_type, &memrate_type_param_ops, &memrate_type, 0600);
+MODULE_PARM_DESC(memrate_type,
+ "Memory rate type for watermarks metric "
+ "(free or available, default: free)");
+
static bool damon_reclaim_enabled(void)
{
if (!ctx)
diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c
index 329cfd0bbe9f..5d6636433bd6 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -1056,6 +1056,10 @@ damos_sysfs_wmark_metric_names[] = {
.metric = DAMOS_WMARK_FREE_MEM_RATE,
.name = "free_mem_rate",
},
+ {
+ .metric = DAMOS_WMARK_AVAILABLE_MEM_RATE,
+ .name = "available_mem_rate",
+ },
};
static ssize_t metric_show(struct kobject *kobj, struct kobj_attribute *attr,
--
2.54.0
next reply other threads:[~2026-06-26 8:10 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-26 8:10 Liew Rui Yan [this message]
2026-06-26 14:18 ` [RFC PATCH] mm/damon/reclaim: add 'available' memory as an optional watermarks metric SeongJae Park
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260626081038.46569-1-aethernet65535@gmail.com \
--to=aethernet65535@gmail.com \
--cc=damon@lists.linux.dev \
--cc=linux-mm@kvack.org \
--cc=sj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox