Skip to contentSkip to conversation

mm/damon: support multiple goal-based quota tuning algorithms

RFC PATCH Superseded SeongJae Park 1 participant 7 messages Feb 12 – Feb 27

Subsystems (4)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

SeongJae Park

author maintainer
#0 lore raw

cover mm/damon: support multiple goal-based quota tuning algorithms

Aim-oriented DAMOS quota atuo-tuning uses a single tuning algorithm. The algorithm is designed to find a non-zero quota that should be consistently kept for achieving the aimed goal for long term. In other words, the algorithm assumes the goal will be under-achieved once the DAMOS scheme is completely deactivated. Memory pressure level is one good example of such an assumed goal metric.

It is particularly useful for long term automated kernel-only operations on dynamic environments. As always, however, no single algorithm fits all. When the environment has static characteristics and the goal metric has no factor to move without additional intervention, the algorithm is difficult to control and accurately achieve the goal. Systems running by not only the kernel but with some user space controls can be examples. Actually there were reports [1,2] of such cases.

Extend DAMOS quotas goal core API and sysfs ABI to support multiple quota tuning algorithms that the API callers and/or ABI users can select. Keep the current algorithm as the default one, to keep the default behavior unchanged. Also give it a name, "consist", as it is designed to "consistently" apply the DAMOS action. And introduce a new tuning algorithm, namely "temporal". It is designed to apply the DAMOS action only temporally until the goal is achieved, in a deterministic way. In more detail, as long as the goal is under-achieved, it uses the maximum quota available. Once the goal is over-achieved, it sets the quota zero.

[1] https://lore.kernel.org/CALa+Y17__d=ZsM1yX+MXx0ozVdsXnFqF4p0g+kATEitrWyZFfg@mail.gmail.com
[2] https://lore.kernel.org/[email protected]

SeongJae Park (5):
mm/damon/core: introduce damos_quota_goal_tuner mm/damon/core: introduce DAMOS_QUOTA_GOAL_TUNER_TEMPORAL mm/damon/sysfs-schemes: implement quotas->goal_tuner file Docs/mm/damon/design: document the goal-based quota tuner selections Docs/admin-guide/mm/damon/usage: document goal_tuner sysfs file

 Documentation/admin-guide/mm/damon/usage.rst | 16 ++++--
 Documentation/mm/damon/design.rst            | 12 ++++
 include/linux/damon.h                        | 11 ++++
 mm/damon/core.c                              | 33 +++++++++--
 mm/damon/sysfs-schemes.c                     | 58 ++++++++++++++++++++
 5 files changed, 120 insertions(+), 10 deletions(-)

base-commit: 3c44a1294328e58fcf8708f8d1c2ddcb03178966

Signature · 1 line
2.47.3
author maintainer
#1 lore raw

RFC PATCH 1/5 mm/damon/core: introduce damos_quota_goal_tuner

Currently DAMOS quota goal feature utilizes a single feedback loop based algorithm for automatic tuning of the effective quota. It is proven to be useful on dynamic environments that operate systems with only kernels. But, no one fits all, and we got multiple reports [1,2] of cases that the algorithm is not optimum.

Introduce a new field of 'struct damos_quotas', namely 'goal_tuner'. It specifies what tuning algorithm the given scheme should use, and allows DAMON API callers to set it as they want. Nonetheless, this commit does not introduce a new tuning algorithm but only the interface. This commit hence makes no behavioral change. A new algorithm will be added by the following commit.

[1] https://lore.kernel.org/CALa+Y17__d=ZsM1yX+MXx0ozVdsXnFqF4p0g+kATEitrWyZFfg@mail.gmail.com
[2] https://lore.kernel.org/[email protected]

---
 include/linux/damon.h | 9 +++++++++
 mm/damon/core.c       | 4 +++-
 2 files changed, 12 insertions(+), 1 deletion(-)
include/linux/damon.h +9 -0
index a4fea23da8576..25345b5f821b9 100644
@@ -213,6 +213,14 @@ struct damos_quota_goal {
 	struct list_head list;
 };
 
