[PATCH] mm/vmscan: add tracepoint for changes in min_seq and max_seq

wangzhen posted 1 patch 13 hours ago
include/trace/events/vmscan.h | 49 +++++++++++++++++++++++++++++++++++
mm/vmscan.c                   |  6 +++++
2 files changed, 55 insertions(+)
[PATCH] mm/vmscan: add tracepoint for changes in min_seq and max_seq
Posted by wangzhen 13 hours ago
From 20f685d13826ebaa86705a689128893be6316c7b Mon Sep 17 00:00:00 2001
From: w00021541 <wangzhen5@hihonor.com>
Date: Tue, 31 Mar 2026 16:00:48 +0800
Subject: [PATCH] mm/vmscan: add tracepoint for changes in min_seq and max_seq

Currently, when tracking the changes in min_seq and max_seq of mglru,
it can only be done through debugfs. The granularity of debugfs is too
coarse when we debug the generations of mglru. there's no way to trace
the increase in min_seq and max_seq, so we add 2 tracepoints,
mm_vmscan_lru_inc_min_seq and mm_vmscan_lru_inc_max_seq.

Test results:

kswapd0-94      [003] d..1.    72.664921: mm_vmscan_lru_inc_min_seq: memcg_id=87 type=0 swappiness=140 min_seq=2
kswapd0-94      [003] d..1.    72.664922: mm_vmscan_lru_inc_min_seq: memcg_id=87 type=1 swappiness=140 min_seq=1
kswapd0-94      [003] d..1.    72.667303: mm_vmscan_lru_inc_max_seq: memcg_id=87 swappiness=140 max_seq=4
kswapd0-94      [000] d..1.    72.807691: mm_vmscan_lru_inc_min_seq: memcg_id=25 type=0 swappiness=140 min_seq=2
kswapd0-94      [000] d..1.    72.807692: mm_vmscan_lru_inc_min_seq: memcg_id=25 type=1 swappiness=140 min_seq=1
kswapd0-94      [000] d..1.    72.810955: mm_vmscan_lru_inc_max_seq: memcg_id=25 swappiness=140 max_seq=4
kswapd0-94      [005] d..1.    73.482586: mm_vmscan_lru_inc_min_seq: memcg_id=91 type=0 swappiness=140 min_seq=2
kswapd0-94      [005] d..1.    73.482588: mm_vmscan_lru_inc_min_seq: memcg_id=91 type=1 swappiness=140 min_seq=1
kswapd0-94      [005] d..1.    73.485509: mm_vmscan_lru_inc_max_seq: memcg_id=91 swappiness=140 max_seq=4
kswapd0-94      [000] d..1.    77.708630: mm_vmscan_lru_inc_min_seq: memcg_id=88 type=0 swappiness=140 min_seq=1
kswapd0-94      [000] d..1.    77.709491: mm_vmscan_lru_inc_min_seq: memcg_id=88 type=0 swappiness=140 min_seq=2
kswapd0-94      [000] d..1.    77.709491: mm_vmscan_lru_inc_min_seq: memcg_id=88 type=1 swappiness=140 min_seq=1
kswapd0-94      [000] d..1.    77.715550: mm_vmscan_lru_inc_max_seq: memcg_id=88 swappiness=140 max_seq=4
kswapd0-94      [003] d..1.    77.749288: mm_vmscan_lru_inc_min_seq: memcg_id=4 type=0 swappiness=140 min_seq=2
kswapd0-94      [003] d..1.    77.749290: mm_vmscan_lru_inc_min_seq: memcg_id=4 type=1 swappiness=140 min_seq=1
kswapd0-94      [003] d..1.    77.763055: mm_vmscan_lru_inc_max_seq: memcg_id=4 swappiness=140 max_seq=4

Signed-off-by: w00021541 <wangzhen5@hihonor.com>
---
 include/trace/events/vmscan.h | 49 +++++++++++++++++++++++++++++++++++
 mm/vmscan.c                   |  6 +++++
 2 files changed, 55 insertions(+)

diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h
index ea58e4656abf..6f2ae5c597fd 100644
--- a/include/trace/events/vmscan.h
+++ b/include/trace/events/vmscan.h
@@ -488,6 +488,55 @@ TRACE_EVENT(mm_vmscan_lru_shrink_active,
 		show_reclaim_flags(__entry->reclaim_flags))
 );
 
