If cgroups are configured into the kernel, then uncharged pages can only come from filemap_add_folio_nocharge. Track such uncharged folios in vmstat so that they are accounted for. Suggested-by: Shakeel Butt Signed-off-by: Boris Burkov --- include/linux/mmzone.h | 3 +++ mm/filemap.c | 18 ++++++++++++++++++ mm/vmstat.c | 3 +++ 3 files changed, 24 insertions(+) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 283913d42d7b..a945dec65371 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -241,6 +241,9 @@ enum node_stat_item { NR_HUGETLB, #endif NR_BALLOON_PAGES, +#ifdef CONFIG_MEMCG + NR_UNCHARGED_FILE_PAGES, +#endif NR_VM_NODE_STAT_ITEMS }; diff --git a/mm/filemap.c b/mm/filemap.c index ccc9cfb4d418..0a258b4a9246 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -146,6 +146,22 @@ static void page_cache_delete(struct address_space *mapping, mapping->nrpages -= nr; } +#ifdef CONFIG_MEMCG +static void filemap_mod_uncharged_vmstat(struct folio *folio, int sign) +{ + long nr = folio_nr_pages(folio) * sign; + + if (!folio_memcg(folio)) + __lruvec_stat_mod_folio(folio, NR_UNCHARGED_FILE_PAGES, nr); +} +#else +static void filemap_mod_uncharged_cgroup_vmstat(struct folio *folio, int sign) +{ + return; +} +#endif + + static void filemap_unaccount_folio(struct address_space *mapping, struct folio *folio) { @@ -190,6 +206,7 @@ static void filemap_unaccount_folio(struct address_space *mapping, __lruvec_stat_mod_folio(folio, NR_FILE_THPS, -nr); filemap_nr_thps_dec(mapping); } + filemap_mod_uncharged_vmstat(folio, -1); /* * At this point folio must be either written or cleaned by @@ -978,6 +995,7 @@ int filemap_add_folio_nocharge(struct address_space *mapping, struct folio *foli if (!(gfp & __GFP_WRITE) && shadow) workingset_refault(folio, shadow); folio_add_lru(folio); + filemap_mod_uncharged_vmstat(folio, 1); } return ret; } diff --git a/mm/vmstat.c b/mm/vmstat.c index a78d70ddeacd..63318742ae5a 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -1281,6 +1281,9 @@ const char * const vmstat_text[] = { "nr_hugetlb", #endif "nr_balloon_pages", +#ifdef CONFIG_MEMCG + "nr_uncharged_file_pages", +#endif /* system-wide enum vm_stat_item counters */ "nr_dirty_threshold", "nr_dirty_background_threshold", -- 2.50.1