• Waiman Long's avatar
    mm/filemap: add missing mem_cgroup_uncharge() to __add_to_page_cache_locked() · da74240e
    Waiman Long authored
    Commit 3fea5a49 ("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/20210125042441.20030-1-longman@redhat.com
    Fixes: 3fea5a49 ("mm: memcontrol: convert page cache to a new mem_cgroup_charge() API")
    Signed-off-by: default avatarWaiman Long <longman@redhat.com>
    Reviewed-by: default avatarAlex Shi <alex.shi@linux.alibaba.com>
    Acked-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
    Cc: Matthew Wilcox <willy@infradead.org>
    Cc: Miaohe Lin <linmiaohe@huawei.com>
    Cc: Muchun Song <smuchun@gmail.com>
    Cc: Michal Hocko <mhocko@suse.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    da74240e
filemap.c 101 KB