When the unmap of the source range fails at the end of an mremap() move, the length of the range is charged to vm_committed_as even if the VMA was never accounted, for example a MAP_SHARED or MAP_NORESERVE mapping. Nothing ever uncharges these pages, so each such failure permanently inflates the committed memory count. This was reproduced with fault injection: each failure on a shmem mapping left Committed_AS higher by the size of the moved range after everything was unmapped. Fix by charging the range again only when accountable_move is set. Fixes: b714ccb02a76 ("mm/mremap: complete refactor of move_vma()") Signed-off-by: Josef Bacik --- mm/mremap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/mremap.c b/mm/mremap.c index cf746bafdee4..6f941aeb1b5f 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -1247,7 +1247,8 @@ static void unmap_source_vma(struct vma_remap_struct *vrm) vrm->vmi_needs_invalidate = true; if (err) { /* OOM: unable to split vma, just get accounts right */ - vm_acct_memory(len >> PAGE_SHIFT); + if (accountable_move) + vm_acct_memory(len >> PAGE_SHIFT); return; } -- 2.55.0