From: Ridong Chen <[email protected]> Aging in MGLRU advances max_seq via inc_max_seq(), creating a new youngest generation. There is currently no tracepoint on this path, so the moment a new generation is created, and how the min_seq of each type trails behind it, cannot be observed as it happens.
Add mm_mglru_inc_max_seq, emitted right after max_seq is bumped, with the memcg id and the new max_seq alongside the anon and file min_seq. Paired with the mm_mglru_isolate_folios tracepoint it makes the full aging-to-eviction window observable per memcg. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Ridong Chen <[email protected]> --- include/trace/events/vmscan.h | 30 ++++++++++++++++++++++++++++++ mm/vmscan.c | 4 ++++ 2 files changed, 34 insertions(+) diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h index a0e3cf75294b..ab93c2f4b318 100644 --- a/include/trace/events/vmscan.h +++ b/include/trace/events/vmscan.h @@ -439,6 +439,36 @@ TRACE_EVENT(mm_mglru_isolate_folios, __entry->max_seq) ); +TRACE_EVENT(mm_mglru_inc_max_seq, + + TP_PROTO(u64 memcg_id, + unsigned long max_seq, + unsigned long anon_min_seq, + unsigned long file_min_seq), + + TP_ARGS(memcg_id, max_seq, anon_min_seq, file_min_seq), + + TP_STRUCT__entry( + __field(u64, memcg_id) + __field(unsigned long, max_seq) + __field(unsigned long, anon_min_seq) + __field(unsigned long, file_min_seq) + ), + + TP_fast_assign( + __entry->memcg_id = memcg_id; + __entry->max_seq = max_seq; + __entry->anon_min_seq = anon_min_seq; + __entry->file_min_seq = file_min_seq; + ), + + TP_printk("memcg_id=%llu max_seq=%lu anon_min_seq=%lu file_min_seq=%lu", + __entry->memcg_id, + __entry->max_seq, + __entry->anon_min_seq, + __entry->file_min_seq) +); + TRACE_EVENT(mm_vmscan_write_folio, TP_PROTO(struct folio *folio), diff --git a/mm/vmscan.c b/mm/vmscan.c index 771fe6827939..3c806a57d113 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -4065,6 +4065,10 @@ 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_mglru_inc_max_seq(mem_cgroup_id(lruvec_memcg(lruvec)), + lrugen->max_seq, + lrugen->min_seq[LRU_GEN_ANON], + lrugen->min_seq[LRU_GEN_FILE]); unlock: lruvec_unlock_irq(lruvec); -- 2.34.1
