Commit b74a120b authored by SeongJae Park's avatar SeongJae Park Committed by Andrew Morton
Browse files

mm/damon/core: implement DAMOS_QUOTA_NODE_MEMCG_USED_BP

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.

Link: https://lkml.kernel.org/r/20251017212706.183502-4-sj@kernel.org


Signed-off-by: default avatarSeongJae Park <sj@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 6a18bbe4
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -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>
@@ -788,6 +789,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;
	}
@@ -2035,12 +2040,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


@@ -2061,6 +2100,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;
	}