All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/2] mm/damon: Introduce basic auto-tuning framework with priority support
@ 2025-12-09 14:50 Enze Li
  2025-12-09 14:50 ` [RFC PATCH 1/2] mm/damon/auto-tuning: introduce DAMON-based auto-tunning module Enze Li
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Enze Li @ 2025-12-09 14:50 UTC (permalink / raw)
  To: sj, akpm; +Cc: damon, linux-mm, enze.li, Enze Li

Currently, users need to manually tune multiple parameters (e.g.,
watermarks, quotas) for different workloads when using DAMON.  This
increases the barrier to entry and complicates adoption.  This patchset
aims to lower this barrier by introducing a basic auto-tuning
framework for DAMON, which allows the system to automatically adapt
DAMON's operational parameters based on user-provided hints and system
state.

The core idea is to allow users to assign a simple priority level to
each monitoring target.  Based on these priorities and the current system
conditions (initially focusing on free memory), the framework
dynamically adjusts DAMON's parameters.  The initial implementation
focuses on the automatic management of watermarks.

While the auto-tuning functionality could be implemented in user space
as a separate daemon, integrating it directly into the DAMON kernel
subsystem offers distinct advantages essential for a memory management
automation feature.  First, it delivers superior performance and
real-time responsiveness by executing tuning logic within the monitoring
thread (kdamond) context, eliminating the latency and overhead of
frequent kernel-user space context switches and system calls.  This
ensures parameter adjustments can keep pace with DAMON's monitoring
cycles.  Second, it provides inherent reliability as the tuning logic
becomes an integral part of the DAMON context, immune to failures of any
user-space process (e.g., termination by the OOM killer) and requiring
no additional service management.  Finally, it offers a simplified,
out-of-the-box experience where users enable auto-tuning through a
single configuration without needing to install, maintain, or ensure
version compatibility of an external tool.  This kernel-based approach
aligns with the goal of creating a robust, low-overhead, and truly
self-adaptive memory management subsystem.

You may want to verify this framework using the following testing
procedure:

 # git clone -b v2 https://github.com/lienze/damo.git
 # cd damo
 # ./damo start --target_pid $(pidof <target1>) --priority 50 \
 --target_pid $(pidof <target2>) --priority 30 --damos_action \
 pageout

Enze Li (2):
  mm/damon/auto-tuning: introduce DAMON-based auto-tunning module
  mm/damon/sysfs: introduce priority sysfs interface

 include/linux/damon.h  |   3 +
 mm/damon/Kconfig       |  11 ++
 mm/damon/Makefile      |   1 +
 mm/damon/auto-tuning.c | 244 +++++++++++++++++++++++++++++++++++++++++
 mm/damon/auto-tuning.h |  10 ++
 mm/damon/core.c        |  11 ++
 mm/damon/sysfs.c       |  41 +++++++
 7 files changed, 321 insertions(+)
 create mode 100644 mm/damon/auto-tuning.c
 create mode 100644 mm/damon/auto-tuning.h

-- 
2.52.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [RFC PATCH 1/2] mm/damon/auto-tuning: introduce DAMON-based auto-tunning module
  2025-12-09 14:50 [RFC PATCH 0/2] mm/damon: Introduce basic auto-tuning framework with priority support Enze Li
@ 2025-12-09 14:50 ` Enze Li
  2025-12-11  8:50   ` kernel test robot
  2025-12-09 14:50 ` [RFC PATCH 2/2] mm/damon/sysfs: introduce priority sysfs interface Enze Li
  2025-12-12  3:38 ` [RFC PATCH 0/2] mm/damon: Introduce basic auto-tuning framework with priority support SeongJae Park
  2 siblings, 1 reply; 5+ messages in thread
From: Enze Li @ 2025-12-09 14:50 UTC (permalink / raw)
  To: sj, akpm; +Cc: damon, linux-mm, enze.li, Enze Li

Currently, users need to manually tune multiple parameters (e.g.,
watermarks, quotas) for different workloads when using DAMON.  This
increases the barrier to entry for ordinary users.  To reduce
configuration complexity, this patch introduces a basic framework for
DAMON auto-tuning and first implements automatic management of
watermarks.

Users only need to set a priority for monitoring targets.  The module
will then automatically calculate and set appropriate watermarks based
on system free memory.  When the set of monitoring targets changes, the
module re-evaluates and adjusts the watermarks to ensure that memory
pages of lower-priority targets remain active longer, thereby delaying
potential reclamation operations.

This implementation is the first step toward "fully DAMON automatic
tuning".  The long-term goal is to enable the system to completely and
self-adaptively optimize all key parameters after the user enables
DAMON.  Based on this framework, future patches can extend this
auto-tuning mechanism to other parameters, such as quotas and sampling
intervals.

Signed-off-by: Enze Li <lienze@kylinos.cn>
---
 include/linux/damon.h  |   3 +
 mm/damon/Kconfig       |  11 ++
 mm/damon/Makefile      |   1 +
 mm/damon/auto-tuning.c | 294 +++++++++++++++++++++++++++++++++++++++++
 mm/damon/auto-tuning.h |  10 ++
 mm/damon/core.c        |  17 +++
 6 files changed, 336 insertions(+)
 create mode 100644 mm/damon/auto-tuning.c
 create mode 100644 mm/damon/auto-tuning.h

diff --git a/include/linux/damon.h b/include/linux/damon.h
index 3813373a9200..f37f45820e33 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -108,6 +108,9 @@ struct damon_target {
 	struct list_head regions_list;
 	struct list_head list;
 	bool obsolete;
+#ifdef CONFIG_DAMON_AUTO_TUNING
+	unsigned int priority;
+#endif
 };
 
 /**
diff --git a/mm/damon/Kconfig b/mm/damon/Kconfig
index 8c868f7035fc..3c3517768f80 100644
--- a/mm/damon/Kconfig
+++ b/mm/damon/Kconfig
@@ -12,6 +12,17 @@ config DAMON
 	  See https://www.kernel.org/doc/html/latest/mm/damon/index.html for
 	  more information.
 
+config DAMON_AUTO_TUNING
+	bool "Build DAMON-based auto-tuning"
+	depends on DAMON_VADDR
+	default n
+	help
+	  This option enables the DAMON-based auto-tuning module, which
+	  automates memory management optimizations by dynamically adapting
+	  to observed data access patterns.
+
+	  If unsure, say N.
+
 config DAMON_KUNIT_TEST
 	bool "Test for damon" if !KUNIT_ALL_TESTS
 	depends on DAMON && KUNIT=y
diff --git a/mm/damon/Makefile b/mm/damon/Makefile
index d8d6bf5f8bff..4be5f5bb6668 100644
--- a/mm/damon/Makefile
+++ b/mm/damon/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-y				:= core.o
+obj-$(CONFIG_DAMON_AUTO_TUNING)	+= auto-tuning.o
 obj-$(CONFIG_DAMON_VADDR)	+= ops-common.o vaddr.o
 obj-$(CONFIG_DAMON_PADDR)	+= ops-common.o paddr.o
 obj-$(CONFIG_DAMON_SYSFS)	+= sysfs-common.o sysfs-schemes.o sysfs.o
diff --git a/mm/damon/auto-tuning.c b/mm/damon/auto-tuning.c
new file mode 100644
index 000000000000..61384e1f4717
--- /dev/null
+++ b/mm/damon/auto-tuning.c
@@ -0,0 +1,294 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DAMON-based auto tuning module.
+ *
+ * Author: Enze Li <lienze@kylinos.cn>
+ * Copyright (C) 2025 KylinSoft Corporation
+ */
+
+#define pr_fmt(fmt) "damon-auto-tuning: " fmt
+
+#include <linux/damon.h>
+#include <linux/kstrtox.h>
+#include <linux/module.h>
+#include <linux/list_sort.h>
+
+#include "auto-tuning.h"
+
+#ifdef MODULE_PARAM_PREFIX
+#undef MODULE_PARAM_PREFIX
+#endif
+#define MODULE_PARAM_PREFIX "damon_auto_tuning."
+
+static bool init_auto_tuning;
+static int auto_targets;
+static int max_nr_targets;
+static unsigned long init_metric;
+struct damon_ctx *auto_ctx;
+
+static struct damos *damon_auto_tuning_new_scheme(void)
+{
+	struct damos_access_pattern auto_pattern = {
+		.min_sz_region = PAGE_SIZE,
+		.max_sz_region = ULONG_MAX,
+		.min_nr_accesses = 0,
+		.max_nr_accesses = 0,
+		.min_age_region = 12000000 / 100000,
+		.max_age_region = UINT_MAX,
+	};
+
+	struct damos_quota auto_quota = {
+		.ms = 10,
+		.sz = 128 * 1024 * 1024,
+		.reset_interval = 1000,
+		.weight_sz = 0,
+		.weight_nr_accesses = 0,
+		.weight_age = 1
+	};
+
+	struct damos_watermarks auto_wmarks = {
+		.metric = DAMOS_WMARK_FREE_MEM_RATE,
+		.interval = 5000000,
+		.high = 500,
+		.mid = 400,
+		.low = 200,
+	};
+
+	return damon_new_scheme(&auto_pattern, DAMOS_PAGEOUT, 0, &auto_quota,
+				&auto_wmarks, NUMA_NO_NODE);
+}
+
+static bool damon_target_filter_match(struct damon_ctx *c,
+				      struct damos_filter *filter,
+				      struct damon_target *t)
+{
+	struct damon_target *ti;
+	int target_idx = 0;
+
+	damon_for_each_target(ti, c) {
+		if (ti == t)
+			break;
+		target_idx++;
+	}
+	return target_idx == filter->target_idx;
+}
+
+static int damon_nr_targets(struct damon_ctx *c)
+{
+	struct damon_target *t;
+	int nr_targets = 0;
+
+	damon_for_each_target(t, c) {
+		if (c->ops.target_valid && c->ops.target_valid(t))
+			nr_targets++;
+	}
+	return nr_targets;
+}
+
+static bool damon_targets_print_info(struct damon_ctx *c)
+{
+	int i = 0;
+	struct damos *s, *next;
+
+	damon_for_each_scheme_safe(s, next, c) {
+		pr_info("scheme%d:\n", ++i);
+		pr_info("\t wmarks {%d %ld %ld %ld %ld %d}\n",
+			s->wmarks.metric, s->wmarks.interval,
+			s->wmarks.high, s->wmarks.mid, s->wmarks.low,
+			s->wmarks.activated);
+	}
+	return true;
+}
+
+static int damon_targets_priority_max(struct damon_ctx *c)
+{
+	struct damon_target *t;
+	int priority_max = 0;
+
+	damon_for_each_target(t, c) {
+		if (c->ops.target_valid && c->ops.target_valid(t))
+			if (t->priority > priority_max)
+				priority_max = t->priority;
+	}
+	pr_debug("%s max=%d\n", __func__, priority_max);
+	return priority_max;
+}
+
+static int damon_targets_priority_min(struct damon_ctx *c)
+{
+	struct damon_target *t;
+	int priority_min = INT_MAX;
+
+	damon_for_each_target(t, c) {
+		if (c->ops.target_valid && c->ops.target_valid(t))
+			if (t->priority < priority_min)
+				priority_min = t->priority;
+	}
+	pr_debug("%s min=%d\n", __func__, priority_min);
+	return priority_min;
+}
+
+static bool _damon_auto_tuning_wmarks(struct damon_ctx *c, struct damos *s,
+				      struct damon_target *t)
+{
+	unsigned long adjust_priority, metric;
+	int min = damon_targets_priority_min(c);
+	int max = damon_targets_priority_max(c);
+	int nr_targets = damon_nr_targets(c);
+	int decay_factor = max_nr_targets - nr_targets;
+
+	metric = global_zone_page_state(NR_FREE_PAGES) * 1000 /
+		 totalram_pages();
+
+	/*
+	 * We are now ready to start adjusting the watermarks based on
+	 * priority.  The goal is to set each target's watermark above the
+	 * system's high watermark (to prevent it from triggering system-wide
+	 * actions) and below its initial memory capacity, as determined by
+	 * its importance.
+	 */
+	pr_debug("%s: metric=%ld\n", __func__, metric);
+	/* TODO: Here, we need to use the system's high watermark value, and
+	 * will temporarily substitute it with 100.
+	 */
+	if (nr_targets < max_nr_targets)
+		adjust_priority = adjust_priority * decay_factor / 10;
+	adjust_priority = (t->priority - min) * (metric - 100) / (max - min) + 100;
+
+	s->wmarks.high = adjust_priority;
+	s->wmarks.mid = adjust_priority;
+	s->wmarks.low = 0;
+	return true;
+}
+
+static bool damon_auto_tuning_wmarks(struct damon_ctx *c)
+{
+	struct damon_target *t;
+	struct damos *s, *next;
+	struct damos_filter *f;
+
+	damon_for_each_target(t, c) {
+		if (c->ops.target_valid && c->ops.target_valid(t)) {
+			damon_for_each_scheme_safe(s, next, c) {
+				damos_for_each_core_filter(f, s) {
+					if (damon_target_filter_match(c, f, t)) {
+						pr_debug("%s: priority=%d(idx=%d)\n",
+							 __func__, t->priority,
+							 f->target_idx);
+						_damon_auto_tuning_wmarks(c, s, t);
+					}
+				}
+			}
+		}
+	}
+	damon_targets_print_info(c);
+	return true;
+}
+
+static bool damon_targets_auto_tuning_tick(struct damon_ctx *c,
+					   bool init_wmarks)
+{
+	int nr_targets = 0;
+	unsigned long cur_jiffies = jiffies;
+	static unsigned long last_jiffies;
+
+	if (last_jiffies != 0) {
+		if (time_is_after_jiffies(last_jiffies + 5 * HZ))
+			return false;
+	}
+
+	pr_debug("%s %ld %ld\n", __func__, cur_jiffies, last_jiffies + 5 * HZ);
+	last_jiffies = cur_jiffies;
+
+	/*
+	 * Any change in the number of targets necessitates a recalibration of
+	 * the per-task watermarks.
+	 */
+	nr_targets = damon_nr_targets(auto_ctx);
+	if (auto_targets != nr_targets) {
+		damon_auto_tuning_wmarks(auto_ctx);
+		auto_targets = nr_targets;
+	}
+
+	if (max_nr_targets < auto_targets)
+		max_nr_targets = auto_targets;
+
+	return true;
+}
+
+static bool damon_targets_auto_tuning_init(struct damon_ctx *c)
+{
+	struct damon_target *t;
+	struct damos *s, *next, *new_scheme;
+	struct damos_filter *new_filter;
+	int i = 0;
+
+	init_auto_tuning = true;
+	auto_ctx = c;
+
+	damon_for_each_scheme_safe(s, next, c)
+		damon_destroy_scheme(s);
+
+	damon_for_each_target(t, c) {
+		new_scheme = damon_auto_tuning_new_scheme();
+		if (!new_scheme)
+			return -ENOMEM;
+
+		new_filter = damos_new_filter(DAMOS_FILTER_TYPE_TARGET, true, true);
+		if (!new_filter)
+			return -ENOMEM;
+		new_filter->target_idx = i++;
+
+		damos_add_filter(new_scheme, new_filter);
+		damon_add_scheme(c, new_scheme);
+
+		pr_info("\t add scheme %d\n", auto_targets);
+		auto_targets++;
+	}
+
+	max_nr_targets = auto_targets;
+
+	damon_targets_print_info(c);
+	damon_auto_tuning_wmarks(c);
+	damon_targets_print_info(c);
+
+	return true;
+}
+
+static bool damon_targets_priority_enabled(struct damon_ctx *c)
+{
+	struct damon_target *t;
+
+	damon_for_each_target(t, c)
+		if (t->priority > 0)
+			return true;
+	return false;
+}
+
+bool kdamond_targets_auto_tuning(struct damon_ctx *c)
+{
+	if (damon_targets_priority_enabled(c)) {
+		if (!init_auto_tuning)
+			damon_targets_auto_tuning_init(c);
+		else
+			damon_targets_auto_tuning_tick(c, false);
+	}
+	return false;
+}
+
+static int __init damon_auto_tuning_init(void)
+{
+	int err;
+
+	if (!damon_initialized()) {
+		err = -ENOMEM;
+		goto out;
+	}
+	init_metric = global_zone_page_state(NR_FREE_PAGES) * 1000 /
+		      totalram_pages();
+	pr_info("%s init_metric=%ld\n", __func__,  init_metric);
+out:
+	return err;
+}
+
+module_init(damon_auto_tuning_init);
diff --git a/mm/damon/auto-tuning.h b/mm/damon/auto-tuning.h
new file mode 100644
index 000000000000..766bff7d1101
--- /dev/null
+++ b/mm/damon/auto-tuning.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Common Code for DAMON auto-tuning
+ *
+ * Author: Enze Li <lienze@kylinos.cn>
+ * Copyright (C) 2025 KylinSoft Corporation
+ */
+
+bool kdamond_targets_auto_tuning(struct damon_ctx *c);
+
diff --git a/mm/damon/core.c b/mm/damon/core.c
index f9fc0375890a..d81a2b42488b 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -20,6 +20,10 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/damon.h>
 
+#ifdef CONFIG_DAMON_AUTO_TUNING
+#include "auto-tuning.h"
+#endif
+
 static DEFINE_MUTEX(damon_lock);
 static int nr_running_ctxs;
 static bool running_exclusive_ctxs;
@@ -476,6 +480,9 @@ struct damon_target *damon_new_target(void)
 	INIT_LIST_HEAD(&t->list);
 	t->obsolete = false;
 
+#ifdef CONFIG_DAMON_AUTO_TUNING
+	t->priority = 0;
+#endif
 	return t;
 }
 
@@ -2603,6 +2610,11 @@ static int kdamond_wait_activation(struct damon_ctx *ctx)
 
 		kdamond_usleep(min_wait_time);
 
+		/* TODO: Adapt to the damond_call mechanism. */
+#ifdef CONFIG_DAMON_AUTO_TUNING
+		kdamond_targets_auto_tuning(ctx);
+#endif
+
 		kdamond_call(ctx, false);
 		damos_walk_cancel(ctx);
 	}
@@ -2667,6 +2679,11 @@ static int kdamond_fn(void *data)
 		unsigned long next_ops_update_sis = ctx->next_ops_update_sis;
 		unsigned long sample_interval = ctx->attrs.sample_interval;
 
+		/* TODO: Adapt to the damond_call mechanism. */
+#ifdef CONFIG_DAMON_AUTO_TUNING
+		kdamond_targets_auto_tuning(ctx);
+#endif
+
 		if (kdamond_wait_activation(ctx))
 			break;
 

base-commit: cb015814f8b6eebcbb8e46e111d108892c5e6821
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC PATCH 2/2] mm/damon/sysfs: introduce priority sysfs interface
  2025-12-09 14:50 [RFC PATCH 0/2] mm/damon: Introduce basic auto-tuning framework with priority support Enze Li
  2025-12-09 14:50 ` [RFC PATCH 1/2] mm/damon/auto-tuning: introduce DAMON-based auto-tunning module Enze Li
