This helper is used to provide a callback to be called for each lruvec list. This abstracts different lruvec implementations (MGLRU vs. classic LRUs). The helper is used by a following commit to iterate all folios in all LRUs lists for memcg recharging. Signed-off-by: Yosry Ahmed <yosryahmed@xxxxxxxxxx> --- include/linux/swap.h | 8 ++++++++ mm/vmscan.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/linux/swap.h b/include/linux/swap.h index 456546443f1f..c0621deceb03 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -406,6 +406,14 @@ extern void lru_cache_add_inactive_or_unevictable(struct page *page, struct vm_area_struct *vma); /* linux/mm/vmscan.c */ +typedef bool (*lruvec_list_fn_t)(struct lruvec *lruvec, + struct list_head *list, + enum lru_list lru, + void *arg); +extern void lruvec_for_each_list(struct lruvec *lruvec, + lruvec_list_fn_t fn, + void *arg); + extern unsigned long zone_reclaimable_pages(struct zone *zone); extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *mask); diff --git a/mm/vmscan.c b/mm/vmscan.c index 1080209a568b..e7956000a3b6 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -6254,6 +6254,34 @@ static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control * #endif /* CONFIG_LRU_GEN */ +/* + * lruvec_for_each_list - make a callback for every folio list in the lruvec + * @lruvec: the lruvec to iterate lists in + * @fn: the callback to make for each list, iteration stops if it returns true + * @arg: argument to pass to @fn + */ +void lruvec_for_each_list(struct lruvec *lruvec, lruvec_list_fn_t fn, void *arg) +{ + enum lru_list lru; + +#ifdef CONFIG_LRU_GEN + if (lru_gen_enabled()) { + int gen, type, zone; + + for_each_gen_type_zone(gen, type, zone) { + lru = type * LRU_INACTIVE_FILE; + if (fn(lruvec, &lruvec->lrugen.folios[gen][type][zone], + lru, arg)) + break; + } + } else +#endif + for_each_evictable_lru(lru) { + if (fn(lruvec, &lruvec->lists[lru], lru, arg)) + break; + } +} + static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc) { unsigned long nr[NR_LRU_LISTS]; -- 2.41.0.255.g8b1d071c50-goog