[RFC PATCH v2 03/10] mm/damon/core: implement DAMOS_QUOTA_NODE_MEMCG_USED_BP

SeongJae Park posted 10 patches 2 months, 1 week ago
[RFC PATCH v2 03/10] mm/damon/core: implement DAMOS_QUOTA_NODE_MEMCG_USED_BP
Posted by SeongJae Park 2 months, 1 week ago
Implement the handling of the new DAMOS quota goal metric for per-memcg
per-node memory usage, namely DAMOS_QUOTA_NODE_MEMCG_USED_BP.  The
metric value is calculated as the sum of active/inactive anon/file pages
of the given cgroup for a given NUMA node.

Signed-off-by: SeongJae Park <sj@kernel.org>
---
 mm/damon/core.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/mm/damon/core.c b/mm/damon/core.c
index 93848b4c6944..1eacf78aa358 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -10,6 +10,7 @@
 #include <linux/damon.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/memcontrol.h>
 #include <linux/mm.h>
 #include <linux/psi.h>
 #include <linux/slab.h>
@@ -2032,12 +2033,46 @@ static __kernel_ulong_t damos_get_node_mem_bp(
 		numerator = i.freeram;
 	return numerator * 10000 / i.totalram;
 }
+
+static unsigned long damos_get_node_memcg_used_bp(
+		struct damos_quota_goal *goal)
+{
+	struct mem_cgroup *memcg;
+	struct lruvec *lruvec;
+	unsigned long used_pages;
+	struct sysinfo i;
+
+	rcu_read_lock();
+	memcg = mem_cgroup_from_id(goal->memcg_id);
+	rcu_read_unlock();
+	if (!memcg) {
+		if (goal->metric == DAMOS_QUOTA_NODE_MEMCG_USED_BP)
+			return 0;
+		else	/* DAMOS_QUOTA_NODE_MEMCG_FREE_BP */
+			return 10000;
+	}
+	mem_cgroup_flush_stats(memcg);
+	lruvec = mem_cgroup_lruvec(memcg, NODE_DATA(goal->nid));
+	used_pages = lruvec_page_state(lruvec, NR_ACTIVE_ANON);
+	used_pages += lruvec_page_state(lruvec, NR_INACTIVE_ANON);
+	used_pages += lruvec_page_state(lruvec, NR_ACTIVE_FILE);
+	used_pages += lruvec_page_state(lruvec, NR_INACTIVE_FILE);
+
+	si_meminfo_node(&i, goal->nid);
+	return used_pages * 10000 / i.totalram;
+}
 #else
 static __kernel_ulong_t damos_get_node_mem_bp(
 		struct damos_quota_goal *goal)
 {
 	return 0;
 }
+
+static unsigned long damos_get_node_memcg_used_bp(
+		struct damos_quota_goal *goal)
+{
+	return 0;
+}
 #endif
 
 
@@ -2058,6 +2093,9 @@ static void damos_set_quota_goal_current_value(struct damos_quota_goal *goal)
 	case DAMOS_QUOTA_NODE_MEM_FREE_BP:
 		goal->current_value = damos_get_node_mem_bp(goal);
 		break;
+	case DAMOS_QUOTA_NODE_MEMCG_USED_BP:
+		goal->current_value = damos_get_node_memcg_used_bp(goal);
+		break;
 	default:
 		break;
 	}
-- 
2.39.5
Re: [RFC PATCH v2 03/10] mm/damon/core: implement DAMOS_QUOTA_NODE_MEMCG_USED_BP
Posted by SeongJae Park 2 months ago
On Thu,  9 Oct 2025 14:20:35 -0700 SeongJae Park <sj@kernel.org> wrote:

> Implement the handling of the new DAMOS quota goal metric for per-memcg
> per-node memory usage, namely DAMOS_QUOTA_NODE_MEMCG_USED_BP.  The
> metric value is calculated as the sum of active/inactive anon/file pages
> of the given cgroup for a given NUMA node.
> 
> Signed-off-by: SeongJae Park <sj@kernel.org>
> ---
>  mm/damon/core.c | 38 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/mm/damon/core.c b/mm/damon/core.c
> index 93848b4c6944..1eacf78aa358 100644
> --- a/mm/damon/core.c
> +++ b/mm/damon/core.c
[...]
> @@ -2058,6 +2093,9 @@ static void damos_set_quota_goal_current_value(struct damos_quota_goal *goal)
>  	case DAMOS_QUOTA_NODE_MEM_FREE_BP:
>  		goal->current_value = damos_get_node_mem_bp(goal);
>  		break;
> +	case DAMOS_QUOTA_NODE_MEMCG_USED_BP:
> +		goal->current_value = damos_get_node_memcg_used_bp(goal);
> +		break;
>  	default:
>  		break;
>  	}
> -- 
> 2.39.5

In addition to damos_set_quota_goal_current_value(), this patch should also
update damos_commit_quota_goal_union(), like below.  I will add that on the
next spin.

--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -825,6 +825,10 @@ static void damos_commit_quota_goal_union(
        case DAMOS_QUOTA_NODE_MEM_FREE_BP:
                dst->nid = src->nid;
                break;
+       case DAMOS_QUOTA_NODE_MEMCG_USED_BP:
+               dst->nid = src->nid;
+               dst->memcg_id = src->memcg_id;
+               break;
        default:
                break;
        }


Thanks,
SJ