@ 2025-12-09 14:50 ` Enze Li
  2025-12-12  3:38 ` [RFC PATCH 0/2] mm/damon: Introduce basic auto-tuning framework with priority support SeongJae Park
  2 siblings, 0 replies; 5+ messages in thread
From: Enze Li @ 2025-12-09 14:50 UTC (permalink / raw)
  To: sj, akpm; +Cc: damon, linux-mm, enze.li, Enze Li

This patch extends the DAMON sysfs interface to support the
configuration of target priorities, enabling users to assign and adjust
the relative importance of monitored processes at runtime.

Signed-off-by: Enze Li <lienze@kylinos.cn>
---
 mm/damon/sysfs.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
index e2bd2d7becdd..224d9e89d967 100644
--- a/mm/damon/sysfs.c
+++ b/mm/damon/sysfs.c
@@ -213,6 +213,9 @@ struct damon_sysfs_target {
 	struct damon_sysfs_regions *regions;
 	int pid;
 	bool obsolete;
+#ifdef CONFIG_DAMON_AUTO_TUNING
+	int priority;
+#endif
 };
 
 static struct damon_sysfs_target *damon_sysfs_target_alloc(void)
@@ -298,9 +301,44 @@ static struct kobj_attribute damon_sysfs_target_pid_attr =
 static struct kobj_attribute damon_sysfs_target_obsolete_attr =
 		__ATTR_RW_MODE(obsolete_target, 0600);
 
