From: Kairui Song To enable moving file pages in folio_mark_accessed directly and lazily for MGLRU, allow updating the LRU statistic atomically without holding a lock. It may cause temporary counter underflow, which should be fine as we still follow final consistency of the counter, and it only serves as a factor for calculating the reclaim budget in vmscan. A little inaccuracy has no visible effect. Signed-off-by: Kairui Song --- include/linux/memcontrol.h | 2 +- include/linux/mm_inline.h | 3 +-- mm/memcontrol.c | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 345a6ba8a3a7..2552f24afe38 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -889,7 +889,7 @@ unsigned long mem_cgroup_get_zone_lru_size(struct lruvec *lruvec, mz = container_of(lruvec, struct mem_cgroup_per_node, lruvec); val = atomic_long_read(&mz->lru_zone_size[zone_idx][lru]); - if (WARN_ON_ONCE(val < 0)) + if (val < 0) return 0; return val; diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index a171070e15f0..045f9ee3880a 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -36,11 +36,10 @@ static __always_inline void __update_lru_size(struct lruvec *lruvec, { struct pglist_data *pgdat = lruvec_pgdat(lruvec); - lockdep_assert_held(&lruvec->lru_lock); WARN_ON_ONCE(nr_pages != (int)nr_pages); mod_lruvec_state(lruvec, NR_LRU_BASE + lru, nr_pages); - __mod_zone_page_state(&pgdat->node_zones[zid], + mod_zone_page_state(&pgdat->node_zones[zid], NR_ZONE_LRU_BASE + lru, nr_pages); } diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 71fad2239973..a3571763e813 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1477,8 +1477,8 @@ struct lruvec *folio_lruvec_lock_irqsave(struct folio *folio, * @zid: zone id of the accounted pages * @nr_pages: positive when adding or negative when removing * - * This function must be called under lru_lock, just before a page is added - * to or just after a page is removed from an lru list. + * This function must be called when a page is added to or removed from + * an lru list. Caller need to protect the lruvec from being freed. */ void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru, int zid, long nr_pages) -- 2.54.0