+/**
+ * enum damos_quota_goal_tuner - Goal-based quota tuning logic.
+ * @DAMOS_QUOTA_GOAL_TUNER_CONSIST:	Aim long term consistent quota.
+ */
+enum damos_quota_goal_tuner {
+	DAMOS_QUOTA_GOAL_TUNER_CONSIST,
+};
+
 /**
  * struct damos_quota - Controls the aggressiveness of the given scheme.
  * @reset_interval:	Charge reset interval in milliseconds.
@@ -260,6 +268,7 @@ struct damos_quota {
 	unsigned long ms;
 	unsigned long sz;
 	struct list_head goals;
+	enum damos_quota_goal_tuner goal_tuner;
 	unsigned long esz;
 
 	unsigned int weight_sz;
mm/damon/core.c +3 -1
index 0ff190ed8a599..1c126d910fe62 100644
@@ -405,8 +405,9 @@ struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
 	INIT_LIST_HEAD(&scheme->list);
 
 	scheme->quota = *(damos_quota_init(quota));
-	/* quota.goals should be separately set by caller */
+	/* quota.goals and .goal_tuner should be separately set by caller */
 	INIT_LIST_HEAD(&scheme->quota.goals);
+	scheme->quota.goal_tuner = DAMOS_QUOTA_GOAL_TUNER_CONSIST;
 
 	scheme->wmarks = *wmarks;
 	scheme->wmarks.activated = true;
@@ -860,6 +861,7 @@ static int damos_commit_quota(struct damos_quota *dst, struct damos_quota *src)
 	err = damos_commit_quota_goals(dst, src);
 	if (err)
 		return err;
+	dst->goal_tuner = src->goal_tuner;
 	dst->weight_sz = src->weight_sz;
 	dst->weight_nr_accesses = src->weight_nr_accesses;
 	dst->weight_age = src->weight_age;
Signature · 1 line
2.47.3
author maintainer
#2 lore raw

Re: [RFC PATCH 1/5] mm/damon/core: introduce damos_quota_goal_tuner

Quoted 54 lines · On Wed, 11 Feb 2026 22:23:08 -0800 SeongJae Park <[email protected]> wrote:

Currently DAMOS quota goal feature utilizes a single feedback loop based algorithm for automatic tuning of the effective quota. It is proven to be useful on dynamic environments that operate systems with only kernels. But, no one fits all, and we got multiple reports [1,2] of cases that the algorithm is not optimum.

Introduce a new field of 'struct damos_quotas', namely 'goal_tuner'. It specifies what tuning algorithm the given scheme should use, and allows DAMON API callers to set it as they want. Nonetheless, this commit does not introduce a new tuning algorithm but only the interface. This commit hence makes no behavioral change. A new algorithm will be added by the following commit.

[1] https://lore.kernel.org/CALa+Y17__d=ZsM1yX+MXx0ozVdsXnFqF4p0g+kATEitrWyZFfg@mail.gmail.com
[2] https://lore.kernel.org/[email protected]

---
 include/linux/damon.h | 9 +++++++++
 mm/damon/core.c       | 4 +++-
 2 files changed, 12 insertions(+), 1 deletion(-)
include/linux/damon.h +9 -0
index a4fea23da8576..25345b5f821b9 100644
@@ -213,6 +213,14 @@ struct damos_quota_goal {
 	struct list_head list;
 };
 
+/**
+ * enum damos_quota_goal_tuner - Goal-based quota tuning logic.
+ * @DAMOS_QUOTA_GOAL_TUNER_CONSIST:	Aim long term consistent quota.
+ */
+enum damos_quota_goal_tuner {
+	DAMOS_QUOTA_GOAL_TUNER_CONSIST,
+};
+
 /**
  * struct damos_quota - Controls the aggressiveness of the given scheme.
  * @reset_interval:	Charge reset interval in milliseconds.
@@ -260,6 +268,7 @@ struct damos_quota {
 	unsigned long ms;
 	unsigned long sz;
 	struct list_head goals;
+	enum damos_quota_goal_tuner goal_tuner;
 	unsigned long esz;
 
 	unsigned int weight_sz;
mm/damon/core.c +0 -0
index 0ff190ed8a599..1c126d910fe62 100644

mm/damon/core.c struct damos *damon_new_scheme(struct damos_access_pattern *pattern, · line 410

Quoted 7 lines
mm/damon/core.c +2 -1
@@ -405,8 +405,9 @@ struct damos *damon_new_scheme(struct damos_access_pattern *pattern,
 	INIT_LIST_HEAD(&scheme->list);
 
 	scheme->quota = *(damos_quota_init(quota));
-	/* quota.goals should be separately set by caller */
+	/* quota.goals and .goal_tuner should be separately set by caller */
 	INIT_LIST_HEAD(&scheme->quota.goals);
+	scheme->quota.goal_tuner = DAMOS_QUOTA_GOAL_TUNER_CONSIST;