+#ifdef CONFIG_DAMON_AUTO_TUNING
+static ssize_t target_priority_show(struct kobject *kobj,
+		struct kobj_attribute *attr, char *buf)
+{
+	struct damon_sysfs_target *target = container_of(kobj,
+			struct damon_sysfs_target, kobj);
+
+	return sysfs_emit(buf, "%d\n", target->priority);
+}
+
+static ssize_t target_priority_store(struct kobject *kobj,
+		struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	int err, value;
+	struct damon_sysfs_target *target = container_of(kobj,
+			struct damon_sysfs_target, kobj);
+	err = kstrtoint(buf, 0, &value);
+	if (err)
+		return -EINVAL;
+
+	if (value > 0 && value <= 100)
+		target->priority = value;
+	else
+		return -EINVAL;
+
+	return count;
+}
+
+static struct kobj_attribute damon_sysfs_target_priority =
+		__ATTR_RW_MODE(target_priority, 0600);
+#endif
+
 static struct attribute *damon_sysfs_target_attrs[] = {
 	&damon_sysfs_target_pid_attr.attr,
 	&damon_sysfs_target_obsolete_attr.attr,
+#ifdef CONFIG_DAMON_AUTO_TUNING
+	&damon_sysfs_target_priority.attr,
+#endif
 	NULL,
 };
 ATTRIBUTE_GROUPS(damon_sysfs_target);
