Merge: mm, mremap: fix mremap() expanding for vma's with vm_ops->close()
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/3206 Upstream commit ca3d76b0aa80 was backported in RHEL-9.2 as commit8c20bfd27e
. This causes a failure when multiple threads within a process try to expand an mmap, and mremap tries to merge the adjacent vma's. RHEL-9.3 backported one fix from upstream v6.2-rc1, 6f12be792fde as RHEL-9.3 commit0517036a0e
, as part of the 100+, RHEL-9.3 Proactive MM fixes. In researching this reported bug, another Fixes patch for ca3d76b0aa80 was found from v6.2-rc7, d014cd7c1c35. So, this MR is backporting this fix, which will be z-streamed into 9.3; after which it will be z-streamed into 9.2 along with 9.3's0517036a0e
commit, so 9.2 is completely repaired. A test program was provided in Jira RHEL-9198 to show the bug, and was used to replicate the bug on a VM, and to demonstrate its repair first in 9.3, then with this added commit. A long term test on a SQL application by a large fintech company reported seeing another vma-merge problem that has the signature that this MR repairs. The test program will be included in future kernel-mm testing as a means to regression test mmap-based, vma-merge logic. Please review, approve & merge into 9.4 asap, as OpenShift and the large fintech customer are anxiously awaiting the zstream-ing of the needed patches to 9.2. JIRA: https://issues.redhat.com/browse/RHEL-9198 Signed-off-by: Donald Dutile <ddutile@redhat.com> Approved-by: Chris von Recklinghausen <crecklin@redhat.com> Approved-by: Rafael Aquini <aquini@redhat.com> Signed-off-by: Scott Weaver <scweaver@redhat.com>
This commit is contained in:
commit
38f8d79078
25
mm/mremap.c
25
mm/mremap.c
|
@ -1035,16 +1035,29 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
|
|||
}
|
||||
|
||||
/*
|
||||
* Function vma_merge() is called on the extension we are adding to
|
||||
* the already existing vma, vma_merge() will merge this extension with
|
||||
* the already existing vma (expand operation itself) and possibly also
|
||||
* with the next vma if it becomes adjacent to the expanded vma and
|
||||
* otherwise compatible.
|
||||
* Function vma_merge() is called on the extension we
|
||||
* are adding to the already existing vma, vma_merge()
|
||||
* will merge this extension with the already existing
|
||||
* vma (expand operation itself) and possibly also with
|
||||
* the next vma if it becomes adjacent to the expanded
|
||||
* vma and otherwise compatible.
|
||||
*
|
||||
* However, vma_merge() can currently fail due to
|
||||
* is_mergeable_vma() check for vm_ops->close (see the
|
||||
* comment there). Yet this should not prevent vma
|
||||
* expanding, so perform a simple expand for such vma.
|
||||
* Ideally the check for close op should be only done
|
||||
* when a vma would be actually removed due to a merge.
|
||||
*/
|
||||
vma = vma_merge(mm, vma, extension_start, extension_end,
|
||||
if (!vma->vm_ops || !vma->vm_ops->close) {
|
||||
vma = vma_merge(mm, vma, extension_start, extension_end,
|
||||
vma->vm_flags, vma->anon_vma, vma->vm_file,
|
||||
extension_pgoff, vma_policy(vma),
|
||||
vma->vm_userfaultfd_ctx, anon_vma_name(vma));
|
||||
} else if (vma_adjust(vma, vma->vm_start, addr + new_len,
|
||||
vma->vm_pgoff, NULL)) {
|
||||
vma = NULL;
|
||||
}
|
||||
if (!vma) {
|
||||
vm_unacct_memory(pages);
|
||||
ret = -ENOMEM;
|
||||
|
|
Loading…
Reference in New Issue