+#ifdef CONFIG_LRU_GEN
+TRACE_EVENT(mm_vmscan_lru_inc_min_seq,
+
+	TP_PROTO(struct mem_cgroup *memcg, int type, int swappiness, unsigned long min_seq),
+
+	TP_ARGS(memcg, type, swappiness, min_seq),
+
+	TP_STRUCT__entry(
+		__field(int, id)
+		__field(int, type)
+		__field(int, swappiness)
+		__field(unsigned long, min_seq)
+	),
+
+	TP_fast_assign(
+		__entry->id = mem_cgroup_id(memcg);
+		__entry->type = type;
+		__entry->swappiness = swappiness;
+		__entry->min_seq = min_seq;
+	),
+
+	TP_printk("memcg_id=%d type=%d swappiness=%d min_seq=%ld",
+		__entry->id, __entry->type,
+		__entry->swappiness, __entry->min_seq)
+);
+
+TRACE_EVENT(mm_vmscan_lru_inc_max_seq,
+
+	TP_PROTO(struct mem_cgroup *memcg, int swappiness, unsigned long max_seq),
+
+	TP_ARGS(memcg, swappiness, max_seq),
+
+	TP_STRUCT__entry(
+		__field(int, id)
+		__field(int, swappiness)
+		__field(unsigned long, max_seq)
+	),
+
+	TP_fast_assign(
+		__entry->id = mem_cgroup_id(memcg);
+		__entry->swappiness = swappiness;
+		__entry->max_seq = max_seq;
+	),
+
+	TP_printk("memcg_id=%d swappiness=%d max_seq=%ld",
+		__entry->id, __entry->swappiness, __entry->max_seq)
+);
+#endif /* CONFIG_LRU_GEN */
+
 TRACE_EVENT(mm_vmscan_node_reclaim_begin,
 
 	TP_PROTO(int nid, int order, gfp_t gfp_flags),
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 0fc9373e8251..6b5d21ee45ba 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3848,6 +3848,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, int swappiness)
 	int zone;
 	int remaining = MAX_LRU_BATCH;
 	struct lru_gen_folio *lrugen = &lruvec->lrugen;
+	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
 	int hist = lru_hist_from_seq(lrugen->min_seq[type]);
 	int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
 
@@ -3892,6 +3893,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, int swappiness)
 done:
 	reset_ctrl_pos(lruvec, type, true);
 	WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1);
+	trace_mm_vmscan_lru_inc_min_seq(memcg, type, swappiness, lrugen->min_seq[type]);
 
 	return true;
 }
@@ -3902,6 +3904,7 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, int swappiness)
 	bool success = false;
 	bool seq_inc_flag = false;
 	struct lru_gen_folio *lrugen = &lruvec->lrugen;
+	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
 	DEFINE_MIN_SEQ(lruvec);
 
 	VM_WARN_ON_ONCE(!seq_is_valid(lruvec));
@@ -3947,6 +3950,7 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, int swappiness)
 
 		reset_ctrl_pos(lruvec, type, true);
 		WRITE_ONCE(lrugen->min_seq[type], min_seq[type]);
+		trace_mm_vmscan_lru_inc_min_seq(memcg, type, swappiness, lrugen->min_seq[type]);
 		success = true;
 	}
 
@@ -3959,6 +3963,7 @@ static bool inc_max_seq(struct lruvec *lruvec, unsigned long seq, int swappiness
 	int prev, next;
 	int type, zone;
 	struct lru_gen_folio *lrugen = &lruvec->lrugen;
+	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
 restart:
 	if (seq < READ_ONCE(lrugen->max_seq))
 		return false;
@@ -4012,6 +4017,7 @@ static bool inc_max_seq(struct lruvec *lruvec, unsigned long seq, int swappiness
 	WRITE_ONCE(lrugen->timestamps[next], jiffies);
 	/* make sure preceding modifications appear */
 	smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1);
+	trace_mm_vmscan_lru_inc_max_seq(memcg, swappiness, lrugen->max_seq);
 unlock:
 	spin_unlock_irq(&lruvec->lru_lock);
 
-- 
2.17.1