@@ -1406,6 +1444,9 @@ static int damon_sysfs_add_target(struct damon_sysfs_target *sys_target,
 			return -EINVAL;
 	}
 	t->obsolete = sys_target->obsolete;
+#ifdef CONFIG_DAMON_AUTO_TUNING
+	t->priority = sys_target->priority;
+#endif
 	return damon_sysfs_set_regions(t, sys_target->regions, ctx->min_sz_region);
 }
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [RFC PATCH 1/2] mm/damon/auto-tuning: introduce DAMON-based auto-tunning module
  2025-12-09 14:50 ` [RFC PATCH 1/2] mm/damon/auto-tuning: introduce DAMON-based auto-tunning module Enze Li
@ 2025-12-11  8:50   ` kernel test robot
  0 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2025-12-11  8:50 UTC (permalink / raw)
  To: Enze Li; +Cc: llvm, oe-kbuild-all

Hi Enze,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build warnings:

[auto build test WARNING on akpm-mm/mm-everything]

url:    https://github.com/intel-lab-lkp/linux/commits/Enze-Li/mm-damon-auto-tuning-introduce-DAMON-based-auto-tunning-module/20251210-025514
base:   https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link:    https://lore.kernel.org/r/20251209145026.3263754-2-lienze%40kylinos.cn
patch subject: [RFC PATCH 1/2] mm/damon/auto-tuning: introduce DAMON-based auto-tunning module
config: x86_64-allmodconfig (https://download.01.org/0day-ci/archive/20251211/202512111604.B1hpFdVs-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251211/202512111604.B1hpFdVs-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512111604.B1hpFdVs-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> mm/damon/auto-tuning.c:155:21: warning: variable 'adjust_priority' is uninitialized when used here [-Wuninitialized]
     155 |                 adjust_priority = adjust_priority * decay_factor / 10;
         |                                   ^~~~~~~~~~~~~~~
   mm/damon/auto-tuning.c:134:31: note: initialize the variable 'adjust_priority' to silence this warning
     134 |         unsigned long adjust_priority, metric;
         |                                      ^
         |                                       = 0
>> mm/damon/auto-tuning.c:283:6: warning: variable 'err' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
     283 |         if (!damon_initialized()) {
         |             ^~~~~~~~~~~~~~~~~~~~
   mm/damon/auto-tuning.c:291:9: note: uninitialized use occurs here
     291 |         return err;
         |                ^~~
   mm/damon/auto-tuning.c:283:2: note: remove the 'if' if its condition is always true
     283 |         if (!damon_initialized()) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~
   mm/damon/auto-tuning.c:281:9: note: initialize the variable 'err' to silence this warning
     281 |         int err;
         |                ^
         |                 = 0
   2 warnings generated.


vim +/adjust_priority +155 mm/damon/auto-tuning.c

   130	
   131	static bool _damon_auto_tuning_wmarks(struct damon_ctx *c, struct damos *s,
   132					      struct damon_target *t)
   133	{
   134		unsigned long adjust_priority, metric;
   135		int min = damon_targets_priority_min(c);
   136		int max = damon_targets_priority_max(c);
   137		int nr_targets = damon_nr_targets(c);
   138		int decay_factor = max_nr_targets - nr_targets;
   139	
   140		metric = global_zone_page_state(NR_FREE_PAGES) * 1000 /
   141			 totalram_pages();
   142	
   143		/*
   144		 * We are now ready to start adjusting the watermarks based on
   145		 * priority.  The goal is to set each target's watermark above the
   146		 * system's high watermark (to prevent it from triggering system-wide
   147		 * actions) and below its initial memory capacity, as determined by
   148		 * its importance.
   149		 */
   150		pr_debug("%s: metric=%ld\n", __func__, metric);
   151		/* TODO: Here, we need to use the system's high watermark value, and
   152		 * will temporarily substitute it with 100.
   153		 */
   154		if (nr_targets < max_nr_targets)
 > 155			adjust_priority = adjust_priority * decay_factor / 10;
   156		adjust_priority = (t->priority - min) * (metric - 100) / (max - min) + 100;
   157	
   158		s->wmarks.high = adjust_priority;
   159		s->wmarks.mid = adjust_priority;
   160		s->wmarks.low = 0;
   161		return true;
   162	}
   163	
   164	static bool damon_auto_tuning_wmarks(struct damon_ctx *c)
   165	{
   166		struct damon_target *t;
   167		struct damos *s, *next;
   168		struct damos_filter *f;
   169	
   170		damon_for_each_target(t, c) {
   171			if (c->ops.target_valid && c->ops.target_valid(t)) {
   172				damon_for_each_scheme_safe(s, next, c) {
   173					damos_for_each_core_filter(f, s) {
   174						if (damon_target_filter_match(c, f, t)) {
   175							pr_debug("%s: priority=%d(idx=%d)\n",
   176								 __func__, t->priority,
   177								 f->target_idx);
   178							_damon_auto_tuning_wmarks(c, s, t);
   179						}
   180					}
   181				}
   182			}
   183		}
   184		damon_targets_print_info(c);
   185		return true;
   186	}
   187	
   188	static bool damon_targets_auto_tuning_tick(struct damon_ctx *c,
   189						   bool init_wmarks)
   190	{
   191		int nr_targets = 0;
   192		unsigned long cur_jiffies = jiffies;
   193		static unsigned long last_jiffies;
   194	
   195		if (last_jiffies != 0) {
   196			if (time_is_after_jiffies(last_jiffies + 5 * HZ))
   197				return false;
   198		}
   199	
   200		pr_debug("%s %ld %ld\n", __func__, cur_jiffies, last_jiffies + 5 * HZ);
   201		last_jiffies = cur_jiffies;
   202	
   203		/*
   204		 * Any change in the number of targets necessitates a recalibration of
   205		 * the per-task watermarks.
   206		 */
   207		nr_targets = damon_nr_targets(auto_ctx);
   208		if (auto_targets != nr_targets) {
   209			damon_auto_tuning_wmarks(auto_ctx);
   210			auto_targets = nr_targets;
   211		}
   212	
   213		if (max_nr_targets < auto_targets)
   214			max_nr_targets = auto_targets;
   215	
   216		return true;
   217	}
   218	
   219	static bool damon_targets_auto_tuning_init(struct damon_ctx *c)
   220	{
   221		struct damon_target *t;
   222		struct damos *s, *next, *new_scheme;
   223		struct damos_filter *new_filter;
   224		int i = 0;
   225	
   226		init_auto_tuning = true;
   227		auto_ctx = c;
   228	
   229		damon_for_each_scheme_safe(s, next, c)
   230			damon_destroy_scheme(s);
   231	
   232		damon_for_each_target(t, c) {
   233			new_scheme = damon_auto_tuning_new_scheme();
   234			if (!new_scheme)
   235				return -ENOMEM;
   236	
   237			new_filter = damos_new_filter(DAMOS_FILTER_TYPE_TARGET, true, true);
   238			if (!new_filter)
   239				return -ENOMEM;
   240			new_filter->target_idx = i++;
   241	
   242			damos_add_filter(new_scheme, new_filter);
   243			damon_add_scheme(c, new_scheme);
   244	
   245			pr_info("\t add scheme %d\n", auto_targets);
   246			auto_targets++;
   247		}
   248	
   249		max_nr_targets = auto_targets;
   250	
   251		damon_targets_print_info(c);
   252		damon_auto_tuning_wmarks(c);
   253		damon_targets_print_info(c);
   254	
   255		return true;
   256	}
   257	
   258	static bool damon_targets_priority_enabled(struct damon_ctx *c)
   259	{
   260		struct damon_target *t;
   261	
   262		damon_for_each_target(t, c)
   263			if (t->priority > 0)
   264				return true;
   265		return false;
   266	}
   267	
   268	bool kdamond_targets_auto_tuning(struct damon_ctx *c)
   269	{
   270		if (damon_targets_priority_enabled(c)) {
   271			if (!init_auto_tuning)
   272				damon_targets_auto_tuning_init(c);
   273			else
   274				damon_targets_auto_tuning_tick(c, false);
   275		}
   276		return false;
   277	}
   278	
   279	static int __init damon_auto_tuning_init(void)
   280	{
   281		int err;
   282	
 > 283		if (!damon_initialized()) {
   284			err = -ENOMEM;
   285			goto out;
   286		}
   287		init_metric = global_zone_page_state(NR_FREE_PAGES) * 1000 /
   288			      totalram_pages();
   289		pr_info("%s init_metric=%ld\n", __func__,  init_metric);
   290	out:
   291		return err;
   292	}
   293	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFC PATCH 0/2] mm/damon: Introduce basic auto-tuning framework with priority support
  2025-12-09 14:50 [RFC PATCH 0/2] mm/damon: Introduce basic auto-tuning framework with priority support Enze Li
  2025-12-09 14:50 ` [RFC PATCH 1/2] mm/damon/auto-tuning: introduce DAMON-based auto-tunning module Enze Li
  2025-12-09 14:50 ` [RFC PATCH 2/2] mm/damon/sysfs: introduce priority sysfs interface Enze Li
@ 2025-12-12  3:38 ` SeongJae Park
  2 siblings, 0 replies; 5+ messages in thread
From: SeongJae Park @ 2025-12-12  3:38 UTC (permalink / raw)
  To: Enze Li; +Cc: SeongJae Park, akpm, damon, linux-mm, enze.li

On Tue,  9 Dec 2025 22:50:24 +0800 Enze Li <lienze@kylinos.cn> wrote:

Sorry for late response!

> Currently, users need to manually tune multiple parameters (e.g.,
> watermarks, quotas) for different workloads when using DAMON.  This
> increases the barrier to entry and complicates adoption.

I cannot agree this more!

> This patchset
> aims to lower this barrier by introducing a basic auto-tuning
> framework for DAMON, which allows the system to automatically adapt
> DAMON's operational parameters based on user-provided hints and system
> state.
> 
> The core idea is to allow users to assign a simple priority level to
> each monitoring target.  Based on these priorities and the current system
> conditions (initially focusing on free memory), the framework
> dynamically adjusts DAMON's parameters.  The initial implementation
> focuses on the automatic management of watermarks.

How difficult watermarks tuning is?  Do you have some real use case or
realistic benchmarks showing it?  Could you please share that?

> 
> While the auto-tuning functionality could be implemented in user space
> as a separate daemon, integrating it directly into the DAMON kernel
> subsystem offers distinct advantages essential for a memory management
> automation feature.  First, it delivers superior performance and
> real-time responsiveness by executing tuning logic within the monitoring
> thread (kdamond) context, eliminating the latency and overhead of
> frequent kernel-user space context switches and system calls.  This
> ensures parameter adjustments can keep pace with DAMON's monitoring
> cycles.  Second, it provides inherent reliability as the tuning logic
> becomes an integral part of the DAMON context, immune to failures of any
> user-space process (e.g., termination by the OOM killer) and requiring
> no additional service management.  Finally, it offers a simplified,
> out-of-the-box experience where users enable auto-tuning through a
> single configuration without needing to install, maintain, or ensure
> version compatibility of an external tool.  This kernel-based approach
> aligns with the goal of creating a robust, low-overhead, and truly
> self-adaptive memory management subsystem.

I agree your points.  In-kernel auto-tuning is much more efficient and simple
to use, compared to user-space based ones.  Nonetheless, the disadvantage of
in-kernel auto-tuning is it increases the maintenace burden.  I'd like to add
lengthy change only if it shows clear benefit.

From this cover letter, I show only "potential" future benefits that might not
land on the real world.  Do you have some real use case or realistic benchmarks
showing the benefit you explained above?  If so, could you please share those?


Thanks,
SJ

[...]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-12-12  3:38 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-09 14:50 [RFC PATCH 0/2] mm/damon: Introduce basic auto-tuning framework with priority support Enze Li
2025-12-09 14:50 ` [RFC PATCH 1/2] mm/damon/auto-tuning: introduce DAMON-based auto-tunning module Enze Li
2025-12-11  8:50   ` kernel test robot
2025-12-09 14:50 ` [RFC PATCH 2/2] mm/damon/sysfs: introduce priority sysfs interface Enze Li
2025-12-12  3:38 ` [RFC PATCH 0/2] mm/damon: Introduce basic auto-tuning framework with priority support SeongJae Park

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.