From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3641C215197 for ; Mon, 17 Mar 2025 05:10:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742188219; cv=none; b=Hc7Pu6gj6aBQa4q/lsO6sHKes3dGWB9sXXRjGqykz2vNiXMjcpNw/zqkBJkoPiSg6iVtSwAu5lN0FTyAk+MVsltUPwqIxPRPsI2lOkmod9ZT+ofRGULXu6bMurJQ+/LpCHcItZ1rUPrJ7T09IEYduuGh1U8nCddVxs4dGzCBq3A= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742188219; c=relaxed/simple; bh=TjaRvRl39c+kApJJCeaOB7Ei5ia6RFEgfzcmwu0Ckhk=; h=Date:To:From:Subject:Message-Id; b=t+0rFZjQ7ibGlVK74nD1UedA5VljspccQ/w+TffzDKeLvLHpMhlY5icSVNGCpGPa+elqq910YsmzrRKMU3dThSpSPzz54vCD17gXiLfaHAWeUw52Nn8vQwUoSaYF3yfu79z+jEEy/O5Tn5sGgNKwtLl5doz4gXslyi5goHc8RiY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b=NTFx+HwP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux-foundation.org header.i=@linux-foundation.org header.b="NTFx+HwP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0AFE2C4CEEC; Mon, 17 Mar 2025 05:10:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linux-foundation.org; s=korg; t=1742188219; bh=TjaRvRl39c+kApJJCeaOB7Ei5ia6RFEgfzcmwu0Ckhk=; h=Date:To:From:Subject:From; b=NTFx+HwPQv4ocmn+FGgiYK0dQXDAH0JQqjV54bZbi4x53D949E+tKeabFI18nPHU3 KEe4ffnzMHfkoqxunRlB7M6QRGlsOgFwpNvia3f9Y4eOpWp3WXe9qDIojAzUnzy38F lR6iBsInppkevwyGFQfWJAz2DfoSxoOSo6h2DzzY= Date: Sun, 16 Mar 2025 22:10:18 -0700 To: mm-commits@vger.kernel.org,vbabka@suse.cz,liam.howlett@oracle.com,jannh@google.com,lorenzo.stoakes@oracle.com,akpm@linux-foundation.org From: Andrew Morton Subject: [merged mm-stable] mm-make-vmg-target-consistent-and-further-simplify-commit_merge.patch removed from -mm tree Message-Id: <20250317051019.0AFE2C4CEEC@smtp.kernel.org> Precedence: bulk X-Mailing-List: mm-commits@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: The quilt patch titled Subject: mm: make vmg->target consistent and further simplify commit_merge() has been removed from the -mm tree. Its filename was mm-make-vmg-target-consistent-and-further-simplify-commit_merge.patch This patch was dropped because it was merged into the mm-stable branch of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm ------------------------------------------------------ From: Lorenzo Stoakes Subject: mm: make vmg->target consistent and further simplify commit_merge() Date: Fri, 31 Jan 2025 12:31:52 +0000 It is confusing for vmg->target to sometimes be the target merged VMA and in one case not. Fix this by having commit_merge() use its awareness of the vmg->_adjust_next_start case to know that it is manipulating a separate vma, abstracted in the 'vma' local variable. Place removal and adjust VMA determination logic into init_multi_vma_prep(), as the flags give us enough information to do so, and since this is the function that sets up the vma_prepare struct it makes sense to do so here. Doing this significantly simplifies commit_merge(), allowing us to eliminate the 'merge_target' handling, initialise the VMA iterator in a more sensible place and simply return vmg->target consistently. This also allows us to simplify setting vmg->target in vma_merge_existing_range() since we are then left only with two cases - merge left (or both) where the target is vmg->prev or merge right in which the target is vmg->next. This makes it easy for somebody reading the code to know what VMA will actually be the one returned and merged into and removes a great deal of the confusing 'adjust' nonsense. This patch has no change in functional behaviour. Link: https://lkml.kernel.org/r/50f96e31ab1980eaaf1006e34a4f6e6dad9320b8.1738326519.git.lorenzo.stoakes@oracle.com Signed-off-by: Lorenzo Stoakes Reviewed-by: Vlastimil Babka Cc: Jann Horn Cc: Liam Howlett Signed-off-by: Andrew Morton --- mm/vma.c | 119 +++++++++++++++++++++++++++-------------------------- mm/vma.h | 6 -- 2 files changed, 62 insertions(+), 63 deletions(-) --- a/mm/vma.c~mm-make-vmg-target-consistent-and-further-simplify-commit_merge +++ a/mm/vma.c @@ -106,24 +106,40 @@ static inline bool are_anon_vmas_compati * init_multi_vma_prep() - Initializer for struct vma_prepare * @vp: The vma_prepare struct * @vma: The vma that will be altered once locked - * @next: The next vma if it is to be adjusted - * @remove: The first vma to be removed - * @remove2: The second vma to be removed + * @vmg: The merge state that will be used to determine adjustment and VMA + * removal. */ static void init_multi_vma_prep(struct vma_prepare *vp, struct vm_area_struct *vma, - struct vm_area_struct *next, - struct vm_area_struct *remove, - struct vm_area_struct *remove2) + struct vma_merge_struct *vmg) { + struct vm_area_struct *adjust; + struct vm_area_struct **remove = &vp->remove; + memset(vp, 0, sizeof(struct vma_prepare)); vp->vma = vma; vp->anon_vma = vma->anon_vma; - vp->remove = remove ? remove : remove2; - vp->remove2 = remove ? remove2 : NULL; - vp->adj_next = next; - if (!vp->anon_vma && next) - vp->anon_vma = next->anon_vma; + + if (vmg && vmg->__remove_middle) { + *remove = vmg->middle; + remove = &vp->remove2; + } + if (vmg && vmg->__remove_next) + *remove = vmg->next; + + if (vmg && vmg->__adjust_middle_start) + adjust = vmg->middle; + else if (vmg && vmg->__adjust_next_start) + adjust = vmg->next; + else + adjust = NULL; + + vp->adj_next = adjust; + if (!vp->anon_vma && adjust) + vp->anon_vma = adjust->anon_vma; + + VM_WARN_ON(vp->anon_vma && adjust && adjust->anon_vma && + vp->anon_vma != adjust->anon_vma); vp->file = vma->vm_file; if (vp->file) @@ -360,7 +376,7 @@ again: */ static void init_vma_prep(struct vma_prepare *vp, struct vm_area_struct *vma) { - init_multi_vma_prep(vp, vma, NULL, NULL, NULL); + init_multi_vma_prep(vp, vma, NULL); } /* @@ -634,76 +650,63 @@ void validate_mm(struct mm_struct *mm) */ static struct vm_area_struct *commit_merge(struct vma_merge_struct *vmg) { - struct vm_area_struct *remove = NULL; - struct vm_area_struct *remove2 = NULL; + struct vm_area_struct *vma; struct vma_prepare vp; - struct vm_area_struct *adjust = NULL; + struct vm_area_struct *adjust; long adj_start; - bool merge_target; /* * If modifying an existing VMA and we don't remove vmg->middle, then we * shrink the adjacent VMA. */ if (vmg->__adjust_middle_start) { + vma = vmg->target; adjust = vmg->middle; /* The POSITIVE value by which we offset vmg->middle->vm_start. */ adj_start = vmg->end - vmg->middle->vm_start; - merge_target = true; + + /* Note: vma iterator must be pointing to 'start'. */ + vma_iter_config(vmg->vmi, vmg->start, vmg->end); } else if (vmg->__adjust_next_start) { + /* + * In this case alone, the VMA we manipulate is vmg->middle, but + * we ultimately return vmg->next. + */ + vma = vmg->middle; adjust = vmg->next; /* The NEGATIVE value by which we offset vmg->next->vm_start. */ adj_start = -(vmg->middle->vm_end - vmg->end); - /* - * In all cases but this - merge right, shrink next - we write - * vmg->target to the maple tree and return this as the merged VMA. - */ - merge_target = false; + + vma_iter_config(vmg->vmi, vmg->next->vm_start + adj_start, + vmg->next->vm_end); } else { + vma = vmg->target; adjust = NULL; adj_start = 0; - merge_target = true; - } - - if (vmg->__remove_middle) - remove = vmg->middle; - if (vmg->__remove_next) - remove2 = vmg->next; - - init_multi_vma_prep(&vp, vmg->target, adjust, remove, remove2); - VM_WARN_ON(vp.anon_vma && adjust && adjust->anon_vma && - vp.anon_vma != adjust->anon_vma); - - if (merge_target) { - /* Note: vma iterator must be pointing to 'start'. */ + /* Note: vma iterator must be pointing to 'start'. */ vma_iter_config(vmg->vmi, vmg->start, vmg->end); - } else { - vma_iter_config(vmg->vmi, adjust->vm_start + adj_start, - adjust->vm_end); } - if (vma_iter_prealloc(vmg->vmi, vmg->target)) + init_multi_vma_prep(&vp, vma, vmg); + + if (vma_iter_prealloc(vmg->vmi, vma)) return NULL; vma_prepare(&vp); - vma_adjust_trans_huge(vmg->target, vmg->start, vmg->end, adj_start); - vma_set_range(vmg->target, vmg->start, vmg->end, vmg->pgoff); - - if (merge_target) - vma_iter_store(vmg->vmi, vmg->target); + vma_adjust_trans_huge(vma, vmg->start, vmg->end, adj_start); + vma_set_range(vma, vmg->start, vmg->end, vmg->pgoff); if (adj_start) { adjust->vm_start += adj_start; adjust->vm_pgoff += PHYS_PFN(adj_start); - - if (!merge_target) - vma_iter_store(vmg->vmi, adjust); } - vma_complete(&vp, vmg->vmi, vmg->target->vm_mm); + vma_iter_store(vmg->vmi, vmg->target); + + vma_complete(&vp, vmg->vmi, vma->vm_mm); - return merge_target ? vmg->target : vmg->next; + return vmg->target; } /* We can only remove VMAs when merging if they do not have a close hook. */ @@ -833,11 +836,15 @@ static __must_check struct vm_area_struc /* No matter what happens, we will be adjusting middle. */ vma_start_write(middle); - if (merge_left) - vma_start_write(prev); - - if (merge_right) + if (merge_right) { vma_start_write(next); + vmg->target = next; + } + + if (merge_left) { + vma_start_write(prev); + vmg->target = prev; + } if (merge_both) { /* @@ -847,7 +854,6 @@ static __must_check struct vm_area_struc * extend delete delete */ - vmg->target = prev; vmg->start = prev->vm_start; vmg->end = next->vm_end; vmg->pgoff = prev->vm_pgoff; @@ -868,7 +874,6 @@ static __must_check struct vm_area_struc * extend shrink/delete */ - vmg->target = prev; vmg->start = prev->vm_start; vmg->pgoff = prev->vm_pgoff; @@ -892,7 +897,6 @@ static __must_check struct vm_area_struc VM_WARN_ON_VMG(vmg->start > middle->vm_start && prev && middle != prev, vmg); if (vmg->__remove_middle) { - vmg->target = next; vmg->end = next->vm_end; vmg->pgoff = next->vm_pgoff - pglen; } else { @@ -903,7 +907,6 @@ static __must_check struct vm_area_struc * merged VMA is NOT vmg->target, but rather vmg->next. */ vmg->__adjust_next_start = true; - vmg->target = middle; vmg->start = middle->vm_start; vmg->end = start; vmg->pgoff = middle->vm_pgoff; --- a/mm/vma.h~mm-make-vmg-target-consistent-and-further-simplify-commit_merge +++ a/mm/vma.h @@ -82,11 +82,7 @@ struct vma_merge_struct { struct vm_area_struct *prev; struct vm_area_struct *middle; struct vm_area_struct *next; - /* - * This is the VMA we ultimately target to become the merged VMA, except - * for the one exception of merge right, shrink next (for details of - * this scenario see vma_merge_existing_range()). - */ + /* This is the VMA we ultimately target to become the merged VMA. */ struct vm_area_struct *target; /* * Initially, the start, end, pgoff fields are provided by the caller _ Patches currently in -mm which might be from lorenzo.stoakes@oracle.com are mm-mremap-correctly-handle-partial-mremap-of-vma-starting-at-0.patch mm-mremap-refactor-mremap-system-call-implementation.patch mm-mremap-introduce-and-use-vma_remap_struct-threaded-state.patch mm-mremap-initial-refactor-of-move_vma.patch mm-mremap-complete-refactor-of-move_vma.patch mm-mremap-refactor-move_page_tables-abstracting-state.patch mm-mremap-thread-state-through-move-page-table-operation.patch