Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vmscan: add a vmscan event for reclaim_pages

reclaim_folio_list uses a dummy reclaim_stat and is not being used. To
know the memory stat, add a new trace event. This is useful how how many
pages are not reclaimed or why.

This is an example:

mm_vmscan_reclaim_pages: nid=0 nr_scanned=112 nr_reclaimed=112 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

Currently reclaim_folio_list is only called by reclaim_pages, and
reclaim_pages is used by damon and madvise. In the latest Android,
reclaim_pages is also used by shmem to reclaim all pages in a
address_space.

[jaewon31.kim@samsung.com: use sc.nr_scanned rather than new counting]
Link: https://lkml.kernel.org/r/20241016143227.961162-1-jaewon31.kim@samsung.com
Link: https://lkml.kernel.org/r/20241011124928.1224813-1-jaewon31.kim@samsung.com
Signed-off-by: Jaewon Kim <jaewon31.kim@samsung.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Jaewon Kim <jaewon31.kim@samsung.com>
Cc: Kalesh Singh <kaleshsingh@google.com>
Cc: Minchan Kim <minchan@kernel.org>
Cc: SeongJae Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Jaewon Kim and committed by
Andrew Morton
1f2d03cc 5708d96d

+48 -2
+45
include/trace/events/vmscan.h
··· 346 346 show_reclaim_flags(__entry->reclaim_flags)) 347 347 ); 348 348 349 + TRACE_EVENT(mm_vmscan_reclaim_pages, 350 + 351 + TP_PROTO(int nid, 352 + unsigned long nr_scanned, unsigned long nr_reclaimed, 353 + struct reclaim_stat *stat), 354 + 355 + TP_ARGS(nid, nr_scanned, nr_reclaimed, stat), 356 + 357 + TP_STRUCT__entry( 358 + __field(int, nid) 359 + __field(unsigned long, nr_scanned) 360 + __field(unsigned long, nr_reclaimed) 361 + __field(unsigned long, nr_dirty) 362 + __field(unsigned long, nr_writeback) 363 + __field(unsigned long, nr_congested) 364 + __field(unsigned long, nr_immediate) 365 + __field(unsigned int, nr_activate0) 366 + __field(unsigned int, nr_activate1) 367 + __field(unsigned long, nr_ref_keep) 368 + __field(unsigned long, nr_unmap_fail) 369 + ), 370 + 371 + TP_fast_assign( 372 + __entry->nid = nid; 373 + __entry->nr_scanned = nr_scanned; 374 + __entry->nr_reclaimed = nr_reclaimed; 375 + __entry->nr_dirty = stat->nr_dirty; 376 + __entry->nr_writeback = stat->nr_writeback; 377 + __entry->nr_congested = stat->nr_congested; 378 + __entry->nr_immediate = stat->nr_immediate; 379 + __entry->nr_activate0 = stat->nr_activate[0]; 380 + __entry->nr_activate1 = stat->nr_activate[1]; 381 + __entry->nr_ref_keep = stat->nr_ref_keep; 382 + __entry->nr_unmap_fail = stat->nr_unmap_fail; 383 + ), 384 + 385 + TP_printk("nid=%d nr_scanned=%ld nr_reclaimed=%ld nr_dirty=%ld nr_writeback=%ld nr_congested=%ld nr_immediate=%ld nr_activate_anon=%d nr_activate_file=%d nr_ref_keep=%ld nr_unmap_fail=%ld", 386 + __entry->nid, 387 + __entry->nr_scanned, __entry->nr_reclaimed, 388 + __entry->nr_dirty, __entry->nr_writeback, 389 + __entry->nr_congested, __entry->nr_immediate, 390 + __entry->nr_activate0, __entry->nr_activate1, 391 + __entry->nr_ref_keep, __entry->nr_unmap_fail) 392 + ); 393 + 349 394 TRACE_EVENT(mm_vmscan_lru_shrink_inactive, 350 395 351 396 TP_PROTO(int nid,
+3 -2
mm/vmscan.c
··· 2129 2129 static unsigned int reclaim_folio_list(struct list_head *folio_list, 2130 2130 struct pglist_data *pgdat) 2131 2131 { 2132 - struct reclaim_stat dummy_stat; 2132 + struct reclaim_stat stat; 2133 2133 unsigned int nr_reclaimed; 2134 2134 struct folio *folio; 2135 2135 struct scan_control sc = { ··· 2140 2140 .no_demotion = 1, 2141 2141 }; 2142 2142 2143 - nr_reclaimed = shrink_folio_list(folio_list, pgdat, &sc, &dummy_stat, true); 2143 + nr_reclaimed = shrink_folio_list(folio_list, pgdat, &sc, &stat, true); 2144 2144 while (!list_empty(folio_list)) { 2145 2145 folio = lru_to_folio(folio_list); 2146 2146 list_del(&folio->lru); 2147 2147 folio_putback_lru(folio); 2148 2148 } 2149 + trace_mm_vmscan_reclaim_pages(pgdat->node_id, sc.nr_scanned, nr_reclaimed, &stat); 2149 2150 2150 2151 return nr_reclaimed; 2151 2152 }