diff --git a/mm/mremap.c b/mm/mremap.c index 7b688bce9002..3cd90b52b750 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -65,7 +65,7 @@ struct vma_remap_struct { /* Internal state, determined in do_mremap(). */ unsigned long delta; /* Absolute delta of old_len,new_len. */ - bool mlocked; /* Was the VMA mlock()'d? */ + bool populate_expand; /* mlock()'d expanded, must populate. */ enum mremap_type remap_type; /* expand, shrink, etc. */ bool mmap_locked; /* Is mm currently write-locked? */ unsigned long charged; /* If VM_ACCOUNT, # pages to account. */ @@ -1010,10 +1010,8 @@ static void vrm_stat_account(struct vma_remap_struct *vrm, struct vm_area_struct *vma = vrm->vma; vm_stat_account(mm, vma->vm_flags, pages); - if (vma->vm_flags & VM_LOCKED) { + if (vma->vm_flags & VM_LOCKED) mm->locked_vm += pages; - vrm->mlocked = true; - } } /* @@ -1660,6 +1658,10 @@ static int check_prep_vma(struct vma_remap_struct *vrm) if (new_len == old_len) return 0; + /* We are expanding and the VMA is mlock()'d so we need to populate. */ + if (vma->vm_flags & VM_LOCKED) + vrm->populate_expand = true; + /* Need to be careful about a growing mapping */ pgoff = (addr - vma->vm_start) >> PAGE_SHIFT; pgoff += vma->vm_pgoff; @@ -1780,7 +1782,8 @@ static unsigned long do_mremap(struct vma_remap_struct *vrm) if (vrm->mmap_locked) mmap_write_unlock(mm); - if (!failed && vrm->mlocked && vrm->new_len > vrm->old_len) + /* VMA mlock'd + was expanded, so populated expanded region. */ + if (!failed && vrm->populate_expand) mm_populate(vrm->new_addr + vrm->old_len, vrm->delta); notify_uffd(vrm, failed);