From: Baoquan He <baoquan.he@linux.dev>
To: Barry Song <baohua@kernel.org>
Cc: Ridong Chen <ridong.chen@linux.dev>,
Steven Rostedt <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Johannes Weiner <hannes@cmpxchg.org>,
Michal Hocko <mhocko@kernel.org>,
Roman Gushchin <roman.gushchin@linux.dev>,
Shakeel Butt <shakeel.butt@linux.dev>,
Dave Chinner <david@fromorbit.com>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Muchun Song <muchun.song@linux.dev>,
Qi Zheng <qi.zheng@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>,
David Hildenbrand <david@kernel.org>,
Lorenzo Stoakes <ljs@kernel.org>,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
linux-mm@kvack.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 v5 6/6] mm/mglru: add tracepoint for inc_max_seq()
Date: Mon, 2 Nov 2026 10:13:12 +0800 [thread overview]
Message-ID: <aufxuOaKZWMYqEQi@bogon> (raw)
In-Reply-To: <CAGsJ_4zUbkFXBhAesVV74-Ndga5f6xEbestK7Qinqddip8xBrw@mail.gmail.com>
On 11/01/26 at 05:21am, Barry Song wrote:
> On Sat, Oct 31, 2026 at 5:02 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 while
> > the lruvec lock is still held, with the node id, memcg id, the new
> > max_seq, the anon and file min_seq, and the number of pages in each
> > generation for both types, summed over zones and clamped to >= 0 the
> > same way the debugfs lru_gen file reports them. The nr_anon/nr_file
> > arrays are indexed by generation slot, so the emitted max_seq/min_seq
> > say which slot holds which seq. They are printed with __print_array(),
> > so the output is hex and its length follows MAX_NR_GENS automatically.
> >
> > Only the lruvec is passed in; all of the above is collected in
> > TP_fast_assign(), so inc_max_seq() does no extra work when the event is
> > disabled. Paired with mm_mglru_scan_folios it makes the full
> > aging-to-eviction window observable per memcg.
> >
> > Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
> > ---
> > mm/trace_vmscan.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++
> > mm/vmscan.c | 2 ++
> > 2 files changed, 49 insertions(+)
> >
> > diff --git a/mm/trace_vmscan.h b/mm/trace_vmscan.h
> > index 8148b8224422..cddf42b5849a 100644
> > --- a/mm/trace_vmscan.h
> > +++ b/mm/trace_vmscan.h
> > @@ -456,6 +456,53 @@ TRACE_EVENT(mm_mglru_scan_folios,
> > __entry->min_seq)
> > );
> >
> > +TRACE_EVENT(mm_mglru_inc_max_seq,
> > +
> > + TP_PROTO(struct lruvec *lruvec),
> > +
> > + TP_ARGS(lruvec),
> > +
> > + TP_STRUCT__entry(
> > + __field(u64, memcg_id)
> > + __field(unsigned long, max_seq)
> > + __field(unsigned long, anon_min_seq)
> > + __field(unsigned long, file_min_seq)
> > + __array(unsigned long, nr_anon, MAX_NR_GENS)
> > + __array(unsigned long, nr_file, MAX_NR_GENS)
> > + __field(int, nid)
> > + ),
> > +
> > + TP_fast_assign(
> > + struct lru_gen_folio *lrugen = &lruvec->lrugen;
> > + int gen, zone;
> > +
> > + __entry->memcg_id = mem_cgroup_id(lruvec_memcg(lruvec));
> > + __entry->max_seq = lrugen->max_seq;
> > + __entry->anon_min_seq = lrugen->min_seq[LRU_GEN_ANON];
> > + __entry->file_min_seq = lrugen->min_seq[LRU_GEN_FILE];
> > + /* summed over zones and clamped to >= 0, as debugfs lru_gen does */
> > + for (gen = 0; gen < MAX_NR_GENS; gen++) {
> > + __entry->nr_anon[gen] = 0;
> > + __entry->nr_file[gen] = 0;
> > + for (zone = 0; zone < MAX_NR_ZONES; zone++) {
> > + __entry->nr_anon[gen] +=
> > + max(lrugen->nr_pages[gen][LRU_GEN_ANON][zone], 0L);
> > + __entry->nr_file[gen] +=
> > + max(lrugen->nr_pages[gen][LRU_GEN_FILE][zone], 0L);
> > + }
> > + }
>
> I feel this is wrong. Can we calculate the newest and
> oldest generations from seq, then print them in order
> from newest to oldest?
Agree, from newest to oldest or oldest to newest makes it clearer.
Printing from lrugen->max_seq - MAX_NR_GENS + 1, or from MAX_NR_GENS,
both looks good.
>
> The nr_pages[] array isn't ordered from newest to
> oldest or vice versa, as we have:
>
> static inline int lru_gen_from_seq(unsigned long seq)
> {
> return seq % MAX_NR_GENS;
> }
>
> And I added a helper here:
> https://lore.kernel.org/linux-mm/20261022220203.91911-11-baohua@kernel.org/
>
> +static inline unsigned long lruvec_gen_size(struct lru_gen_folio *lrugen,
> + int type, unsigned long seq)
> +{
> + int gen = lru_gen_from_seq(seq);
> + unsigned long size = 0;
> +
> + for (int zone = 0; zone < MAX_NR_ZONES; zone++)
> + size += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L);
> + return size;
> +}
>
> Maybe you could port it here as a separate patch so it
> can land earlier as part of your tracepoints series. We
> could then use it in the next version of the swappiness
> series.
>
> Best,
> Barry
prev parent reply other threads:[~2026-11-02 2:13 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-31 9:00 [PATCH v5 0/6] mm/vmscan: move tracepoints to mm/ and add MGLRU tracepoints Ridong Chen
2026-10-31 9:00 ` [PATCH v5 1/6] mm/memcontrol: drop unused vmscan tracepoint include Ridong Chen
2026-11-01 3:20 ` Baoquan He
2026-10-31 9:00 ` [PATCH v5 2/6] mm/vmscan: move vmscan tracepoints to a local header Ridong Chen
2026-10-31 9:27 ` Muchun Song
2026-11-02 1:37 ` Baoquan He
2026-10-31 9:00 ` [PATCH v5 3/6] mm/vmscan: move struct scan_control to a dedicated header Ridong Chen
2026-10-31 9:29 ` Muchun Song
2026-11-02 1:38 ` Baoquan He
2026-10-31 9:00 ` [PATCH v5 4/6] mm/vmscan: pass scan_control to the vmscan tracepoints Ridong Chen
2026-10-31 10:12 ` Muchun Song
2026-11-02 1:40 ` Baoquan He
2026-10-31 9:00 ` [PATCH v5 5/6] mm/mglru: add tracepoint for scan_folios() Ridong Chen
2026-10-31 21:02 ` Barry Song
2026-11-02 1:44 ` Baoquan He
2026-10-31 9:00 ` [PATCH v5 6/6] mm/mglru: add tracepoint for inc_max_seq() Ridong Chen
2026-10-31 21:21 ` Barry Song
2026-11-02 2:13 ` 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=aufxuOaKZWMYqEQi@bogon \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.