• M
    mm: Fix page counter mismatch in shmem_mfill_atomic_pte · 454336e1
    Ma Wupeng 提交于
    hulk inclusion
    category: bugfix
    bugzilla: https://gitee.com/openeuler/kernel/issues/I5JT6V
    CVE: NA
    
    --------------------------------
    
    shmem_mfill_atomic_pte() wrongly called mem_cgroup_cancel_charge() in
    "success" path, it should mem_cgroup_uncharge() to dec memory counter
    instead.
    mem_cgroup_cancel_charge() should only be used if this transaction is
    unsuccessful and mem_cgroup_uncharge() is used to do this if this
    transaction succeed.
    
    This will lead to page->memcg not null and will uncharge one more in
    put_page(). The page counter will underflow to maximum value and trigger
    oom to kill all process include sshd and leave system unaccessible.
    
    page->memcg is set in the following path:
    mem_cgroup_commit_charge
    	commit_charge
    		page->mem_cgroup = memcg;
    
    extra uncharge will be done in the following path:
    put_page
    	__put_page
    		__put_single_page
    			mem_cgroup_uncharge
    				if (!page->mem_cgroup) <-- should return
    					return
    				uncharge_page
    				uncharge_batch
    
    To fix this, call mem_cgroup_commit_charge() at the end of this transaction
    to make sure this transaction is really finished.
    
    Fixes: 4c27fe4c ("userfaultfd: shmem: add shmem_mcopy_atomic_pte for userfaultfd support")
    Signed-off-by: NMa Wupeng <mawupeng1@huawei.com>
    Reviewed-by: NKefeng Wang <wangkefeng.wang@huawei.com>
    Signed-off-by: NYongqiang Liu <liuyongqiang13@huawei.com>
    454336e1
shmem.c 111.3 KB