* [PATCH RFC 0/2] mm/mglru: add tracepoints for aging and isolation
@ 2026-09-07 4:24 Ridong Chen
2026-09-07 4:24 ` [PATCH RFC 1/2] mm/mglru: add tracepoint for folio isolation Ridong Chen
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Ridong Chen @ 2026-09-07 4:24 UTC (permalink / raw)
To: Steven Rostedt, Masami Hiramatsu, Andrew Morton, Johannes Weiner
Cc: Mathieu Desnoyers, David Hildenbrand, Michal Hocko, Qi Zheng,
Shakeel Butt, Lorenzo Stoakes, Kairui Song, Barry Song,
Axel Rasmussen, Yuanchu Xie, Wei Xu, linux-kernel,
linux-trace-kernel, linux-mm, Ridong Chen, Ridong Chen
From: Ridong Chen <chenridong@xiaomi.com>
MGLRU currently has no tracepoints of its own. The scan and evict paths
reuse the classic-LRU tracepoints (trace_mm_vmscan_lru_isolate() and
trace_mm_vmscan_lru_shrink_inactive()), which predate MGLRU and carry no
generation, sequence, memcg or swappiness context. A trace of a running
system therefore cannot tell which memcg a given scan/evict belongs to,
how far reclaim has progressed through the generations, or when a new
generation is created - so how MGLRU actually operates is effectively
invisible.
Add two tracepoints on the two paths that define an MGLRU cycle:
- mm_mglru_isolate_folios, on the isolation (eviction) path, carrying
the memcg id, the type scanned, the effective swappiness, the
scanned/isolated counts, and the anon/file min_seq and max_seq.
- mm_mglru_inc_max_seq, on the aging path, emitted when a new youngest
generation is created, carrying the memcg id, the new max_seq, and
the anon/file min_seq.
Both live at MGLRU-specific layers with no classic-LRU counterpart, so
they neither change nor duplicate the existing tracepoints. Paired, they
make the full aging-to-eviction window observable per memcg: aging
advances max_seq (the leading edge), isolation consumes the oldest
generations, and the min_seq/max_seq pair on each event shows how the
generation window moves over time.
A sample trace, with the classic-LRU tracepoints left enabled to show
how they interleave:
mm_mglru_inc_max_seq: memcg_id=1085 max_seq=7 anon_min_seq=4 file_min_seq=5
mm_vmscan_lru_isolate: classzone=4 order=0 nr_requested=17 nr_scanned=17 nr_skipped=0 nr_taken=0 lru=inactive_file
mm_vmscan_lru_isolate: classzone=4 order=0 nr_requested=17 nr_scanned=17 nr_skipped=0 nr_taken=0 lru=inactive_file
mm_mglru_isolate_folios: memcg_id=1085 type=file swappiness=0 nr_scanned=34 nr_isolated=0 anon_min_seq=4 file_min_seq=5 max_seq=7
mm_vmscan_lru_isolate: classzone=4 order=0 nr_requested=64 nr_scanned=64 nr_skipped=0 nr_taken=21 lru=inactive_file
mm_mglru_isolate_folios: memcg_id=73 type=file swappiness=0 nr_scanned=64 nr_isolated=21 anon_min_seq=7 file_min_seq=8 max_seq=10
mm_vmscan_lru_shrink_inactive: nid=0 nr_scanned=64 nr_reclaimed=21 nr_dirty=0 nr_writeback=0 nr_congested=0 nr_immediate=0 nr_activate_anon=0 nr_activate_file=0 nr_ref_keep=0 nr_unmap_fail=0 priority=4 flags=RECLAIM_WB_FILE|RECLAIM_WB_ASYNC
mm_mglru_inc_max_seq: memcg_id=73 max_seq=11 anon_min_seq=8 file_min_seq=8
mm_vmscan_lru_isolate: classzone=4 order=0 nr_requested=64 nr_scanned=10 nr_skipped=0 nr_taken=10 lru=inactive_file
mm_mglru_isolate_folios: memcg_id=73 type=file swappiness=0 nr_scanned=10 nr_isolated=10 anon_min_seq=8 file_min_seq=8 max_seq=11
mm_vmscan_lru_shrink_inactive: nid=0 nr_scanned=10 nr_reclaimed=7 nr_dirty=0 nr_writeback=0 nr_congested=0 nr_immediate=0 nr_activate_anon=0 nr_activate_file=3 nr_ref_keep=0 nr_unmap_fail=0 priority=4 flags=RECLAIM_WB_FILE|RECLAIM_WB_ASYNC
The two mm_mglru_isolate_folios lines tell memcg 1085 and memcg 73
apart, and show one making no progress (nr_isolated=0 against min_seq=4/5)
while the other evicts and then ages (max_seq 10 -> 11, min_seq catching
up to 8). The bare mm_vmscan_lru_isolate lines above carry none of that
context - they cannot even say which memcg they came from.
Sent as RFC to get feedback on the choice of tracepoint sites and fields
before proposing them as stable ABI.
Ridong Chen (2):
mm/mglru: add tracepoint for folio isolation
mm/mglru: add tracepoint for inc_max_seq
include/trace/events/vmscan.h | 77 +++++++++++++++++++++++++++++++++++
mm/vmscan.c | 13 +++++-
2 files changed, 89 insertions(+), 1 deletion(-)
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH RFC 1/2] mm/mglru: add tracepoint for folio isolation 2026-09-07 4:24 [PATCH RFC 0/2] mm/mglru: add tracepoints for aging and isolation Ridong Chen @ 2026-09-07 4:24 ` Ridong Chen 2026-09-09 6:40 ` Barry Song 2026-09-07 4:24 ` [PATCH RFC 2/2] mm/mglru: add tracepoint for inc_max_seq Ridong Chen 2026-09-08 13:45 ` [PATCH RFC 0/2] mm/mglru: add tracepoints for aging and isolation Steven Rostedt 2 siblings, 1 reply; 11+ messages in thread From: Ridong Chen @ 2026-09-07 4:24 UTC (permalink / raw) To: Steven Rostedt, Masami Hiramatsu, Andrew Morton, Johannes Weiner Cc: Mathieu Desnoyers, David Hildenbrand, Michal Hocko, Qi Zheng, Shakeel Butt, Lorenzo Stoakes, Kairui Song, Barry Song, Axel Rasmussen, Yuanchu Xie, Wei Xu, linux-kernel, linux-trace-kernel, linux-mm, Ridong Chen, Ridong Chen From: Ridong Chen <chenridong@xiaomi.com> MGLRU's scan_folios() and evict_folios() emit the classic-LRU tracepoints trace_mm_vmscan_lru_isolate() and trace_mm_vmscan_lru_shrink_inactive(). Those predate MGLRU and are indistinguishable from the classic-LRU path: they carry no generation, sequence, memcg or swappiness context, so a trace of an MGLRU run cannot tell which memcg a given scan/evict belongs to, nor how far reclaim has progressed through the generations. Add mm_mglru_isolate_folios, emitted once per isolate_folios() call with the memcg id, the type actually scanned, the effective swappiness, the scanned/isolated counts, and the anon/file min_seq and max_seq. The min_seq/max_seq triplet ties each isolation to the generation layout it ran against, which the classic-LRU tracepoints cannot express. This is emitted at the isolate_folios() layer, which is MGLRU-specific and has no classic-LRU counterpart, so it neither changes nor duplicates the existing scan/evict tracepoints. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Ridong Chen <chenridong@xiaomi.com> --- include/trace/events/vmscan.h | 47 +++++++++++++++++++++++++++++++++++ mm/vmscan.c | 9 ++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h index 8a872990b4be..a0e3cf75294b 100644 --- a/include/trace/events/vmscan.h +++ b/include/trace/events/vmscan.h @@ -392,6 +392,53 @@ TRACE_EVENT(mm_vmscan_lru_isolate, __print_symbolic(__entry->lru, LRU_NAMES)) ); +TRACE_EVENT(mm_mglru_isolate_folios, + + TP_PROTO(u64 memcg_id, + int type, + int swappiness, + unsigned long nr_scanned, + unsigned long nr_isolated, + unsigned long anon_min_seq, + unsigned long file_min_seq, + unsigned long max_seq), + + TP_ARGS(memcg_id, type, swappiness, nr_scanned, nr_isolated, + anon_min_seq, file_min_seq, max_seq), + + TP_STRUCT__entry( + __field(u64, memcg_id) + __field(int, type) + __field(int, swappiness) + __field(unsigned long, nr_scanned) + __field(unsigned long, nr_isolated) + __field(unsigned long, anon_min_seq) + __field(unsigned long, file_min_seq) + __field(unsigned long, max_seq) + ), + + TP_fast_assign( + __entry->memcg_id = memcg_id; + __entry->type = type; + __entry->swappiness = swappiness; + __entry->nr_scanned = nr_scanned; + __entry->nr_isolated = nr_isolated; + __entry->anon_min_seq = anon_min_seq; + __entry->file_min_seq = file_min_seq; + __entry->max_seq = max_seq; + ), + + TP_printk("memcg_id=%llu type=%s swappiness=%d nr_scanned=%lu nr_isolated=%lu anon_min_seq=%lu file_min_seq=%lu max_seq=%lu", + __entry->memcg_id, + __entry->type ? "file" : "anon", + __entry->swappiness, + __entry->nr_scanned, + __entry->nr_isolated, + __entry->anon_min_seq, + __entry->file_min_seq, + __entry->max_seq) +); + TRACE_EVENT(mm_vmscan_write_folio, TP_PROTO(struct folio *folio), diff --git a/mm/vmscan.c b/mm/vmscan.c index 8409ea4bbf37..771fe6827939 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -4843,6 +4843,7 @@ static int isolate_folios(unsigned long nr_to_scan, struct lruvec *lruvec, bool type_fallback_allowed = !is_single_type_reclaim(swappiness); int type = get_type_to_scan(lruvec, swappiness); int total_scanned = 0, scanned, tier; + struct lru_gen_folio *lrugen = &lruvec->lrugen; bool tried = false; retry: @@ -4854,7 +4855,7 @@ static int isolate_folios(unsigned long nr_to_scan, struct lruvec *lruvec, if (*isolated) { *isolate_type = type; *isolate_scanned = scanned; - return total_scanned; + goto done; } /* @@ -4876,6 +4877,12 @@ static int isolate_folios(unsigned long nr_to_scan, struct lruvec *lruvec, goto retry; } +done: + trace_mm_mglru_isolate_folios(mem_cgroup_id(lruvec_memcg(lruvec)), + type, swappiness, total_scanned, *isolated, + lrugen->min_seq[LRU_GEN_ANON], + lrugen->min_seq[LRU_GEN_FILE], + lrugen->max_seq); return total_scanned; } -- 2.34.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH RFC 1/2] mm/mglru: add tracepoint for folio isolation 2026-09-07 4:24 ` [PATCH RFC 1/2] mm/mglru: add tracepoint for folio isolation Ridong Chen @ 2026-09-09 6:40 ` Barry Song 2026-09-09 12:00 ` Ridong Chen 0 siblings, 1 reply; 11+ messages in thread From: Barry Song @ 2026-09-09 6:40 UTC (permalink / raw) To: Ridong Chen Cc: Steven Rostedt, Masami Hiramatsu, Andrew Morton, Johannes Weiner, Mathieu Desnoyers, David Hildenbrand, Michal Hocko, Qi Zheng, Shakeel Butt, Lorenzo Stoakes, Kairui Song, Axel Rasmussen, Yuanchu Xie, Wei Xu, linux-kernel, linux-trace-kernel, linux-mm, Ridong Chen On Mon, Sep 7, 2026 at 12:25 PM Ridong Chen <ridong.chen@linux.dev> wrote: > > From: Ridong Chen <chenridong@xiaomi.com> > > MGLRU's scan_folios() and evict_folios() emit the classic-LRU > tracepoints trace_mm_vmscan_lru_isolate() and > trace_mm_vmscan_lru_shrink_inactive(). Those predate MGLRU and are > indistinguishable from the classic-LRU path: they carry no generation, > sequence, memcg or swappiness context, so a trace of an MGLRU run cannot > tell which memcg a given scan/evict belongs to, nor how far reclaim has > progressed through the generations. > > Add mm_mglru_isolate_folios, emitted once per isolate_folios() call with > the memcg id, the type actually scanned, the effective swappiness, the > scanned/isolated counts, and the anon/file min_seq and max_seq. The > min_seq/max_seq triplet ties each isolation to the generation layout it > ran against, which the classic-LRU tracepoints cannot express. > > This is emitted at the isolate_folios() layer, which is MGLRU-specific > and has no classic-LRU counterpart, so it neither changes nor duplicates > the existing scan/evict tracepoints. > I have no objection to MGLRU having some tracepoints. However, one major concern is that the code is changing rapidly, so the tracepoints may not be stable. We would need to maintain them as the code evolves. > Assisted-by: Claude:claude-opus-4-8 > Signed-off-by: Ridong Chen <chenridong@xiaomi.com> > --- > include/trace/events/vmscan.h | 47 +++++++++++++++++++++++++++++++++++ > mm/vmscan.c | 9 ++++++- > 2 files changed, 55 insertions(+), 1 deletion(-) > [...] > diff --git a/mm/vmscan.c b/mm/vmscan.c > index 8409ea4bbf37..771fe6827939 100644 > --- a/mm/vmscan.c > +++ b/mm/vmscan.c [...] > @@ -4876,6 +4877,12 @@ static int isolate_folios(unsigned long nr_to_scan, struct lruvec *lruvec, > goto retry; > } > > +done: > + trace_mm_mglru_isolate_folios(mem_cgroup_id(lruvec_memcg(lruvec)), > + type, swappiness, total_scanned, *isolated, > + lrugen->min_seq[LRU_GEN_ANON], > + lrugen->min_seq[LRU_GEN_FILE], > + lrugen->max_seq); Maybe `scan_folios()` would be a better place for this, as it can more directly reflect what we're doing for each type. > return total_scanned; > } > Best Regards Barry ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH RFC 1/2] mm/mglru: add tracepoint for folio isolation 2026-09-09 6:40 ` Barry Song @ 2026-09-09 12:00 ` Ridong Chen 2026-09-09 12:11 ` Barry Song 0 siblings, 1 reply; 11+ messages in thread From: Ridong Chen @ 2026-09-09 12:00 UTC (permalink / raw) To: Barry Song Cc: Steven Rostedt, Masami Hiramatsu, Andrew Morton, Johannes Weiner, Mathieu Desnoyers, David Hildenbrand, Michal Hocko, Qi Zheng, Shakeel Butt, Lorenzo Stoakes, Kairui Song, Axel Rasmussen, Yuanchu Xie, Wei Xu, linux-kernel, linux-trace-kernel, linux-mm, Ridong Chen On 9/9/2026 2:40 PM, Barry Song wrote: > On Mon, Sep 7, 2026 at 12:25 PM Ridong Chen <ridong.chen@linux.dev> wrote: >> >> From: Ridong Chen <chenridong@xiaomi.com> >> >> MGLRU's scan_folios() and evict_folios() emit the classic-LRU >> tracepoints trace_mm_vmscan_lru_isolate() and >> trace_mm_vmscan_lru_shrink_inactive(). Those predate MGLRU and are >> indistinguishable from the classic-LRU path: they carry no generation, >> sequence, memcg or swappiness context, so a trace of an MGLRU run cannot >> tell which memcg a given scan/evict belongs to, nor how far reclaim has >> progressed through the generations. >> >> Add mm_mglru_isolate_folios, emitted once per isolate_folios() call with >> the memcg id, the type actually scanned, the effective swappiness, the >> scanned/isolated counts, and the anon/file min_seq and max_seq. The >> min_seq/max_seq triplet ties each isolation to the generation layout it >> ran against, which the classic-LRU tracepoints cannot express. >> >> This is emitted at the isolate_folios() layer, which is MGLRU-specific >> and has no classic-LRU counterpart, so it neither changes nor duplicates >> the existing scan/evict tracepoints. >> > > I have no objection to MGLRU having some tracepoints. However, one > major concern is that the code is changing rapidly, so the tracepoints > may not be stable. We would need to maintain them as the code evolves. > Indeed. GEN-LRU has been available for several years now, and many vendors are already using it, so adding tracepoints is a necessary step. >> Assisted-by: Claude:claude-opus-4-8 >> Signed-off-by: Ridong Chen <chenridong@xiaomi.com> >> --- >> include/trace/events/vmscan.h | 47 +++++++++++++++++++++++++++++++++++ >> mm/vmscan.c | 9 ++++++- >> 2 files changed, 55 insertions(+), 1 deletion(-) >> > [...] >> diff --git a/mm/vmscan.c b/mm/vmscan.c >> index 8409ea4bbf37..771fe6827939 100644 >> --- a/mm/vmscan.c >> +++ b/mm/vmscan.c > [...] >> @@ -4876,6 +4877,12 @@ static int isolate_folios(unsigned long nr_to_scan, struct lruvec *lruvec, >> goto retry; >> } >> >> +done: >> + trace_mm_mglru_isolate_folios(mem_cgroup_id(lruvec_memcg(lruvec)), >> + type, swappiness, total_scanned, *isolated, >> + lrugen->min_seq[LRU_GEN_ANON], >> + lrugen->min_seq[LRU_GEN_FILE], >> + lrugen->max_seq); > > Maybe `scan_folios()` would be a better place for this, as it can more > directly reflect what we're doing for each type. > scan_folios() already contains the trace_mm_vmscan_lru_isolate tracepoint(traditional tracepoint), but it lacks any GEN-LRU-specific information. Adding another tracepoint there would be redundant. Therefore, I placed the new tracepoint in isolate_folios(), where it can capture GEN-LRU's specific details. Additionally, it can indicate whether a fallback to the other type has occurred. > >> return total_scanned; >> } >> > > Best Regards > Barry -- Best regards Ridong ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH RFC 1/2] mm/mglru: add tracepoint for folio isolation 2026-09-09 12:00 ` Ridong Chen @ 2026-09-09 12:11 ` Barry Song 2026-09-09 12:41 ` Ridong Chen 0 siblings, 1 reply; 11+ messages in thread From: Barry Song @ 2026-09-09 12:11 UTC (permalink / raw) To: Ridong Chen Cc: Steven Rostedt, Masami Hiramatsu, Andrew Morton, Johannes Weiner, Mathieu Desnoyers, David Hildenbrand, Michal Hocko, Qi Zheng, Shakeel Butt, Lorenzo Stoakes, Kairui Song, Axel Rasmussen, Yuanchu Xie, Wei Xu, linux-kernel, linux-trace-kernel, linux-mm, Ridong Chen On Wed, Sep 9, 2026 at 8:00 PM Ridong Chen <ridong.chen@linux.dev> wrote: > > > > On 9/9/2026 2:40 PM, Barry Song wrote: > > On Mon, Sep 7, 2026 at 12:25 PM Ridong Chen <ridong.chen@linux.dev> wrote: > >> > >> From: Ridong Chen <chenridong@xiaomi.com> > >> > >> MGLRU's scan_folios() and evict_folios() emit the classic-LRU > >> tracepoints trace_mm_vmscan_lru_isolate() and > >> trace_mm_vmscan_lru_shrink_inactive(). Those predate MGLRU and are > >> indistinguishable from the classic-LRU path: they carry no generation, > >> sequence, memcg or swappiness context, so a trace of an MGLRU run cannot > >> tell which memcg a given scan/evict belongs to, nor how far reclaim has > >> progressed through the generations. > >> > >> Add mm_mglru_isolate_folios, emitted once per isolate_folios() call with > >> the memcg id, the type actually scanned, the effective swappiness, the > >> scanned/isolated counts, and the anon/file min_seq and max_seq. The > >> min_seq/max_seq triplet ties each isolation to the generation layout it > >> ran against, which the classic-LRU tracepoints cannot express. > >> > >> This is emitted at the isolate_folios() layer, which is MGLRU-specific > >> and has no classic-LRU counterpart, so it neither changes nor duplicates > >> the existing scan/evict tracepoints. > >> > > > > I have no objection to MGLRU having some tracepoints. However, one > > major concern is that the code is changing rapidly, so the tracepoints > > may not be stable. We would need to maintain them as the code evolves. > > > > Indeed. GEN-LRU has been available for several years now, and many vendors are > already using it, so adding tracepoints is a necessary step. > > >> Assisted-by: Claude:claude-opus-4-8 > >> Signed-off-by: Ridong Chen <chenridong@xiaomi.com> > >> --- > >> include/trace/events/vmscan.h | 47 +++++++++++++++++++++++++++++++++++ > >> mm/vmscan.c | 9 ++++++- > >> 2 files changed, 55 insertions(+), 1 deletion(-) > >> > > [...] > >> diff --git a/mm/vmscan.c b/mm/vmscan.c > >> index 8409ea4bbf37..771fe6827939 100644 > >> --- a/mm/vmscan.c > >> +++ b/mm/vmscan.c > > [...] > >> @@ -4876,6 +4877,12 @@ static int isolate_folios(unsigned long nr_to_scan, struct lruvec *lruvec, > >> goto retry; > >> } > >> > >> +done: > >> + trace_mm_mglru_isolate_folios(mem_cgroup_id(lruvec_memcg(lruvec)), > >> + type, swappiness, total_scanned, *isolated, > >> + lrugen->min_seq[LRU_GEN_ANON], > >> + lrugen->min_seq[LRU_GEN_FILE], > >> + lrugen->max_seq); > > > > Maybe `scan_folios()` would be a better place for this, as it can more > > directly reflect what we're doing for each type. > > > > scan_folios() already contains the trace_mm_vmscan_lru_isolate > tracepoint(traditional tracepoint), but it lacks any GEN-LRU-specific > information. Adding another tracepoint there would be redundant. Therefore, I > placed the new tracepoint in isolate_folios(), where it can capture GEN-LRU's > specific details. Additionally, it can indicate whether a fallback to the other > type has occurred. if `trace_mm_vmscan_lru_isolate` is located in `scan_folios()`, that would be strong evidence that `scan_folios()` is a better place for adding a new tracepoint for LRU gen. There is no need to avoid this location just because we already have a tracepoint here. In fact, I think this is evidence that it is a better place, not the opposite. BTW, `isolate_folios()` might be deleted soon, depending on how we improve MGLRU and on some ongoing work from Kairui. But `scan_folios()` should be long-lived, as we need to scan folios in any case. Therefore, adding tracepoints to `isolate_folios()` doesn't seem to be related to the stable ABI concern mentioned in your cover letter. Best Regards Barry ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH RFC 1/2] mm/mglru: add tracepoint for folio isolation 2026-09-09 12:11 ` Barry Song @ 2026-09-09 12:41 ` Ridong Chen 0 siblings, 0 replies; 11+ messages in thread From: Ridong Chen @ 2026-09-09 12:41 UTC (permalink / raw) To: Barry Song Cc: Steven Rostedt, Masami Hiramatsu, Andrew Morton, Johannes Weiner, Mathieu Desnoyers, David Hildenbrand, Michal Hocko, Qi Zheng, Shakeel Butt, Lorenzo Stoakes, Kairui Song, Axel Rasmussen, Yuanchu Xie, Wei Xu, linux-kernel, linux-trace-kernel, linux-mm, Ridong Chen On 9/9/2026 8:11 PM, Barry Song wrote: > On Wed, Sep 9, 2026 at 8:00 PM Ridong Chen <ridong.chen@linux.dev> wrote: >> >> >> >> On 9/9/2026 2:40 PM, Barry Song wrote: >>> On Mon, Sep 7, 2026 at 12:25 PM Ridong Chen <ridong.chen@linux.dev> wrote: >>>> >>>> From: Ridong Chen <chenridong@xiaomi.com> >>>> >>>> MGLRU's scan_folios() and evict_folios() emit the classic-LRU >>>> tracepoints trace_mm_vmscan_lru_isolate() and >>>> trace_mm_vmscan_lru_shrink_inactive(). Those predate MGLRU and are >>>> indistinguishable from the classic-LRU path: they carry no generation, >>>> sequence, memcg or swappiness context, so a trace of an MGLRU run cannot >>>> tell which memcg a given scan/evict belongs to, nor how far reclaim has >>>> progressed through the generations. >>>> >>>> Add mm_mglru_isolate_folios, emitted once per isolate_folios() call with >>>> the memcg id, the type actually scanned, the effective swappiness, the >>>> scanned/isolated counts, and the anon/file min_seq and max_seq. The >>>> min_seq/max_seq triplet ties each isolation to the generation layout it >>>> ran against, which the classic-LRU tracepoints cannot express. >>>> >>>> This is emitted at the isolate_folios() layer, which is MGLRU-specific >>>> and has no classic-LRU counterpart, so it neither changes nor duplicates >>>> the existing scan/evict tracepoints. >>>> >>> >>> I have no objection to MGLRU having some tracepoints. However, one >>> major concern is that the code is changing rapidly, so the tracepoints >>> may not be stable. We would need to maintain them as the code evolves. >>> >> >> Indeed. GEN-LRU has been available for several years now, and many vendors are >> already using it, so adding tracepoints is a necessary step. >> >>>> Assisted-by: Claude:claude-opus-4-8 >>>> Signed-off-by: Ridong Chen <chenridong@xiaomi.com> >>>> --- >>>> include/trace/events/vmscan.h | 47 +++++++++++++++++++++++++++++++++++ >>>> mm/vmscan.c | 9 ++++++- >>>> 2 files changed, 55 insertions(+), 1 deletion(-) >>>> >>> [...] >>>> diff --git a/mm/vmscan.c b/mm/vmscan.c >>>> index 8409ea4bbf37..771fe6827939 100644 >>>> --- a/mm/vmscan.c >>>> +++ b/mm/vmscan.c >>> [...] >>>> @@ -4876,6 +4877,12 @@ static int isolate_folios(unsigned long nr_to_scan, struct lruvec *lruvec, >>>> goto retry; >>>> } >>>> >>>> +done: >>>> + trace_mm_mglru_isolate_folios(mem_cgroup_id(lruvec_memcg(lruvec)), >>>> + type, swappiness, total_scanned, *isolated, >>>> + lrugen->min_seq[LRU_GEN_ANON], >>>> + lrugen->min_seq[LRU_GEN_FILE], >>>> + lrugen->max_seq); >>> >>> Maybe `scan_folios()` would be a better place for this, as it can more >>> directly reflect what we're doing for each type. >>> >> >> scan_folios() already contains the trace_mm_vmscan_lru_isolate >> tracepoint(traditional tracepoint), but it lacks any GEN-LRU-specific >> information. Adding another tracepoint there would be redundant. Therefore, I >> placed the new tracepoint in isolate_folios(), where it can capture GEN-LRU's >> specific details. Additionally, it can indicate whether a fallback to the other >> type has occurred. > > if `trace_mm_vmscan_lru_isolate` is located in `scan_folios()`, that > would be strong evidence that `scan_folios()` is a better place for > adding a new tracepoint for LRU gen. > > There is no need to avoid this location just because we already have a > tracepoint here. In fact, I think this is evidence that it is a better > place, not the opposite. > Good point. Thank you very much, that does make sense. > BTW, `isolate_folios()` might be deleted soon, depending on how we > improve MGLRU and on some ongoing work from Kairui. But `scan_folios()` > should be long-lived, as we need to scan folios in any case. Therefore, > adding tracepoints to `isolate_folios()` doesn't seem to be related to > the stable ABI concern mentioned in your cover letter. > > Best Regards > Barry -- Best regards Ridong ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH RFC 2/2] mm/mglru: add tracepoint for inc_max_seq 2026-09-07 4:24 [PATCH RFC 0/2] mm/mglru: add tracepoints for aging and isolation Ridong Chen 2026-09-07 4:24 ` [PATCH RFC 1/2] mm/mglru: add tracepoint for folio isolation Ridong Chen @ 2026-09-07 4:24 ` Ridong Chen 2026-09-09 6:45 ` Barry Song 2026-09-08 13:45 ` [PATCH RFC 0/2] mm/mglru: add tracepoints for aging and isolation Steven Rostedt 2 siblings, 1 reply; 11+ messages in thread From: Ridong Chen @ 2026-09-07 4:24 UTC (permalink / raw) To: Steven Rostedt, Masami Hiramatsu, Andrew Morton, Johannes Weiner Cc: Mathieu Desnoyers, David Hildenbrand, Michal Hocko, Qi Zheng, Shakeel Butt, Lorenzo Stoakes, Kairui Song, Barry Song, Axel Rasmussen, Yuanchu Xie, Wei Xu, linux-kernel, linux-trace-kernel, linux-mm, Ridong Chen, Ridong Chen From: Ridong Chen <chenridong@xiaomi.com> 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 <chenridong@xiaomi.com> --- 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 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH RFC 2/2] mm/mglru: add tracepoint for inc_max_seq 2026-09-07 4:24 ` [PATCH RFC 2/2] mm/mglru: add tracepoint for inc_max_seq Ridong Chen @ 2026-09-09 6:45 ` Barry Song 2026-09-09 12:43 ` Ridong Chen 0 siblings, 1 reply; 11+ messages in thread From: Barry Song @ 2026-09-09 6:45 UTC (permalink / raw) To: Ridong Chen Cc: Steven Rostedt, Masami Hiramatsu, Andrew Morton, Johannes Weiner, Mathieu Desnoyers, David Hildenbrand, Michal Hocko, Qi Zheng, Shakeel Butt, Lorenzo Stoakes, Kairui Song, Axel Rasmussen, Yuanchu Xie, Wei Xu, linux-kernel, linux-trace-kernel, linux-mm, Ridong Chen On Mon, Sep 7, 2026 at 12:25 PM Ridong Chen <ridong.chen@linux.dev> wrote: > > From: Ridong Chen <chenridong@xiaomi.com> > > 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 <chenridong@xiaomi.com> > --- > 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]); I suspect we also want to know the number of pages in each generation, similar to: /sys/kernel/debug # cat lru_gen memcg 1 / node 0 0 25672 0 85 1 25672 0 4249 2 25672 21 0 3 25672 0 0 memcg 19 /A node 0 0 23036 0 0 1 23036 0 0 2 23036 0 0 3 23036 0 0 Best Regards Barry ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH RFC 2/2] mm/mglru: add tracepoint for inc_max_seq 2026-09-09 6:45 ` Barry Song @ 2026-09-09 12:43 ` Ridong Chen 0 siblings, 0 replies; 11+ messages in thread From: Ridong Chen @ 2026-09-09 12:43 UTC (permalink / raw) To: Barry Song Cc: Steven Rostedt, Masami Hiramatsu, Andrew Morton, Johannes Weiner, Mathieu Desnoyers, David Hildenbrand, Michal Hocko, Qi Zheng, Shakeel Butt, Lorenzo Stoakes, Kairui Song, Axel Rasmussen, Yuanchu Xie, Wei Xu, linux-kernel, linux-trace-kernel, linux-mm, Ridong Chen On 9/9/2026 2:45 PM, Barry Song wrote: > On Mon, Sep 7, 2026 at 12:25 PM Ridong Chen <ridong.chen@linux.dev> wrote: >> >> From: Ridong Chen <chenridong@xiaomi.com> >> >> 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 <chenridong@xiaomi.com> >> --- >> 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]); > > I suspect we also want to know the number of pages in each generation, > similar to: > > /sys/kernel/debug # cat lru_gen > memcg 1 / > node 0 > 0 25672 0 85 > 1 25672 0 4249 > 2 25672 21 0 > 3 25672 0 0 > memcg 19 /A > node 0 > 0 23036 0 0 > 1 23036 0 0 > 2 23036 0 0 > 3 23036 0 0 > Thanks. Will add. -- Best regards Ridong ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH RFC 0/2] mm/mglru: add tracepoints for aging and isolation 2026-09-07 4:24 [PATCH RFC 0/2] mm/mglru: add tracepoints for aging and isolation Ridong Chen 2026-09-07 4:24 ` [PATCH RFC 1/2] mm/mglru: add tracepoint for folio isolation Ridong Chen 2026-09-07 4:24 ` [PATCH RFC 2/2] mm/mglru: add tracepoint for inc_max_seq Ridong Chen @ 2026-09-08 13:45 ` Steven Rostedt 2026-09-09 11:37 ` Ridong Chen 2 siblings, 1 reply; 11+ messages in thread From: Steven Rostedt @ 2026-09-08 13:45 UTC (permalink / raw) To: Ridong Chen Cc: Masami Hiramatsu, Andrew Morton, Johannes Weiner, Mathieu Desnoyers, David Hildenbrand, Michal Hocko, Qi Zheng, Shakeel Butt, Lorenzo Stoakes, Kairui Song, Barry Song, Axel Rasmussen, Yuanchu Xie, Wei Xu, linux-kernel, linux-trace-kernel, linux-mm, Ridong Chen On Mon, 7 Sep 2026 12:24:45 +0800 Ridong Chen <ridong.chen@linux.dev> wrote: > Sent as RFC to get feedback on the choice of tracepoint sites and fields > before proposing them as stable ABI. I'll let the MM maintainers determine the above. From a tracing POV, they are simple trace events. Acked-by: Steven Rostedt <rostedt@goodmis.org> -- Steve ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH RFC 0/2] mm/mglru: add tracepoints for aging and isolation 2026-09-08 13:45 ` [PATCH RFC 0/2] mm/mglru: add tracepoints for aging and isolation Steven Rostedt @ 2026-09-09 11:37 ` Ridong Chen 0 siblings, 0 replies; 11+ messages in thread From: Ridong Chen @ 2026-09-09 11:37 UTC (permalink / raw) To: Steven Rostedt Cc: Masami Hiramatsu, Andrew Morton, Johannes Weiner, Mathieu Desnoyers, David Hildenbrand, Michal Hocko, Qi Zheng, Shakeel Butt, Lorenzo Stoakes, Kairui Song, Barry Song, Axel Rasmussen, Yuanchu Xie, Wei Xu, linux-kernel, linux-trace-kernel, linux-mm, Ridong Chen On 9/8/2026 9:45 PM, Steven Rostedt wrote: > On Mon, 7 Sep 2026 12:24:45 +0800 > Ridong Chen <ridong.chen@linux.dev> wrote: > >> Sent as RFC to get feedback on the choice of tracepoint sites and fields >> before proposing them as stable ABI. > > I'll let the MM maintainers determine the above. From a tracing POV, they > are simple trace events. > > Acked-by: Steven Rostedt <rostedt@goodmis.org> > > -- Steve Thanks. -- Best regards Ridong ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-09-09 12:43 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-07 4:24 [PATCH RFC 0/2] mm/mglru: add tracepoints for aging and isolation Ridong Chen 2026-09-07 4:24 ` [PATCH RFC 1/2] mm/mglru: add tracepoint for folio isolation Ridong Chen 2026-09-09 6:40 ` Barry Song 2026-09-09 12:00 ` Ridong Chen 2026-09-09 12:11 ` Barry Song 2026-09-09 12:41 ` Ridong Chen 2026-09-07 4:24 ` [PATCH RFC 2/2] mm/mglru: add tracepoint for inc_max_seq Ridong Chen 2026-09-09 6:45 ` Barry Song 2026-09-09 12:43 ` Ridong Chen 2026-09-08 13:45 ` [PATCH RFC 0/2] mm/mglru: add tracepoints for aging and isolation Steven Rostedt 2026-09-09 11:37 ` Ridong Chen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).