aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorSeongJae Park <sj@kernel.org>2024-02-19 11:44:23 -0800
committerAndrew Morton <akpm@linux-foundation.org>2024-02-23 17:48:28 -0800
commitbcce9bc16f56fbc254857fcb31674ab868b824d7 (patch)
tree121d181c945e37aa8ff3465e37f1afe3aa4efbe7 /mm
parent06ba5b309ed870cf1a0fedc611d0e7fbb6425a2d (diff)
downloadlinux-bcce9bc16f56fbc254857fcb31674ab868b824d7.tar.gz
mm/damon/core: support multiple metrics for quota goal
DAMOS quota auto-tuning asks users to assess the current tuned quota and provide the feedback in a manual and repeated way. It allows users generate the feedback from a source that the kernel cannot access, and writing a script or a function for doing the manual and repeated feeding is not a big deal. However, additional works are additional works, and it could be more efficient if DAMOS could do the fetch itself, especially in case of DAMON sysfs interface use case, since it can avoid the context switches between the user-space and the kernel-space, though the overhead would be only trivial in most cases. Also in many cases, feedbacks could be made from kernel-accessible sources, such as PSI, CPU usage, etc. Make the quota goal to support multiple types of metrics including such ones. Link: https://lkml.kernel.org/r/20240219194431.159606-13-sj@kernel.org Signed-off-by: SeongJae Park <sj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/damon/core.c22
-rw-r--r--mm/damon/sysfs-schemes.c5
2 files changed, 22 insertions, 5 deletions
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 907f467fc8c007..973423166ee28f 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -300,15 +300,16 @@ void damos_destroy_filter(struct damos_filter *f)
}
struct damos_quota_goal *damos_new_quota_goal(
- unsigned long target_value, unsigned long current_value)
+ enum damos_quota_goal_metric metric,
+ unsigned long target_value)
{
struct damos_quota_goal *goal;
goal = kmalloc(sizeof(*goal), GFP_KERNEL);
if (!goal)
return NULL;
+ goal->metric = metric;
goal->target_value = target_value;
- goal->current_value = current_value;
INIT_LIST_HEAD(&goal->list);
return goal;
}
@@ -1124,16 +1125,31 @@ static unsigned long damon_feed_loop_next_input(unsigned long last_input,
return min_input;
}
+static void damos_set_quota_goal_current_value(struct damos_quota_goal *goal)
+{
+ u64 now_psi_total;
+
+ switch (goal->metric) {
+ case DAMOS_QUOTA_USER_INPUT:
+ /* User should already set goal->current_value */
+ break;
+ default:
+ break;
+ }
+}
+
/* Return the highest score since it makes schemes least aggressive */
static unsigned long damos_quota_score(struct damos_quota *quota)
{
struct damos_quota_goal *goal;
unsigned long highest_score = 0;
- damos_for_each_quota_goal(goal, quota)
+ damos_for_each_quota_goal(goal, quota) {
+ damos_set_quota_goal_current_value(goal);
highest_score = max(highest_score,
goal->current_value * 10000 /
goal->target_value);
+ }
return highest_score;
}
diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c
index 50218a7bfa0a68..7a8a39f2679b73 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -1899,10 +1899,11 @@ static int damos_sysfs_set_quota_score(
if (!sysfs_goal->target_value)
continue;
- goal = damos_new_quota_goal(sysfs_goal->target_value,
- sysfs_goal->current_value);
+ goal = damos_new_quota_goal(DAMOS_QUOTA_USER_INPUT,
+ sysfs_goal->target_value);
if (!goal)
return -ENOMEM;
+ goal->current_value = sysfs_goal->current_value;
damos_add_quota_goal(quota, goal);
}
return 0;