From patchwork Thu May 4 21:27:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lorenzo Stoakes X-Patchwork-Id: 13231848 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 EF1CEC7EE29 for ; Thu, 4 May 2023 21:28:03 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 097BA6B0078; Thu, 4 May 2023 17:28:03 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id F3BFE6B007B; Thu, 4 May 2023 17:28:02 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id DB69E6B007D; Thu, 4 May 2023 17:28:02 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) by kanga.kvack.org (Postfix) with ESMTP id 899CD6B0078 for ; Thu, 4 May 2023 17:28:02 -0400 (EDT) Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-3f315712406so78837595e9.0 for ; Thu, 04 May 2023 14:28:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1683235681; x=1685827681; 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=qkndhYeKpdj265qSAWGVggIskUvt1UIo0+mdAihYUxw=; b=AteVRjKUbfb+r9a5MwmSJz52Wmk7nfvL2lLANu4qx3OoPEX4FJMC9P24blVvL9cJjT OkVTnGWwzhebc6uan6QVemWa/27AZspCXqPV6r+WIgwWPRAzoNPNu5PiMPI+8evUQtcS KGQX6bzuw7iDXbCgjyrVwry2YNqRe+iYpkEFDCjB9wq/nn9oFsxAPB6CSLHujtfhz176 oT3yX4jmz2MaVgFF9lvB4RPVvln76a8cuESYaaQm/b8AV+brrNItdtIzinYmbDtltWrA YhOxHXkhh1ZZll/EuP3yHv5DVDGreaRiKo0VI6c2281o8cnjHSULah3iJQlKpBOz1uf2 HrJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683235681; x=1685827681; 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=qkndhYeKpdj265qSAWGVggIskUvt1UIo0+mdAihYUxw=; b=hManAoYPkWnZjg8jF1Xamo8mM3UMxA1S5PRsydLGy/YwvylubBuuaCeHoFmtJjlUJQ g41qd/uBX7IJg9RHfXMF6dlQZ3Fnd5T0jjkqZmo153z8TpZzxeGdlhHHsbtUrL1UrmzH f3BgHQZy9R1uin4Vagf87ijrKa9iB4Edv14trZv1EyVPNqJhBqrHBDx0Ghx691kpBd12 2+u2VubzSQBG6AMy86jaX6ZcVf4WMb3nsuJ2MlhO/2x1Wa1JrD21W1pGuh45+qbdcng2 +EQWL/7tb1pcjociT8Ych37DBi8NYg2wpXxIRGF4lcCwwWVjXJdnQKZFNMbWSgKnc1Cm vXOA== X-Gm-Message-State: AC+VfDyCRQEgYbSX6qdu0ZWjV4FkW8q2zaQDbX917CcyJU1g2UTRP3PX MB3BOaSoVjMHf2HeYxynqZNBzXF22olATQ== X-Google-Smtp-Source: ACHHUZ7XJTWUqV1QKPwzQJmoCOnjvVDrmgLrIWoBnpZBrbofmSjOveRFSeqhevMmXudNjoinNCM53g== X-Received: by 2002:a1c:c906:0:b0:3f1:72d8:a1b1 with SMTP id f6-20020a1cc906000000b003f172d8a1b1mr151060wmb.7.1683235681054; Thu, 04 May 2023 14:28:01 -0700 (PDT) Received: from lucifer.home (host86-156-84-164.range86-156.btcentralplus.com. [86.156.84.164]) by smtp.googlemail.com with ESMTPSA id h15-20020a05600c314f00b003f1978bbcd6sm51617562wmo.3.2023.05.04.14.27.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 May 2023 14:28:00 -0700 (PDT) From: Lorenzo Stoakes To: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Andrew Morton Cc: Jason Gunthorpe , Jens Axboe , Matthew Wilcox , Dennis Dalessandro , Leon Romanovsky , Christian Benvenuti , Nelson Escobar , Bernard Metzler , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Bjorn Topel , Magnus Karlsson , Maciej Fijalkowski , Jonathan Lemon , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Christian Brauner , Richard Cochran , Alexei Starovoitov , Daniel Borkmann , Jesper Dangaard Brouer , John Fastabend , linux-fsdevel@vger.kernel.org, linux-perf-users@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, Oleg Nesterov , Jason Gunthorpe , John Hubbard , Jan Kara , "Kirill A . Shutemov" , Pavel Begunkov , Mika Penttila , David Hildenbrand , Dave Chinner , Theodore Ts'o , Peter Xu , Matthew Rosato , "Paul E . McKenney" , Christian Borntraeger , Lorenzo Stoakes Subject: [PATCH v9 1/3] mm/mmap: separate writenotify and dirty tracking logic Date: Thu, 4 May 2023 22:27:51 +0100 Message-Id: <0f218370bd49b4e6bbfbb499f7c7b92c26ba1ceb.1683235180.git.lstoakes@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 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: vma_wants_writenotify() is specifically intended for setting PTE page table flags, accounting for existing page table flag state and whether the underlying filesystem performs dirty tracking for a file-backed mapping. Everything is predicated firstly on whether the mapping is shared writable, as this is the only instance where dirty tracking is pertinent - MAP_PRIVATE mappings will always be CoW'd and unshared, and read-only file-backed shared mappings cannot be written to, even with FOLL_FORCE. All other checks are in line with existing logic, though now separated into checks eplicitily for dirty tracking and those for determining how to set page table flags. We make this change so we can perform checks in the GUP logic to determine which mappings might be problematic when written to. Signed-off-by: Lorenzo Stoakes Reviewed-by: John Hubbard Reviewed-by: Mika Penttilä Reviewed-by: Jan Kara Reviewed-by: Jason Gunthorpe Acked-by: David Hildenbrand --- include/linux/mm.h | 1 + mm/mmap.c | 58 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 27ce77080c79..7b1d4e7393ef 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2422,6 +2422,7 @@ extern unsigned long move_page_tables(struct vm_area_struct *vma, #define MM_CP_UFFD_WP_ALL (MM_CP_UFFD_WP | \ MM_CP_UFFD_WP_RESOLVE) +bool vma_needs_dirty_tracking(struct vm_area_struct *vma); int vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot); static inline bool vma_wants_manual_pte_write_upgrade(struct vm_area_struct *vma) { diff --git a/mm/mmap.c b/mm/mmap.c index 13678edaa22c..8ef5929057fc 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1475,6 +1475,48 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg) } #endif /* __ARCH_WANT_SYS_OLD_MMAP */ +static bool vm_ops_needs_writenotify(const struct vm_operations_struct *vm_ops) +{ + return vm_ops && (vm_ops->page_mkwrite || vm_ops->pfn_mkwrite); +} + +static bool vma_is_shared_writable(struct vm_area_struct *vma) +{ + return (vma->vm_flags & (VM_WRITE | VM_SHARED)) == + (VM_WRITE | VM_SHARED); +} + +static bool vma_fs_can_writeback(struct vm_area_struct *vma) +{ + /* No managed pages to writeback. */ + if (vma->vm_flags & VM_PFNMAP) + return false; + + return vma->vm_file && vma->vm_file->f_mapping && + mapping_can_writeback(vma->vm_file->f_mapping); +} + +/* + * Does this VMA require the underlying folios to have their dirty state + * tracked? + */ +bool vma_needs_dirty_tracking(struct vm_area_struct *vma) +{ + /* Only shared, writable VMAs require dirty tracking. */ + if (!vma_is_shared_writable(vma)) + return false; + + /* Does the filesystem need to be notified? */ + if (vm_ops_needs_writenotify(vma->vm_ops)) + return true; + + /* + * Even if the filesystem doesn't indicate a need for writenotify, if it + * can writeback, dirty tracking is still required. + */ + return vma_fs_can_writeback(vma); +} + /* * Some shared mappings will want the pages marked read-only * to track write events. If so, we'll downgrade vm_page_prot @@ -1483,21 +1525,18 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg) */ int vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot) { - vm_flags_t vm_flags = vma->vm_flags; - const struct vm_operations_struct *vm_ops = vma->vm_ops; - /* If it was private or non-writable, the write bit is already clear */ - if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED))) + if (!vma_is_shared_writable(vma)) return 0; /* The backer wishes to know when pages are first written to? */ - if (vm_ops && (vm_ops->page_mkwrite || vm_ops->pfn_mkwrite)) + if (vm_ops_needs_writenotify(vma->vm_ops)) return 1; /* The open routine did something to the protections that pgprot_modify * won't preserve? */ if (pgprot_val(vm_page_prot) != - pgprot_val(vm_pgprot_modify(vm_page_prot, vm_flags))) + pgprot_val(vm_pgprot_modify(vm_page_prot, vma->vm_flags))) return 0; /* @@ -1511,13 +1550,8 @@ int vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot) if (userfaultfd_wp(vma)) return 1; - /* Specialty mapping? */ - if (vm_flags & VM_PFNMAP) - return 0; - /* Can the mapping track the dirty pages? */ - return vma->vm_file && vma->vm_file->f_mapping && - mapping_can_writeback(vma->vm_file->f_mapping); + return vma_fs_can_writeback(vma); } /*