From: Baoquan He <baoquan.he@linux.dev>
To: Ridong Chen <ridong.chen@linux.dev>
Cc: Barry Song <baohua@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Johannes Weiner <hannes@cmpxchg.org>,
Steven Rostedt <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Roman Gushchin <roman.gushchin@linux.dev>,
Dave Chinner <david@fromorbit.com>,
David Hildenbrand <david@kernel.org>,
Michal Hocko <mhocko@kernel.org>, Qi Zheng <qi.zheng@linux.dev>,
Shakeel Butt <shakeel.butt@linux.dev>,
Lorenzo Stoakes <ljs@kernel.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Muchun Song <muchun.song@linux.dev>,
Kairui Song <kasong@tencent.com>,
Axel Rasmussen <axelrasmussen@google.com>,
Yuanchu Xie <yuanchu@google.com>, Wei Xu <weixugc@google.com>,
Baolin Wang <baolin.wang@linux.alibaba.com>,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
linux-trace-kernel@vger.kernel.org,
"open list:CONTROL GROUP - MEMORY RESOURCE CONTROLLER (MEMCG)"
<cgroups@vger.kernel.org>,
"open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)"
<bpf@vger.kernel.org>, Ridong Chen <chenridong@xiaomi.com>
Subject: Re: [PATCH v7 7/7] mm/mglru: add tracepoint for aging
Date: Thu, 5 Nov 2026 09:58:10 +0800 [thread overview]
Message-ID: <auvisj8NeTJ8FunG@MiWiFi-R3L-srv> (raw)
In-Reply-To: <4f830c30-f99c-4f75-851b-1a3f6d1342b1@linux.dev>
On 11/05/26 at 09:48am, Ridong Chen wrote:
>
>
> On 11/5/2026 4:56 AM, Barry Song wrote:
> > On Wed, Nov 4, 2026 at 9:10 PM Ridong Chen <ridong.chen@linux.dev> wrote:
> > >
> > > From: Ridong Chen <chenridong@xiaomi.com>
> > >
> > > Aging in MGLRU advances max_seq to create a new youngest generation.
> > > It is triggered from try_to_shrink_lruvec() when should_run_aging()
> > > finds that eviction is no longer possible, or that it would be better
> > > to age first at the current priority. There is currently no tracepoint
> > > on this path, so it cannot be observed when and why aging is needed.
> > >
> > > Add mm_mglru_aging, emitted in try_to_shrink_lruvec() right before
> > > try_to_inc_max_seq(), with the node id, memcg id, sc->priority,
> > > swappiness, max_seq, the anon and file min_seq, and the number of pages
> > > in each generation for both types, as computed by lruvec_gen_size().
> > >
> > > The reason for aging is not reported explicitly, as the logic in
> > > should_run_aging() may change, e.g. for imbalance-based aging. It can
> > > be derived from the generation window and the per-generation sizes,
> > > which are taken before aging, so the youngest generation is populated
> > > as well.
> > >
> > > The nr_anon/nr_file arrays are ordered by seq rather than by generation
> > > slot: entry i holds the generation max_seq - MAX_NR_GENS + 1 + i, i.e.
> > > they go from the oldest generation to the newest, the same order as the
> > > debugfs lru_gen file, so the output can be read directly without mapping
> > > slots back to seqs. The arrays are printed with __print_array(), so the
> > > output is hex and its length follows MAX_NR_GENS automatically.
> > >
> > > Only the lruvec, sc and swappiness are passed in; everything else,
> > > including max_seq, is read in TP_fast_assign(), so try_to_shrink_lruvec()
> > > does no extra work when the event is disabled. Reading max_seq there
> > > rather than using the caller's copy keeps the window consistent with
> > > the per-generation sizes read right after it, should another reclaimer
> > > age the lruvec in between.
> > >
> > > The event marks the aging decision, not its result: the following
> > > try_to_inc_max_seq() may find that aging is already in progress or
> > > done by another reclaimer, so concurrent reclaimers can each emit it
> > > for the same max_seq. Whether max_seq was advanced can be seen from the
> > > following mm_mglru_scan_folios.
> > >
> > > Suggested-by: Barry Song <baohua@kernel.org>
> > > Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
> > > ---
> >
> > Much better now:
> >
> > ~ # echo 1 > /sys/kernel/tracing/events/vmscan/mm_mglru_aging/enable
> > ~ # ./a.out
> > Mapped 400 MB at 0xffff98a00000
> > ^C
> > ~ # cat /sys/kernel/tracing/trace | grep mglru_aging
> > kswapd0-49 [001] ..... 104.277689: mm_mglru_aging:
> > nid=0 memcg_id=1 priority=6 swappiness=60 max_seq=3 anon_min_seq=2
> > file_min_seq=1 nr_anon={0x0,0x0,0xd360,0x0}
> > nr_file={0x0,0x23e2,0x0,0x0}
> > kswapd0-49 [001] ..... 104.536448: mm_mglru_aging:
> > nid=0 memcg_id=1 priority=3 swappiness=60 max_seq=4 anon_min_seq=2
> > file_min_seq=2 nr_anon={0x0,0x20,0xf8bc,0x0}
> > nr_file={0x0,0x91a,0xbd,0x0}
> > a.out-79 [000] ..... 104.689518: mm_mglru_aging:
> > nid=0 memcg_id=1 priority=4 swappiness=60 max_seq=5 anon_min_seq=3
> > file_min_seq=4 nr_anon={0x0,0xf8a0,0x1188,0x0}
> > nr_file={0x0,0x0,0x2,0x7}
> > kswapd0-49 [001] ..... 107.282038: mm_mglru_aging:
> > nid=0 memcg_id=1 priority=2 swappiness=60 max_seq=6 anon_min_seq=4
> > file_min_seq=5 nr_anon={0x0,0x6c50,0xa168,0x605}
> > nr_file={0x0,0x0,0x98,0x18}
> > kswapd0-49 [001] ..... 107.812598: mm_mglru_aging:
> > nid=0 memcg_id=1 priority=1 swappiness=60 max_seq=7 anon_min_seq=5
> > file_min_seq=6 nr_anon={0x0,0xfe10,0x1721,0x54}
> > nr_file={0x0,0x0,0x1a,0x3}
> > a.out-79 [000] ..... 108.936872: mm_mglru_aging:
> > nid=0 memcg_id=1 priority=2 swappiness=60 max_seq=8 anon_min_seq=6
> > file_min_seq=7 nr_anon={0x8,0x7d29,0x8c54,0xc90}
> > nr_file={0x0,0x0,0x4,0x2}
> > kswapd0-49 [001] ..... 108.937115: mm_mglru_aging:
> > nid=0 memcg_id=1 priority=2 swappiness=60 max_seq=8 anon_min_seq=6
> > file_min_seq=7 nr_anon={0x0,0x7d15,0x8c94,0xcac}
> > nr_file={0x0,0x0,0x4,0x2}
> > kswapd0-49 [001] ..... 109.425258: mm_mglru_aging:
> > nid=0 memcg_id=1 priority=1 swappiness=60 max_seq=9 anon_min_seq=7
> > file_min_seq=8 nr_anon={0x0,0xed69,0x24bc,0x488}
> > nr_file={0x0,0x0,0x3,0x3}
> >
> > One thing that looks a bit weird, though. For example:
> >
> > max_seq=3 anon_min_seq=2
> >
> > We have only two generations for anon, but we print four:
> >
> > nr_anon={0x0,0x0,0xd360,0x0}
> >
> > The two oldest generations don't actually exist. Ideally,
> > we would print only the two existing generations:
> >
> > nr_anon={0xd360,0x0}
> >
> > you should be able to fix it by:
> >
> > __print_array(__entry->nr_anon, __entry->max_seq -
> > __entry->anon_min_seq + 1 , sizeof(unsigned long)),
> > __print_array(__entry->nr_file, __entry->max_seq -
> > __entry->file_min_seq + 1, sizeof(unsigned long)))
> >
> > But I guess it's fine, since the two extra entries are both
> > zero.
> >
> > And, I personally prefer the youngest-to-oldest order,
> > as we usually have:
> >
> > head ---------- tail
> >
> > where head is young and tail is old.
> >
> > Your output uses:
> >
> > tail ---------- head
> >
> > But anyway, I guess this is just a matter of whether we
> > read it from left to right or right to left. Personally, I
> > find it more natural to read from youngest to oldest.
> >
> > If you're not tired of working on this and would like to make
> > a few more improvements, you could address the two issues
> > above. But it is up to you.
> >
> > For the patch,
> >
> > Reviewed-by: Barry Song <baohua@kernel.org>
>
> Hi, Barry,
>
> Thanks a lot for testing and the Reviewed-by.
>
> Updating it would be fine with me, but I'd slightly prefer the current
> output, to keep it consistent with the debugfs lru_gen_full file. It
> also prints a fixed window of MAX_NR_GENS generations from the oldest
> to the newest, marking the ones below min_seq with 'x'. The event
> reports anon_min_seq and file_min_seq in place of the 'x', so the
> generations that don't exist can still be told apart, and they always
> read 0. Keeping the same window and order makes it easy to compare the
> event with debugfs, e.g. when looking at both while debugging.
>
> That said, if others such as Baolin, Baoquan or Kairui also prefer
> printing only the existing generations from the youngest to the
> oldest, I'm happy to send another version with that change.
I like oldest -> youngest a little better because when I am thinking
about MGLRU logic in my mind, I would put min_seq in the left, max_seq
in the right, then wrap around from right to left.
prev parent reply other threads:[~2026-11-05 1:58 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 13:08 [PATCH v7 0/7] mm/vmscan: move tracepoints to mm/ and add MGLRU tracepoints Ridong Chen
2026-11-04 13:08 ` [PATCH v7 1/7] mm/memcontrol: drop unused vmscan tracepoint include Ridong Chen
2026-11-04 13:08 ` [PATCH v7 2/7] mm/vmscan: move vmscan tracepoints to a local header Ridong Chen
2026-11-04 13:08 ` [PATCH v7 3/7] mm/vmscan: move struct scan_control to a dedicated header Ridong Chen
2026-11-04 13:08 ` [PATCH v7 4/7] mm/vmscan: pass scan_control to the vmscan tracepoints Ridong Chen
2026-11-04 13:08 ` [PATCH v7 5/7] mm/mglru: add tracepoint for scan_folios() Ridong Chen
2026-11-04 13:08 ` [PATCH v7 6/7] mm/mglru: add lruvec_gen_size() helper Ridong Chen
2026-11-04 13:08 ` [PATCH v7 7/7] mm/mglru: add tracepoint for aging Ridong Chen
2026-11-04 20:56 ` Barry Song
2026-11-05 1:48 ` Ridong Chen
2026-11-05 1:58 ` Baoquan He [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=auvisj8NeTJ8FunG@MiWiFi-R3L-srv \
--to=baoquan.he@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=axelrasmussen@google.com \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=bpf@vger.kernel.org \
--cc=cgroups@vger.kernel.org \
--cc=chenridong@xiaomi.com \
--cc=david@fromorbit.com \
--cc=david@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=kasong@tencent.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=ljs@kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mhiramat@kernel.org \
--cc=mhocko@kernel.org \
--cc=muchun.song@linux.dev \
--cc=qi.zheng@linux.dev \
--cc=ridong.chen@linux.dev \
--cc=roman.gushchin@linux.dev \
--cc=rostedt@goodmis.org \
--cc=shakeel.butt@linux.dev \
--cc=weixugc@google.com \
--cc=yuanchu@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox