Re: [RFC PATCH v5 01/14] mm/mglru: report evictable sizes per type

From: KunWu Chan

Date: Tue Oct 27 2026 - 04:51:51 EST


On Fri, Oct 23, 2026 at 6:02 AM Barry Song (Xiaomi) <baohua@xxxxxxxxxx> wrote:
>
> From: Kairui Song <kasong@xxxxxxxxxxx>
>
> Change lruvec_evictable_size() to return the number of evictable
> anonymous and file pages separately instead of a single total, so
> that callers can weigh the two types independently.
>
> Update lruvec_is_sizable() and get_nr_to_scan() accordingly; the
> summed totals are unchanged, so there is no functional change.
>
> Signed-off-by: Kairui Song <kasong@xxxxxxxxxxx>
> Signed-off-by: Barry Song (Xiaomi) <baohua@xxxxxxxxxx>
> ---
> mm/vmscan.c | 22 +++++++++++++---------
> 1 file changed, 13 insertions(+), 9 deletions(-)
>
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index fc823fe3bd1f..3be0d6c04a82 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -4332,32 +4332,35 @@ static void set_initial_priority(struct pglist_data *pgdat, struct scan_control
> sc->priority = clamp(priority, DEF_PRIORITY / 2, DEF_PRIORITY);
> }
>
> -static unsigned long lruvec_evictable_size(struct lruvec *lruvec, int swappiness)
> +static void lruvec_evictable_size(struct lruvec *lruvec, int swappiness,
> + unsigned long nr[])
> {
> int gen, type, zone;
> - unsigned long seq, total = 0;
> + unsigned long seq;
> struct lru_gen_folio *lrugen = &lruvec->lrugen;
> DEFINE_MAX_SEQ(lruvec);
> DEFINE_MIN_SEQ(lruvec);
>
> + nr[LRU_GEN_ANON] = 0;
> + nr[LRU_GEN_FILE] = 0;
> +
> for_each_evictable_type(type, swappiness) {
> for (seq = min_seq[type]; seq <= max_seq; seq++) {
> gen = lru_gen_from_seq(seq);
> for (zone = 0; zone < MAX_NR_ZONES; zone++)
> - total += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L);
> + nr[type] += max(READ_ONCE(lrugen->nr_pages[gen][type][zone]), 0L);
> }
> }
> -
> - return total;
> }
>
> static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
> {
> - unsigned long total;
> + unsigned long total, sizes[ANON_AND_FILE];
> int swappiness = get_swappiness(lruvec, sc);
> struct mem_cgroup *memcg = lruvec_memcg(lruvec);
>
> - total = lruvec_evictable_size(lruvec, swappiness);
> + lruvec_evictable_size(lruvec, swappiness, sizes);
> + total = sizes[LRU_GEN_ANON] + sizes[LRU_GEN_FILE];
>
> /* whether the size is big enough to be helpful */
> return mem_cgroup_online(memcg) ? (total >> sc->priority) : total;
> @@ -5181,7 +5184,7 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
> static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
> struct mem_cgroup *memcg, int swappiness)
> {
> - unsigned long nr_to_scan, evictable;
> + unsigned long nr_to_scan, evictable, sizes[ANON_AND_FILE];
> struct pglist_data *pgdat = lruvec_pgdat(lruvec);
>
> /*
> @@ -5197,7 +5200,8 @@ static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
> return 0;
> }
>
> - evictable = lruvec_evictable_size(lruvec, swappiness);
> + lruvec_evictable_size(lruvec, swappiness, sizes);
> + evictable = sizes[LRU_GEN_ANON] + sizes[LRU_GEN_FILE];
>
> /* try to scrape all its memory if this memcg was deleted */
> if (!mem_cgroup_online(memcg))
> --
> 2.34.1
>

Both call sites preserve the previous total by summing the
anon and file sizes.

Reviewed-by: Kunwu Chan <kunwu.chan@xxxxxxxxx>

Thanks,
Kunwu