summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/damon.h7
-rw-r--r--mm/damon/core.c25
2 files changed, 32 insertions, 0 deletions
diff --git a/include/linux/damon.h b/include/linux/damon.h
index 5a06993d8479..886d07294f4e 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -130,12 +130,14 @@ enum damos_action {
* enum damos_quota_goal_metric - Represents the metric to be used as the goal
*
* @DAMOS_QUOTA_USER_INPUT: User-input value.
+ * @DAMOS_QUOTA_SOME_MEM_PSI_US: System level some memory PSI in us.
* @NR_DAMOS_QUOTA_GOAL_METRICS: Number of DAMOS quota goal metrics.
*
* Metrics equal to larger than @NR_DAMOS_QUOTA_GOAL_METRICS are unsupported.
*/
enum damos_quota_goal_metric {
DAMOS_QUOTA_USER_INPUT,
+ DAMOS_QUOTA_SOME_MEM_PSI_US,
NR_DAMOS_QUOTA_GOAL_METRICS,
};
@@ -144,6 +146,7 @@ enum damos_quota_goal_metric {
* @metric: Metric to be used for representing the goal.
* @target_value: Target value of @metric to achieve with the tuning.
* @current_value: Current value of @metric.
+ * @last_psi_total: Last measured total PSI
* @list: List head for siblings.
*
* Data structure for getting the current score of the quota tuning goal. The
@@ -159,6 +162,10 @@ struct damos_quota_goal {
enum damos_quota_goal_metric metric;
unsigned long target_value;
unsigned long current_value;
+ /* metric-dependent fields */
+ union {
+ u64 last_psi_total;
+ };
struct list_head list;
};
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 973423166ee2..6d503c1c125e 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -11,6 +11,7 @@
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/mm.h>
+#include <linux/psi.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -1125,6 +1126,25 @@ static unsigned long damon_feed_loop_next_input(unsigned long last_input,
return min_input;
}
+#ifdef CONFIG_PSI
+
+static u64 damos_get_some_mem_psi_total(void)
+{
+ if (static_branch_likely(&psi_disabled))
+ return 0;
+ return div_u64(psi_system.total[PSI_AVGS][PSI_MEM * 2],
+ NSEC_PER_USEC);
+}
+
+#else /* CONFIG_PSI */
+
+static inline u64 damos_get_some_mem_psi_total(void)
+{
+ return 0;
+};
+
+#endif /* CONFIG_PSI */
+
static void damos_set_quota_goal_current_value(struct damos_quota_goal *goal)
{
u64 now_psi_total;
@@ -1133,6 +1153,11 @@ static void damos_set_quota_goal_current_value(struct damos_quota_goal *goal)
case DAMOS_QUOTA_USER_INPUT:
/* User should already set goal->current_value */
break;
+ case DAMOS_QUOTA_SOME_MEM_PSI_US:
+ now_psi_total = damos_get_some_mem_psi_total();
+ goal->current_value = now_psi_total - goal->last_psi_total;
+ goal->last_psi_total = now_psi_total;
+ break;
default:
break;
}