From patchwork Sun Oct 8 20:23:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Stoakes X-Patchwork-Id: 13412798 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3B5D3E95A90 for ; Sun, 8 Oct 2023 20:23:34 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id EAB2E6B016B; Sun, 8 Oct 2023 16:23:29 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id E65DA6B017C; Sun, 8 Oct 2023 16:23:29 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id C5F376B0187; Sun, 8 Oct 2023 16:23:29 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id AFCAD6B016B for ; Sun, 8 Oct 2023 16:23:29 -0400 (EDT) Received: from smtpin12.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 8EE671601B2 for ; Sun, 8 Oct 2023 20:23:29 +0000 (UTC) X-FDA: 81323419338.12.F67FDFE Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) by imf30.hostedemail.com (Postfix) with ESMTP id C21A680004 for ; Sun, 8 Oct 2023 20:23:27 +0000 (UTC) Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=iBzQFaVf; spf=pass (imf30.hostedemail.com: domain of lstoakes@gmail.com designates 209.85.128.42 as permitted sender) smtp.mailfrom=lstoakes@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1696796607; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=VCWwJGD+i6SLQnaAJLGE5OXPFaOejL4paLAiGQJbd2k=; b=LJLpRVH/38rzZJs1dXJ7HYcx2QWjBWugSPs2DFRYCHDxQQrH7ECCraq0xQcXkZ9j2nsetV /HUOVJBkjXAV89xa7IDLokSowR2Sd4AwBdT/+UNjKVtirnRPnqgA2CL5ToA7as02qMhaP1 dbl2MylDZeJdBJO6wvj6uQuVC91qbuU= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=iBzQFaVf; spf=pass (imf30.hostedemail.com: domain of lstoakes@gmail.com designates 209.85.128.42 as permitted sender) smtp.mailfrom=lstoakes@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1696796607; a=rsa-sha256; cv=none; b=py9Qbxi5qR16qWSVgSRZX793zZ6kDPDriQ3Q7twi2Dn71wJ3ZJw58oCDS8JtjQijjSDbBX L3mam5R4eZWnYmJR2xfCKlXdHgsFM4BVtKqT+0NW1UO/580lRXNlFOxHwluDeLmDeBogEc NC9LKtsyvg3GbNdPv/LOaykBqpzRxsw= Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-405505b07dfso28738595e9.0 for ; Sun, 08 Oct 2023 13:23:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696796606; x=1697401406; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=VCWwJGD+i6SLQnaAJLGE5OXPFaOejL4paLAiGQJbd2k=; b=iBzQFaVfSl8nHkciUO1LbHPRLM1/O/myQlJipwcVFDSOWh/u2jr3LqAVAEq5/L4jPF I6s0/0RDJkIeGEKVOHHUemdLxlmuvC2xtnTvhLyLru3VLF4WTMG8qRB19NsJkOWBXKDV XOkNPt+Yj2xP0tQPwbRllT0CFapQCUk/yIBHJXbg1hS852g2CSzKg5ExTl4A4g3PPth0 EfesEAJrExWjeYTg+Bbx0X3q6lD9Ufl8lvUNg5Bhpb4Wbu8SlD5c8ecqXSHbcAF5VkDN aa6y76JVaeL0N73kbdpzGow62x965LkvfLSp41BXp45MlDXNg4yEGhdkz0mpo/D9/Tro qmYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696796606; x=1697401406; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VCWwJGD+i6SLQnaAJLGE5OXPFaOejL4paLAiGQJbd2k=; b=b834yVX6sNbLEgsjAXSH0i2y1xeqQMxE06sQ7gQHlXABCHCcuH1J99JxUfCbZ3CaJ6 34aLSx3D/MAWcRYpShGBdBMB0/eZYIGdmTmPx/CPU7vuTaG/d5p6kmrdwUpQ9kpk3ztZ 5cBGqdaRGUmvj6YV357cf7uvZNJyrxKRzNapfvsX3MmtBLDIeguACrlTd+fVEUKDQVj6 0VKlAUY0MJWZImKHNQzqOpihVkCL0jFjaoBtMy8LjArUbRsFwr+54l+esPRjDSsOkzLF Q+uQ46HR5INgm1Tfy3BIavfZ/o2DuCEJ9CsrZdA/kLxpIPEqG0lJzB79mhKWCz6PMPam VsWQ== X-Gm-Message-State: AOJu0YzVN5xyIbeBmgmPEdQ9NsP+I/5BzfxaxjHz0OQ5CRMHgFUeEzwg +H+pvfBxcWG84s7/IB2QSou1Dk3K2dc= X-Google-Smtp-Source: AGHT+IFCA87467gu7z5IDWce4HL8A128HwTPWTaB+9+eEVOi6NwgXaeueapZGaEywr2dFnR51gtXgg== X-Received: by 2002:a05:6000:1112:b0:317:6734:c2ae with SMTP id z18-20020a056000111200b003176734c2aemr7884139wrw.11.1696796606069; Sun, 08 Oct 2023 13:23:26 -0700 (PDT) Received: from lucifer.home ([2a00:23c5:dc8c:8701:1663:9a35:5a7b:1d76]) by smtp.googlemail.com with ESMTPSA id c5-20020a05600c0ac500b0040586360a36sm11474879wmr.17.2023.10.08.13.23.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Oct 2023 13:23:25 -0700 (PDT) From: Lorenzo Stoakes To: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Andrew Morton , Alexander Viro , Christian Brauner Cc: "=Liam R . Howlett" , Vlastimil Babka , linux-fsdevel@vger.kernel.org, Lorenzo Stoakes Subject: [PATCH 4/4] mm: abstract VMA extension and merge into vma_merge_extend() helper Date: Sun, 8 Oct 2023 21:23:16 +0100 Message-ID: <1ed3d1ba0069104e1685298aa2baf980c38a85ff.1696795837.git.lstoakes@gmail.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: References: MIME-Version: 1.0 X-Rspamd-Queue-Id: C21A680004 X-Rspam-User: X-Stat-Signature: fqppwa7wf5tin1i1ay1ficnecbgr43xx X-Rspamd-Server: rspam01 X-HE-Tag: 1696796607-513016 X-HE-Meta: U2FsdGVkX19JA7sVKDEVnkwIVDing+dQ7tkrZ0mk7juVJ08l84TA+2G0rInejfB4awTZ9W3nminD5WAcx1WhP312/+GbipjBWs2XDgxMuvhXOSrtX/HHdZV7Nm12z9BW+mxqSgmESWgGByqtuaXlfBbYqfPU46WInZVFUYLZW/B4mWT9s+uAVY/UOqJd6l7SeqyNG61gu8Zr+kN5DBlT/R5SbQvQarpeRvBoWICMCyC7HAcsLe55IlA0hTGnHbJnAKDKYWthngA1evhGEq0nfbfsEpkzxgZIrRRTQTbvDFVTBke19LMPusAbVYwhIy1UCTL8CiBDOGZG+GsOk2Y8t9iVDk9WOpLgkIqKG9TOuOOK+gRH3gmrpsWdOd8rlfZEKstK6TIUdyF+3wGjCtLvSfwosNqnH7gSu4QvlyETgVOc8ywpgANBs2eFTENEhbNogZP8HVA4sdJMieuuF7ofd4fak9/g1OXSk7Cj6hWenVjknJ1PAMOwVzcnuSsuJlc9rHkzLclzkEZG5OpN2BtqSugYOPtoGHq6GAbrhSB19FAfyTZnZtEOv2GjpNcjS8GuYrZg1Tpk/5GqdJw0G3MBDNbDwVt4pSdOLh0PpAJKDLFUTyyrdVrAJhGgU0t/iOuUGk8T0V17xxel7apTCJRJRfL6K/NkHViO0nyBzNAxmtzzPw27t46Zfa5C2tljIYgYhgmRvc/aYeg+4609sDeKLgbecQczD0P3Iv5LGSfJejj5lxECikBP6Wq5b16j1WtB6iS30borx5mwQmuy48yMOW2FcAr/czyPrUrVabXvT4zeSuZgzsqEWQfPZHB90fA/1kndAna9k1txddo0PlIko0m/SNPWlUyvBcP8Zuzu2rAbdoUS7YcjFys5kcPzkxY5jgn6n+lOHXokdxoi0xx7pUWZxd+gUnKVsXzDSyBpUCbeatHbza8jnDwEmH6TNpQfkav/O0beD0Bhgt3VW0T yoe8Zcqs UzH12ne/RA5JdSrIGbjCdevU7LXqnUsnMPkmrsqHXQ574Z5DywogwVxse5DttfvgwyUWhQmpZX3N78HeOJRBgxbjiW1xL8qojK7oKktomKQone99KHI1HCmK/Nbh/PDToSwWSxKZ+aPNv7YIfZmvCxu4ekqnqK+LRMStKP4RJCiHfyc7vgsMh9J611OWtKmXrqlUCZTwPqY740bpCNP3kixAW9+KrTRSRdB2whowotnvLr3668owSB7o0I+yM5jDzstuJJuwT4YdbHZJUUGzLO96nBdpukf31qBSvL0mC03aseUkZQDvqqiYGz72B4qtV2350diQ+XjXR1AH7TR6yeZKRsCvzVDywVk8A355Udt1Pvq0p7Nm5tNgQ6hDs37cspYrdMe5eu2pH+yN1ivzaCYv12X9AIh32IdVjtNu35EaOl7AGY8A0Xw2KwK0B5OdM7SQAfdBxjOXh8tFLXAJAvowI5BV8EvZlIx1C X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: mremap uses vma_merge() in the case where a VMA needs to be extended. This can be significantly simplified and abstracted. This makes it far easier to understand what the actual function is doing, avoids future mistakes in use of the confusing vma_merge() function and importantly allows us to make future changes to how vma_merge() is implemented by knowing explicitly which merge cases each invocation uses. Note that in the mremap() extend case, we perform this merge only when old_len == vma->vm_end - addr. The extension_start, i.e. the start of the extended portion of the VMA is equal to addr + old_len, i.e. vma->vm_end. With this refactoring, vma_merge() is no longer required anywhere except mm/mmap.c, so mark it static. Signed-off-by: Lorenzo Stoakes Reviewed-by: Vlastimil Babka --- mm/internal.h | 8 +++----- mm/mmap.c | 32 +++++++++++++++++++++++++------- mm/mremap.c | 30 +++++++++++++----------------- 3 files changed, 41 insertions(+), 29 deletions(-) diff --git a/mm/internal.h b/mm/internal.h index ddaeb9f2d9d7..6fa722b07a94 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -1014,11 +1014,9 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, /* * mm/mmap.c */ -struct vm_area_struct *vma_merge(struct vma_iterator *vmi, - struct mm_struct *, struct vm_area_struct *prev, unsigned long addr, - unsigned long end, unsigned long vm_flags, struct anon_vma *, - struct file *, pgoff_t, struct mempolicy *, struct vm_userfaultfd_ctx, - struct anon_vma_name *); +struct vm_area_struct *vma_merge_extend(struct vma_iterator *vmi, + struct vm_area_struct *vma, + unsigned long delta); enum { /* mark page accessed */ diff --git a/mm/mmap.c b/mm/mmap.c index 51be864b876b..5d2f2e8d7307 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -860,13 +860,13 @@ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, * **** is not represented - it will be merged and the vma containing the * area is returned, or the function will return NULL */ -struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm, - struct vm_area_struct *prev, unsigned long addr, - unsigned long end, unsigned long vm_flags, - struct anon_vma *anon_vma, struct file *file, - pgoff_t pgoff, struct mempolicy *policy, - struct vm_userfaultfd_ctx vm_userfaultfd_ctx, - struct anon_vma_name *anon_name) +static struct vm_area_struct +*vma_merge(struct vma_iterator *vmi, struct mm_struct *mm, + struct vm_area_struct *prev, unsigned long addr, unsigned long end, + unsigned long vm_flags, struct anon_vma *anon_vma, struct file *file, + pgoff_t pgoff, struct mempolicy *policy, + struct vm_userfaultfd_ctx vm_userfaultfd_ctx, + struct anon_vma_name *anon_name) { struct vm_area_struct *curr, *next, *res; struct vm_area_struct *vma, *adjust, *remove, *remove2; @@ -2546,6 +2546,24 @@ static struct vm_area_struct *vma_merge_new_vma(struct vma_iterator *vmi, vma->vm_userfaultfd_ctx, anon_vma_name(vma)); } +/* + * Expand vma by delta bytes, potentially merging with an immediately adjacent + * VMA with identical properties. + */ +struct vm_area_struct *vma_merge_extend(struct vma_iterator *vmi, + struct vm_area_struct *vma, + unsigned long delta) +{ + pgoff_t pgoff = vma->vm_pgoff + + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT); + + /* vma is specified as prev, so case 1 or 2 will apply. */ + return vma_merge(vmi, vma->vm_mm, vma, vma->vm_end, vma->vm_end + delta, + vma->vm_flags, vma->anon_vma, vma->vm_file, pgoff, + vma_policy(vma), vma->vm_userfaultfd_ctx, + anon_vma_name(vma)); +} + /* * do_vmi_align_munmap() - munmap the aligned region from @start to @end. * @vmi: The vma iterator diff --git a/mm/mremap.c b/mm/mremap.c index ce8a23ef325a..38d98465f3d8 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -1096,14 +1096,12 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, /* old_len exactly to the end of the area.. */ if (old_len == vma->vm_end - addr) { + unsigned long delta = new_len - old_len; + /* can we just expand the current mapping? */ - if (vma_expandable(vma, new_len - old_len)) { - long pages = (new_len - old_len) >> PAGE_SHIFT; - unsigned long extension_start = addr + old_len; - unsigned long extension_end = addr + new_len; - pgoff_t extension_pgoff = vma->vm_pgoff + - ((extension_start - vma->vm_start) >> PAGE_SHIFT); - VMA_ITERATOR(vmi, mm, extension_start); + if (vma_expandable(vma, delta)) { + long pages = delta >> PAGE_SHIFT; + VMA_ITERATOR(vmi, mm, vma->vm_end); long charged = 0; if (vma->vm_flags & VM_ACCOUNT) { @@ -1115,17 +1113,15 @@ 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_extend() is called on the + * extension we are adding to the already existing vma, + * vma_merge_extend() 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. */ - vma = vma_merge(&vmi, 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)); + vma = vma_merge_extend(&vmi, vma, delta); if (!vma) { vm_unacct_memory(charged); ret = -ENOMEM;