All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ridong Chen <ridong.chen@linux.dev>
To: Baoquan He <baoquan.he@linux.dev>
Cc: Steven Rostedt <rostedt@goodmis.org>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Johannes Weiner <hannes@cmpxchg.org>,
	Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
	Kairui Song <kasong@tencent.com>, Qi Zheng <qi.zheng@linux.dev>,
	Shakeel Butt <shakeel.butt@linux.dev>,
	Barry Song <baohua@kernel.org>,
	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>,
	Michal Hocko <mhocko@kernel.org>,
	Lorenzo Stoakes <ljs@kernel.org>,
	linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
	"open list:MEMORY MANAGEMENT - MGLRU (MULTI-GEN LRU)"
	<linux-mm@kvack.org>, Ridong Chen <chenridong@xiaomi.com>
Subject: Re: [PATCH v2 2/3] mm/mglru: add tracepoint for scan_folios()
Date: Thu, 17 Sep 2026 11:12:20 +0800	[thread overview]
Message-ID: <34ffedaf-8f98-48eb-b3a9-d42f273a261d@linux.dev> (raw)
In-Reply-To: <aqs9auiVq2EplTha@fedora>



On 9/17/2026 9:07 AM, Baoquan He wrote:
> On 09/16/26 at 08:17pm, Ridong Chen wrote:
>>
>>
>> On 9/16/2026 10:14 AM, Baoquan He wrote:
>>> On 09/15/26 at 08:17pm, Ridong Chen wrote:
>>>>
>>>>
>>>> On 9/15/2026 7:14 PM, Baoquan He wrote:
>>>>> On 09/11/26 at 06:29pm, Ridong Chen wrote:
>>>>>> From: Ridong Chen <chenridong@xiaomi.com>
>>>>> ...snip...
>>>>>> ---
>>>>>>     include/trace/events/vmscan.h | 63 +++++++++++++++++++++++++++++++++++
>>>>>>     mm/vmscan.c                   |  6 ++++
>>>>>>     2 files changed, 69 insertions(+)
>>>>>>
>>>>>> diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h
>>>>>> index 8a872990b4be..5defa8f6719c 100644
>>>>>> --- a/include/trace/events/vmscan.h
>>>>>> +++ b/include/trace/events/vmscan.h
>>>>>> @@ -392,6 +392,69 @@ TRACE_EVENT(mm_vmscan_lru_isolate,
>>>>>>     		__print_symbolic(__entry->lru, LRU_NAMES))
>>>>>>     );
>>>>>> +TRACE_EVENT(mm_mglru_scan_folios,
>>>>>> +
>>>>>> +	TP_PROTO(struct lruvec *lruvec,
>>>>>> +		int highest_zoneidx,
>>>>>> +		int order,
>>>>>> +		unsigned long nr_requested,
>>>>>> +		unsigned long nr_scanned,
>>>>>> +		unsigned long nr_sorted,
>>>>>> +		unsigned long nr_skipped,
>>>>>> +		unsigned long nr_taken,
>>>>>> +		int lru,
>>>>>> +		unsigned long max_seq,
>>>>>> +		int tier,
>>>>>> +		unsigned long min_seq),
>>>>>
>>>>
>>>> Thank you for your review.
>>>>
>>>>> Do we need show nid? Guess phone vendor doesn't care about multi-NUMA
>>>>> system.
>>>>>
>>>>
>>>> Eh, nid is not an mglru-specific key. Since there are 12 elements here, it
>>>> can't be added here.
>>>
>>> Hmm, we print memcg_id but not nid, it may not be so clear. How do you
>                                 ^~~~ typo, s/not/no/
> 
>>> differentiate several lruvec-s on one memcg? I am not very familiar with
>>> trace mechanism, do we have a element number limit?
>>>
>>
>> Yes, it will fail to compile if there are more than 12 elements.
>>
>> With AI's help, see
>>
>> include/trace/bpf_probe.h
>> ```
>> 30 #define __CAST1(a,...) __CAST_TO_U64(a)
>>   31 #define __CAST2(a,...) __CAST_TO_U64(a), __CAST1(__VA_ARGS__)
>>   32 #define __CAST3(a,...) __CAST_TO_U64(a), __CAST2(__VA_ARGS__)
>>   33 #define __CAST4(a,...) __CAST_TO_U64(a), __CAST3(__VA_ARGS__)
>>   34 #define __CAST5(a,...) __CAST_TO_U64(a), __CAST4(__VA_ARGS__)
>>   35 #define __CAST6(a,...) __CAST_TO_U64(a), __CAST5(__VA_ARGS__)
>>   36 #define __CAST7(a,...) __CAST_TO_U64(a), __CAST6(__VA_ARGS__)
>>   37 #define __CAST8(a,...) __CAST_TO_U64(a), __CAST7(__VA_ARGS__)
>>   38 #define __CAST9(a,...) __CAST_TO_U64(a), __CAST8(__VA_ARGS__)
>>   39 #define __CAST10(a,...) __CAST_TO_U64(a), __CAST9(__VA_ARGS__)
>>   40 #define __CAST11(a,...) __CAST_TO_U64(a), __CAST10(__VA_ARGS__)
>>   41 #define __CAST12(a,...) __CAST_TO_U64(a), __CAST11(__VA_ARGS__)
>> /* tracepoints with more than 12 arguments will hit build error */
>> ```
>>
>>> Imagine I only want to trace this function, now I can see memcg_id,
>>> zone_idex, while don't know node/lruvec, that's a little pitty. Just my
>>> personal opinion, I could miss anything.
>>>
>>
>> Yeah, you are right. In my personal experience, I always enable
>> trace_mm_vmscan_lru_isolate and trace_mm_vmscan_lru_shrink_inactive, which
>> contain node_id. So we can see how the lruvec is scanned and shrunk, and we
>> can get node_id from trace_mm_vmscan_lru_shrink_inactive. I am not arguing
>> that this is exactly the 'correct' way to use these tracepoints, but I think
>> it is a common usage.
>>
>> I am open to that. If we want to record node_id, we have to remove an
>> element. Maybe tier? But I would strongly recommend record memcg_id, we
>> frequently need to check the reclaim behavior of a memcg, and most of our
> 
> Sorry, that's my typo which could cause misunderstanding. I meant "we print
> memcg_id but no nid, it may not be so clear". I agree with you that
> memcg_id is undispensable.
> 
>> scenarios are non-NUMA.
> 
> Understood, mobile phone mostly is non-NUMA, while server is different.
> About adding nid, I cousulted AI too, it says it's doable.
> 
> It says The 12-argument limit only counts the TP_PROTO arguments (that's
> the BPF __CAST12/bpf_trace_run12 path), not the __entry fields in
> TP_STRUCT__entry. And nid doesn't have to be a 13th argument at all. We
> already pass lruvec, so nid can be derived from it in TP_fast_assign with
> lruvec_pgdat(lruvec)->node_id.
>                                                                                                        
> e.g. for mm_mglru_scan_folios:
>                                                                                                        
>     TP_STRUCT__entry(
>        __field(u64, memcg_id)
>        __field(int, nid)
>        __field(int, highest_zoneidx)
>        __field(int, order)
>        __field(unsigned long, nr_requested)
>        __field(unsigned long, nr_scanned)
>        __field(unsigned long, nr_sorted)
>        __field(unsigned long, nr_skipped)
>        __field(unsigned long, nr_taken)
>        __field(int, lru)
>        __field(unsigned long, max_seq)
>        __field(int, tier)
>        __field(unsigned long, min_seq)
>     ),
>                                                                                                        
>     TP_fast_assign(
>        __entry->memcg_id = mem_cgroup_id(lruvec_memcg(lruvec));
>        __entry->nid      = lruvec_pgdat(lruvec)->node_id;
>        __entry->highest_zoneidx = highest_zoneidx;
>        ...
>     ),
>                                                                                                        
>     TP_printk("memcg_id=%llu nid=%d classzone=%d order=%d ...",
>        __entry->memcg_id,
>        __entry->nid,
>        __entry->highest_zoneidx,
>        ...)
>                                                                                                        
> lruvec_pgdat() comes from include/linux/mmzone.h, which vmscan.h already
> pulls in via linux/mm.h, so no extra include is needed. The same pattern
> applies to mm_mglru_inc_max_seq in patch 3 if you want nid there too.
> I didn't try it though, please feel free to give it a shot.
> 

Good. It works, I just tested it. Will add nid.

> 
>>
> 
>>>>
>>>>
>>>>> And I checked v1 thread, seems Steven suggested to move the two int to
>>>>> avoid extra padding.
>>>>>
>>>>
>>>> Yeah, I will update it. I updated v2 to fix Sashiko's issue, before Steven
>>>> had any comment.
>>>>
>>>>
>>>>>> +
>>>>>> +	TP_ARGS(lruvec, highest_zoneidx, order, nr_requested, nr_scanned,
>>>>>> +		nr_sorted, nr_skipped, nr_taken, lru, max_seq, tier, min_seq),
>>>>>> +
>>>>>> +	TP_STRUCT__entry(
>>>>>> +		__field(u64, memcg_id)
>>>>>> +		__field(int, highest_zoneidx)
>>>>>> +		__field(int, order)
>>>>>> +		__field(unsigned long, nr_requested)
>>>>>> +		__field(unsigned long, nr_scanned)
>>>>>> +		__field(unsigned long, nr_sorted)
>>>>>> +		__field(unsigned long, nr_skipped)
>>>>>> +		__field(unsigned long, nr_taken)
>>>>>> +		__field(int, lru)
>>>>>> +		__field(unsigned long, max_seq)
>>>>>> +		__field(int, tier)
>>>>>> +		__field(unsigned long, min_seq)
>>>>>> +	),
>>>>>> +
>>>>>> +	TP_fast_assign(
>>>>>> +		__entry->memcg_id = mem_cgroup_id(lruvec_memcg(lruvec));
>>>>>> +		__entry->highest_zoneidx = highest_zoneidx;
>>>>>> +		__entry->order = order;
>>>>>> +		__entry->nr_requested = nr_requested;
>>>>>> +		__entry->nr_scanned = nr_scanned;
>>>>>> +		__entry->nr_sorted = nr_sorted;
>>>>>> +		__entry->nr_skipped = nr_skipped;
>>>>>> +		__entry->nr_taken = nr_taken;
>>>>>> +		__entry->lru = lru;
>>>>>> +		__entry->max_seq = max_seq;
>>>>>> +		__entry->tier = tier;
>>>>>> +		__entry->min_seq = min_seq;
>>>>>> +	),
>>>>>> +
>>>>>> +	TP_printk("memcg_id=%llu classzone=%d order=%d nr_requested=%lu nr_scanned=%lu nr_sorted=%lu nr_skipped=%lu nr_taken=%lu lru=%s max_seq=%lu tier=%d min_seq=%lu",
>>>>>> +		__entry->memcg_id,
>>>>>> +		__entry->highest_zoneidx,
>>>>>> +		__entry->order,
>>>>>> +		__entry->nr_requested,
>>>>>> +		__entry->nr_scanned,
>>>>>> +		__entry->nr_sorted,
>>>>>> +		__entry->nr_skipped,
>>>>>> +		__entry->nr_taken,
>>>>>> +		__print_symbolic(__entry->lru, LRU_NAMES),
>>>>>> +		__entry->max_seq,
>>>>>> +		__entry->tier,
>>>>>> +		__entry->min_seq)
>>>>>> +);
>>>>>> +
>>>>>>     TRACE_EVENT(mm_vmscan_write_folio,
>>>>>>     	TP_PROTO(struct folio *folio),
>>>>>> diff --git a/mm/vmscan.c b/mm/vmscan.c
>>>>>> index 2554a6513aa8..67f59aa73fb9 100644
>>>>>> --- a/mm/vmscan.c
>>>>>> +++ b/mm/vmscan.c
>>>>>> @@ -4876,6 +4876,12 @@ static int scan_folios(unsigned long nr_to_scan, struct lruvec *lruvec,
>>>>>>     	trace_mm_vmscan_lru_isolate(sc->reclaim_idx, sc->order, nr_to_scan,
>>>>>>     				scanned, skipped, isolated,
>>>>>>     				type ? LRU_INACTIVE_FILE : LRU_INACTIVE_ANON);
>>>>>> +	trace_mm_mglru_scan_folios(lruvec,
>>>>>> +				   sc->reclaim_idx, sc->order, nr_to_scan,
>>>>>> +				   scanned, sorted, skipped, isolated,
>>>>>> +				   type ? LRU_INACTIVE_FILE : LRU_INACTIVE_ANON,
>>>>>> +				   lrugen->max_seq, tier,
>>>>>> +				   lrugen->min_seq[type]);
>>>>>
>>>>> And seems Steven also suggested to calculate lru, max_seq, min_seq in
>>>>> TP_fast_assign() in v1 which could be missed.
>>>>>
>>>>
>>>> Thanks, I will update it following Steven's suggestions.
>>>>
>>>>
>>>>>            TP_fast_assign(
>>>>>                    __entry->memcg_id = mem_cgroup_id(lruvec_memcg(lruvec));
>>>>>                    __entry->highest_zoneidx = sc->reclaim_idx;
>>>>>                    __entry->order = sc->order;
>>>>>                    __entry->nr_requested = nr_requested;
>>>>>                    __entry->nr_scanned = nr_scanned;
>>>>>                    __entry->nr_sorted = nr_sorted;
>>>>>                    __entry->nr_skipped = nr_skipped;
>>>>>                    __entry->nr_taken = nr_taken;
>>>>>                    __entry->lru = type ? LRU_INACTIVE_FILE : LRU_INACTIVE_ANON;
>>>>>                    __entry->max_seq = lrugen->max_seq;
>>>>>                    __entry->tier = tier;
>>>>>                    __entry->min_seq = lrugen->min_seq;
>>>>>            ),
>>>>>
>>>>
>>>> However, 'sc' is an internal structure, so sc->order cannot be accessed in
>>>> TP_fast_assign(), and I don't think it is worth making scan_control an
>>>> external structure just for this.
>>>
>>> Agree.
>>>
>>>>
>>>>>
>>>>>>     	*isolatedp = isolated;
>>>>>>     	return scanned;
>>>>>> -- 
>>>>>> 2.34.1
>>>>>>
>>>>
>>>> -- 
>>>> Best regards
>>>> Ridong
>>>>
>>
>> -- 
>> Best regards
>> Ridong
>>

-- 
Best regards
Ridong


  reply	other threads:[~2026-09-17  3:12 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-11 10:29 [PATCH v2 0/3] mm/mglru: add tracepoints for scan and aging paths Ridong Chen
2026-09-11 10:29 ` [PATCH v2 1/3] mm/mglru: factor out lru_gen_seq_nr_pages() Ridong Chen
2026-09-14  7:09   ` Baolin Wang
2026-09-15  6:32   ` Baoquan He
2026-09-11 10:29 ` [PATCH v2 2/3] mm/mglru: add tracepoint for scan_folios() Ridong Chen
2026-09-14  7:47   ` Baolin Wang
2026-09-14  9:04     ` Ridong Chen
2026-09-15 11:14   ` Baoquan He
2026-09-15 12:17     ` Ridong Chen
2026-09-16  2:14       ` Baoquan He
2026-09-16 12:17         ` Ridong Chen
2026-09-17  1:07           ` Baoquan He
2026-09-17  3:12             ` Ridong Chen [this message]
2026-09-16 13:51         ` Steven Rostedt
2026-09-17  1:23           ` Baoquan He
2026-09-17  3:21             ` Ridong Chen
2026-09-11 10:29 ` [PATCH v2 3/3] mm/mglru: add tracepoint for inc_max_seq() Ridong Chen
2026-09-14  7:38   ` Baolin Wang

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=34ffedaf-8f98-48eb-b3a9-d42f273a261d@linux.dev \
    --to=ridong.chen@linux.dev \
    --cc=akpm@linux-foundation.org \
    --cc=axelrasmussen@google.com \
    --cc=baohua@kernel.org \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=baoquan.he@linux.dev \
    --cc=chenridong@xiaomi.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=qi.zheng@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.