Skip to content

Commit

Permalink
mm/filemap: add missing mem_cgroup_uncharge() to __add_to_page_cache_…
Browse files Browse the repository at this point in the history
…locked()

OpenAnolis Bug Tracker: 0000546

commit da74240eb3fcd806edb1643874363e954d9e948b upstream.

Commit 3fea5a4 ("mm: memcontrol: convert page cache to a new
mem_cgroup_charge() API") introduced a bug in __add_to_page_cache_locked()
causing the following splat:

  page dumped because: VM_BUG_ON_PAGE(page_memcg(page))
  pages's memcg:ffff8889a4116000
  ------------[ cut here ]------------
  kernel BUG at mm/memcontrol.c:2924!
  invalid opcode: 0000 [#1] SMP KASAN PTI
  CPU: 35 PID: 12345 Comm: cat Tainted: G S      W I       5.11.0-rc4-debug+ #1
  Hardware name: HP HP Z8 G4 Workstation/81C7, BIOS P60 v01.25 12/06/2017
  RIP: commit_charge+0xf4/0x130
  Call Trace:
    mem_cgroup_charge+0x175/0x770
    __add_to_page_cache_locked+0x712/0xad0
    add_to_page_cache_lru+0xc5/0x1f0
    cachefiles_read_or_alloc_pages+0x895/0x2e10 [cachefiles]
    __fscache_read_or_alloc_pages+0x6c0/0xa00 [fscache]
    __nfs_readpages_from_fscache+0x16d/0x630 [nfs]
    nfs_readpages+0x24e/0x540 [nfs]
    read_pages+0x5b1/0xc40
    page_cache_ra_unbounded+0x460/0x750
    generic_file_buffered_read_get_pages+0x290/0x1710
    generic_file_buffered_read+0x2a9/0xc30
    nfs_file_read+0x13f/0x230 [nfs]
    new_sync_read+0x3af/0x610
    vfs_read+0x339/0x4b0
    ksys_read+0xf1/0x1c0
    do_syscall_64+0x33/0x40
    entry_SYSCALL_64_after_hwframe+0x44/0xa9

Before that commit, there was a try_charge() and commit_charge() in
__add_to_page_cache_locked().  These two separated charge functions were
replaced by a single mem_cgroup_charge().  However, it forgot to add a
matching mem_cgroup_uncharge() when the xarray insertion failed with the
page released back to the pool.

Fix this by adding a mem_cgroup_uncharge() call when insertion error
happens.

Link: https://lkml.kernel.org/r/[email protected]
Fixes: 3fea5a4 ("mm: memcontrol: convert page cache to a new mem_cgroup_charge() API")
Signed-off-by: Waiman Long <[email protected]>
Reviewed-by: Alex Shi <[email protected]>
Acked-by: Johannes Weiner <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Miaohe Lin <[email protected]>
Cc: Muchun Song <[email protected]>
Cc: Michal Hocko <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: zhongjiang-ali <[email protected]>
Acked-by: Xunlei Pang <[email protected]>
Signed-off-by: Xunlei Pang <[email protected]>
  • Loading branch information
Waiman Long authored and shiloong committed Nov 22, 2021
1 parent 61225b9 commit f29ac29
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions mm/filemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,7 @@ static int __add_to_page_cache_locked(struct page *page,
{
int huge = PageHuge(page);
int error;
bool charged = false;

VM_BUG_ON_PAGE(!PageLocked(page), page);
VM_BUG_ON_PAGE(PageSwapBacked(page), page);
Expand All @@ -874,12 +875,15 @@ static int __add_to_page_cache_locked(struct page *page,
put_page(page);
return error;
}
charged = true;
}

error = radix_tree_maybe_preload(gfp_mask & GFP_RECLAIM_MASK);
if (error) {
page->mapping = NULL;
put_page(page);
if (charged)
mem_cgroup_uncharge(page);
return error;
}

Expand All @@ -899,6 +903,8 @@ static int __add_to_page_cache_locked(struct page *page,
page->mapping = NULL;
/* Leave page->index set: truncation relies upon it */
xa_unlock_irq(&mapping->i_pages);
if (charged)
mem_cgroup_uncharge(page);
put_page(page);
return error;
}
Expand Down

0 comments on commit f29ac29

Please sign in to comment.