Ravi found this is resetting tuner setup in damon_sysfs_add_quota_score() in sysfs-schemes.c. As a result, users were unable to use goal_tuner feature. Ravi further suggested a fix that sets the goal_tuner after damon_new_scheme(), as suggested here.

I was thinking that's the right fix assuming the comment is right. I was also thinking I entirely forgot setting the goal_tuner field in sysfs-schemes.c. But I now find I didn't entirely forget it, as the third patch of this series does set it on the quota struct that is passed to damon_new_scheme(). However I was stupidly forgetting the fact that damon_new_scheme() overwrites the field, and I asked callers to set it after the call.

Now I think the above initialization and the instruction on the comment is just wrong. There is no reason to refuse the caller-set value in the parameter struct. Rather, it only confuses callers.

I will fix the issue by simply dropping the above diff.

[1] https://lore.kernel.org/[email protected]

Thanks,
SJ

[...]

author maintainer
#3 lore raw

RFC PATCH 2/5 mm/damon/core: introduce DAMOS_QUOTA_GOAL_TUNER_TEMPORAL

In reply to SeongJae Park

Introduce a new goal-based DAMOS quota auto-tuning algorithm, namely DAMOS_QUOTA_GOAL_TUNER_TEMPORAL (temporal in short). The algorithm aims to trigger the DAMOS action only for a temporal time, until the goal is achieved. For the temporal period, it uses as much quota as allowed. Once the goal is achieved, it sets the quota zero, so effectively make the scheme be deactivated.

---
 include/linux/damon.h |  2 ++
 mm/damon/core.c       | 29 ++++++++++++++++++++++++-----
 2 files changed, 26 insertions(+), 5 deletions(-)
include/linux/damon.h +2 -0
index 25345b5f821b9..0ab247fb06ca8 100644
@@ -216,9 +216,11 @@ struct damos_quota_goal {
 /**
  * enum damos_quota_goal_tuner - Goal-based quota tuning logic.
  * @DAMOS_QUOTA_GOAL_TUNER_CONSIST:	Aim long term consistent quota.
+ * @DAMOS_QUOTA_GOAL_TUNER_TEMPORAL:	Aim zero quota asap.
  */
 enum damos_quota_goal_tuner {
 	DAMOS_QUOTA_GOAL_TUNER_CONSIST,
+	DAMOS_QUOTA_GOAL_TUNER_TEMPORAL,
 };
 
 /**
mm/damon/core.c +24 -5
index 1c126d910fe62..81e3ef737be77 100644
@@ -2217,6 +2217,26 @@ static unsigned long damos_quota_score(struct damos_quota *quota)
 	return highest_score;
 }
 
+static void damos_goal_tune_esz_bp_consist(struct damos_quota *quota)
+{
+	unsigned long score = damos_quota_score(quota);
+
+	quota->esz_bp = damon_feed_loop_next_input(
+			max(quota->esz_bp, 10000UL), score);
+}
+
+static void damos_goal_tune_esz_bp_temporal(struct damos_quota *quota)
+{
+	unsigned long score = damos_quota_score(quota);
+
+	if (score >= 10000)
+		quota->esz_bp = 0;
+	else if (quota->sz)
+		quota->esz_bp = quota->sz * 10000;
+	else
+		quota->esz_bp = ULONG_MAX;
+}
+
 /*
  * Called only if quota->ms, or quota->sz are set, or quota->goals is not empty
  */
@@ -2231,11 +2251,10 @@ static void damos_set_effective_quota(struct damos_quota *quota)
 	}
 
 	if (!list_empty(&quota->goals)) {
-		unsigned long score = damos_quota_score(quota);
-
-		quota->esz_bp = damon_feed_loop_next_input(
-				max(quota->esz_bp, 10000UL),
-				score);
+		if (quota->goal_tuner == DAMOS_QUOTA_GOAL_TUNER_CONSIST)
+			damos_goal_tune_esz_bp_consist(quota);
+		else if (quota->goal_tuner == DAMOS_QUOTA_GOAL_TUNER_TEMPORAL)
+			damos_goal_tune_esz_bp_temporal(quota);
 		esz = quota->esz_bp / 10000;
 	}
 
Signature · 1 line
2.47.3
author maintainer
#4 lore raw

RFC PATCH 3/5 mm/damon/sysfs-schemes: implement quotas->goal_tuner file

In reply to SeongJae Park

Add a new DAMON sysfs interface file, namely goal_tuner under the DAMOS quotas directory. It is connected to the damos_quota->goal_tuner field. Users can therefore select their favorite goal-based quotas tuning algorithm by writing special keywords to the file.

---
 mm/damon/sysfs-schemes.c | 58 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
mm/damon/sysfs-schemes.c +58 -0
index 2b05a64771884..b30d9139b1c23 100644
@@ -1492,6 +1492,7 @@ struct damon_sysfs_quotas {
 	unsigned long sz;
 	unsigned long reset_interval_ms;
 	unsigned long effective_sz;	/* Effective size quota in bytes */
+	enum damos_quota_goal_tuner goal_tuner;
 };
 
 static struct damon_sysfs_quotas *damon_sysfs_quotas_alloc(void)
@@ -1614,6 +1615,58 @@ static ssize_t effective_bytes_show(struct kobject *kobj,
 	return sysfs_emit(buf, "%lu\n", quotas->effective_sz);
 }
 
+struct damos_sysfs_qgoal_tuner_name {
+	enum damos_quota_goal_tuner tuner;
+	char *name;
+};
+
+static struct damos_sysfs_qgoal_tuner_name damos_sysfs_qgoal_tuner_names[] = {
+	{
+		.tuner = DAMOS_QUOTA_GOAL_TUNER_CONSIST,
+		.name = "consist",
+	},
+	{
+		.tuner = DAMOS_QUOTA_GOAL_TUNER_TEMPORAL,
+		.name = "temporal",
+	},
+};
+
+static ssize_t goal_tuner_show(struct kobject *kobj,
+		struct kobj_attribute *attr, char *buf)
+{
+	struct damon_sysfs_quotas *quotas = container_of(kobj,
+			struct damon_sysfs_quotas, kobj);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(damos_sysfs_qgoal_tuner_names); i++) {
+		struct damos_sysfs_qgoal_tuner_name *tuner_name;
+
+		tuner_name = &damos_sysfs_qgoal_tuner_names[i];
+		if (tuner_name->tuner == quotas->goal_tuner)
+			return sysfs_emit(buf, "%s\n", tuner_name->name);
+	}
+	return -EINVAL;
+}
+
+static ssize_t goal_tuner_store(struct kobject *kobj,
+		struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	struct damon_sysfs_quotas *quotas = container_of(kobj,
+			struct damon_sysfs_quotas, kobj);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(damos_sysfs_qgoal_tuner_names); i++) {
+		struct damos_sysfs_qgoal_tuner_name *tuner_name;
+
+		tuner_name = &damos_sysfs_qgoal_tuner_names[i];
+		if (sysfs_streq(buf, tuner_name->name)) {
+			quotas->goal_tuner = tuner_name->tuner;
+			return count;
+		}
+	}
+	return -EINVAL;
+}
+
 static void damon_sysfs_quotas_release(struct kobject *kobj)
 {
 	kfree(container_of(kobj, struct damon_sysfs_quotas, kobj));
@@ -1631,11 +1684,15 @@ static struct kobj_attribute damon_sysfs_quotas_reset_interval_ms_attr =
 static struct kobj_attribute damon_sysfs_quotas_effective_bytes_attr =
 		__ATTR_RO_MODE(effective_bytes, 0400);
 
+static struct kobj_attribute damon_sysfs_quotas_goal_tuner_attr =
+		__ATTR_RW_MODE(goal_tuner, 0600);
+
 static struct attribute *damon_sysfs_quotas_attrs[] = {
 	&damon_sysfs_quotas_ms_attr.attr,
 	&damon_sysfs_quotas_sz_attr.attr,
 	&damon_sysfs_quotas_reset_interval_ms_attr.attr,
 	&damon_sysfs_quotas_effective_bytes_attr.attr,
+	&damon_sysfs_quotas_goal_tuner_attr.attr,
 	NULL,
 };
 ATTRIBUTE_GROUPS(damon_sysfs_quotas);
@@ -2726,6 +2783,7 @@ static struct damos *damon_sysfs_mk_scheme(
 		.weight_sz = sysfs_weights->sz,
 		.weight_nr_accesses = sysfs_weights->nr_accesses,
 		.weight_age = sysfs_weights->age,
+		.goal_tuner = sysfs_quotas->goal_tuner,
 	};
 	struct damos_watermarks wmarks = {
 		.metric = sysfs_wmarks->metric,
Signature · 1 line
2.47.3
author maintainer
#5 lore raw

RFC PATCH 4/5 Docs/mm/damon/design: document the goal-based quota tuner selections

In reply to SeongJae Park

Document the newly added goal-based quota tuner selection feature. Provide the list of the available tuner with descriptions of their behaviors and when those can be used.

---
 Documentation/mm/damon/design.rst | 12 ++++++++++++
 1 file changed, 12 insertions(+)
Documentation/mm/damon/design.rst +12 -0
index dd64f5d7f3193..28d932ceaf7ed 100644
@@ -564,6 +564,18 @@ aggressiveness (the quota) of the corresponding scheme.  For example, if DAMOS
 is under achieving the goal, DAMOS automatically increases the quota.  If DAMOS
 is over achieving the goal, it decreases the quota.
 
+There are two such tuning algorithms that users can select as they need.
+
+- ``consist``: A proportional feedback loop based algorithm.  Tries to find an
+  optimum quota that should be consistently kept, to keep achieving the goal.
+  Useful for kernel-only operation on dynamic and long-running environments.
+  This is the default selection.  If unsure, use this.
+- ``temporal``: More straightforward algorithm.  Tries to achieve the goal as
+  fast as possible, using maximum allowed quota, but only for a temporal short
+  time.  When the quota is under-achieved, this algorithm keeps tuning quota to
+  a maximum allowed one.  Once the quota is [over]-achieved, this sets the
+  quota zero.  Useful for deterministic control required environments.
+
 The goal can be specified with five parameters, namely ``target_metric``,
 ``target_value``, ``current_value``, ``nid`` and ``path``.  The auto-tuning
 mechanism tries to make ``current_value`` of ``target_metric`` be same to
Signature · 1 line
2.47.3
author maintainer
#6 lore raw

RFC PATCH 5/5 Docs/admin-guide/mm/damon/usage: document goal_tuner sysfs file

In reply to SeongJae Park

Update the DAMON usage document for the new sysfs file for the goal based quota auto-tuning, 'goal_tuner'.

---
 Documentation/admin-guide/mm/damon/usage.rst | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
Documentation/admin-guide/mm/damon/usage.rst +12 -4
index b0f3969b6b3b1..534e1199cf091 100644
@@ -83,7 +83,7 @@ comma (",").
     │ │ │ │ │ │ │ │ sz/min,max
     │ │ │ │ │ │ │ │ nr_accesses/min,max
     │ │ │ │ │ │ │ │ age/min,max
-    │ │ │ │ │ │ │ :ref:`quotas <sysfs_quotas>`/ms,bytes,reset_interval_ms,effective_bytes
+    │ │ │ │ │ │ │ :ref:`quotas <sysfs_quotas>`/ms,bytes,reset_interval_ms,effective_bytes,goal_tuner
     │ │ │ │ │ │ │ │ weights/sz_permil,nr_accesses_permil,age_permil
     │ │ │ │ │ │ │ │ :ref:`goals <sysfs_schemes_quota_goals>`/nr_goals
     │ │ │ │ │ │ │ │ │ 0/target_metric,target_value,current_value,nid,path
@@ -377,9 +377,9 @@ schemes/<N>/quotas/
 The directory for the :ref:`quotas <damon_design_damos_quotas>` of the given
 DAMON-based operation scheme.
 
-Under ``quotas`` directory, four files (``ms``, ``bytes``,
-``reset_interval_ms``, ``effective_bytes``) and two directories (``weights`` and
-``goals``) exist.
+Under ``quotas`` directory, five files (``ms``, ``bytes``,
+``reset_interval_ms``, ``effective_bytes`` and ``goal_tuner``) and two
+directories (``weights`` and ``goals``) exist.
 
 You can set the ``time quota`` in milliseconds, ``size quota`` in bytes, and
 ``reset interval`` in milliseconds by writing the values to the three files,
@@ -390,6 +390,14 @@ apply the action to only up to ``bytes`` bytes of memory regions within the
 quota limits unless at least one :ref:`goal <sysfs_schemes_quota_goals>` is
 set.
 
+You can set the goal-based effective quota auto-tuning algorithm to use, by
+writing the algorithm name to ``goal_tuner`` file.  Reading the file returns
+the currently selected tuner algorithm.  Refer to the design documentation of
+:ref:`automatic quota tuning goals <damon_design_damos_quotas_auto_tuning>` for
+the background design of the feature and the name of the selectable algorithms.
+Refer to :ref:`goals directory <sysfs_schemes_quota_goals>` for the goals
+setup.
+
 The time quota is internally transformed to a size quota.  Between the
 transformed size quota and user-specified size quota, smaller one is applied.
 Based on the user-specified :ref:`goal <sysfs_schemes_quota_goals>`, the
Signature · 1 line
2.47.3