From patchwork Thu Jan 25 19:32:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 13531562 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 CD0CDC48260 for ; Thu, 25 Jan 2024 19:34:08 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 61338280010; Thu, 25 Jan 2024 14:34:08 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 59B3F280004; Thu, 25 Jan 2024 14:34:08 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 41455280010; Thu, 25 Jan 2024 14:34:08 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id 328EE280004 for ; Thu, 25 Jan 2024 14:34:08 -0500 (EST) Received: from smtpin06.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 0DD74120D78 for ; Thu, 25 Jan 2024 19:34:08 +0000 (UTC) X-FDA: 81718834176.06.A9FDBD1 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by imf01.hostedemail.com (Postfix) with ESMTP id 506074000E for ; Thu, 25 Jan 2024 19:34:06 +0000 (UTC) Authentication-Results: imf01.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=RySZ1uEH; dmarc=pass (policy=none) header.from=redhat.com; spf=pass (imf01.hostedemail.com: domain of david@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=david@redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1706211246; 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=t50qmPGMpYBEYaKXQ+yO8QVLOuyugBz/n/H7V6E+Pmw=; b=ib9YmhIC74lgSzIPI7j1mpxoksjH4H8UHMe+o956/XdTHXMcGJ6XKyZDW7awopQQU5Fuvr 4N1J9stb90fywCLgU7SRYcRd67R+peP1qxJpUskimhUyVzqX64GsFooMlGB3RZwqMh8YZg 5DGrIAfMFRqakaalJZUUSNwWxUT8AXY= ARC-Authentication-Results: i=1; imf01.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=RySZ1uEH; dmarc=pass (policy=none) header.from=redhat.com; spf=pass (imf01.hostedemail.com: domain of david@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=david@redhat.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1706211246; a=rsa-sha256; cv=none; b=UdYnv0EZEmNKTXOmh/fJkSG94guk/T3t0r1LsO18HOJUSRZYRffjbbjxcrhmURSOHLKdBF vS0UV1hNjHZzf2N3aLulbq4Trq7lw0tAlsjpaiSZjmlfRTI/Cn6SE0dc5NykMmaO/kq+NQ 2Yus5ahC3z6SiE7LrwJfFfAw9pDfMUk= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1706211245; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=t50qmPGMpYBEYaKXQ+yO8QVLOuyugBz/n/H7V6E+Pmw=; b=RySZ1uEHTlySiBn/5GIHErv1YCYKiLCckoxy7YKub7ty2jsFs13vqUvcClYiXPVM0n5WBV 9K/88z6XvVMaeisTA2TzYJIHzlSLJ0PLzRZZfxHUvXh6TIWV0yjNiLpnFNxgr4yfaKBDAJ 7yUlIgS916BoqpZ7w0o15tpNAm/bYNo= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-255-d5Q_-Ra7Nw6rcBDvoDTvqQ-1; Thu, 25 Jan 2024 14:34:01 -0500 X-MC-Unique: d5Q_-Ra7Nw6rcBDvoDTvqQ-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id E2A0C1013665; Thu, 25 Jan 2024 19:33:59 +0000 (UTC) Received: from t14s.redhat.com (unknown [10.39.193.154]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9077F492BC6; Thu, 25 Jan 2024 19:33:53 +0000 (UTC) From: David Hildenbrand To: linux-kernel@vger.kernel.org Cc: linux-mm@kvack.org, David Hildenbrand , Andrew Morton , Matthew Wilcox , Ryan Roberts , Russell King , Catalin Marinas , Will Deacon , Dinh Nguyen , Michael Ellerman , Nicholas Piggin , Christophe Leroy , "Aneesh Kumar K.V" , "Naveen N. Rao" , Paul Walmsley , Palmer Dabbelt , Albert Ou , Alexander Gordeev , Gerald Schaefer , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , Sven Schnelle , "David S. Miller" , linux-arm-kernel@lists.infradead.org, linuxppc-dev@lists.ozlabs.org, linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org, sparclinux@vger.kernel.org Subject: [PATCH v2 14/15] mm/memory: ignore dirty/accessed/soft-dirty bits in folio_pte_batch() Date: Thu, 25 Jan 2024 20:32:26 +0100 Message-ID: <20240125193227.444072-15-david@redhat.com> In-Reply-To: <20240125193227.444072-1-david@redhat.com> References: <20240125193227.444072-1-david@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.9 X-Rspamd-Queue-Id: 506074000E X-Rspam-User: X-Rspamd-Server: rspam04 X-Stat-Signature: q6b3eduryi6nnami41fc6oez9dgsj7t6 X-HE-Tag: 1706211246-600241 X-HE-Meta: U2FsdGVkX1+7XaeRd2jnquusuMSP0ClklcYI98CX+vSdVP2cT0YhoXtyxViH3cY+w7yj/xbF6fELQf7+xrv+vygYQc+6vu8zWpIjXTmS0IgUStweloav+BJR2KBimCeHdqO5T3g/UluGPOJIwlzRKQeQsV/QQ6RaTbrJ7TbfsPGYYkd8IsZmT2mV7Dh6jxIshJSzGyFv1ANx8hegq46uGS4ftlJLufP+k6kc3dbq/xW55SB2GLuIBTtNC7Az49v1IGrgv9gGLyDRMfDsBs4fwZQ/7tR9zeoaKkFVXp8XRsIhksOPKSl4C06sjQm3nGD/Wch4PxVVPeixYgxXKG9TYryenRFGBYv/fDwFvA25PmNJs55EzU0+zpDYeAvUjcENuU5lJa7H7hrNZicquDst2aPPRb6YQkVn3uhfxAoG6eGNr9XKvBk7WD/NXL791qMoDjmEDey3sxOhCwdGXqfuGiMp1uf2yq/haT5bqiT/ry5ITjZU5HjWmJU1sodRr3OuX0I6V3XnzfudhHR3ZKLTsGW9MpXQbJ5X5F2eqb3nzVsLs+aHCHBxtzqUlYdS9Pp7GWP2HKJe2fWS9Co9SN9sHUAv1Mgq2lWoetvnzi1p7dy2aDmTnA7ctHx4SxFSwdCxh2/u27sapF3DwVoVs85qmlpK0XeLhLEuqhOQEf4qCp1/Awdi+MQMsyeSTRQSDyKz9Pugf3unanRRl5yD8Bw3nqh3NZp7nJ3Ki1MhI0eN0an7dzNbR05YZyQ1uJ32bSkeA4S8ErmW916m5DZK9heRm5anekQLamz8LKk91qLhk7x208LyA8QpziR0UE/+1x4jwfmtAVDdGjQx7zXVz31RnLD66oS7pEHQ9VZh9AnRW5B6JAjNDldCF+HIBNFNEdhpZKxTD/1gXaxtauM+84tA52TPg5Z3iI04EaNhziu2zrzEjXK+wdj40jj/uwRwHzCSTcWjkQ5/bgp1gTwDvuM RPYTCqdK Afu0u1BdjLNjspGk47yqCo6sQOW2o/g4INc8gyv7oqwT/yYWJC/+eVnL1YwYVQQjwHXWYzjpPz93Om2IVgdJyphGAIxWt2JkJi5EC1QuQD2AWTco0JZX8MI8zS6aDhJppLW1SpPRSuUdVlvtUrnKCKKdCyuE8aJi+pE1+BkUBaKlQ5bu5W9jOL3bnbV7dZp6QuY+t3spHaJ6o4IApoc9AhOZmNtceQIOTaBQs 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: List-Subscribe: List-Unsubscribe: Let's always ignore the accessed/young bit: we'll always mark the PTE as old in our child process during fork, and upcoming users will similarly not care. Ignore the dirty bit only if we don't want to duplicate the dirty bit into the child process during fork. Maybe, we could just set all PTEs in the child dirty if any PTE is dirty. For now, let's keep the behavior unchanged, this can be optimized later if required. Ignore the soft-dirty bit only if the bit doesn't have any meaning in the src vma, and similarly won't have any in the copied dst vma. For now, we won't bother with the uffd-wp bit. Signed-off-by: David Hildenbrand Reviewed-by: Ryan Roberts --- mm/memory.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index 4d1be89a01ee0..b3f035fe54c8d 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -953,24 +953,44 @@ static __always_inline void __copy_present_ptes(struct vm_area_struct *dst_vma, set_ptes(dst_vma->vm_mm, addr, dst_pte, pte, nr); } +/* Flags for folio_pte_batch(). */ +typedef int __bitwise fpb_t; + +/* Compare PTEs after pte_mkclean(), ignoring the dirty bit. */ +#define FPB_IGNORE_DIRTY ((__force fpb_t)BIT(0)) + +/* Compare PTEs after pte_clear_soft_dirty(), ignoring the soft-dirty bit. */ +#define FPB_IGNORE_SOFT_DIRTY ((__force fpb_t)BIT(1)) + +static inline pte_t __pte_batch_clear_ignored(pte_t pte, fpb_t flags) +{ + if (flags & FPB_IGNORE_DIRTY) + pte = pte_mkclean(pte); + if (likely(flags & FPB_IGNORE_SOFT_DIRTY)) + pte = pte_clear_soft_dirty(pte); + return pte_mkold(pte); +} + /* * Detect a PTE batch: consecutive (present) PTEs that map consecutive * pages of the same folio. * - * All PTEs inside a PTE batch have the same PTE bits set, excluding the PFN. + * All PTEs inside a PTE batch have the same PTE bits set, excluding the PFN, + * the accessed bit, dirty bit (with FPB_IGNORE_DIRTY) and soft-dirty bit + * (with FPB_IGNORE_SOFT_DIRTY). */ static inline int folio_pte_batch(struct folio *folio, unsigned long addr, - pte_t *start_ptep, pte_t pte, int max_nr) + pte_t *start_ptep, pte_t pte, int max_nr, fpb_t flags) { unsigned long folio_end_pfn = folio_pfn(folio) + folio_nr_pages(folio); const pte_t *end_ptep = start_ptep + max_nr; - pte_t expected_pte = pte_next_pfn(pte); + pte_t expected_pte = __pte_batch_clear_ignored(pte_next_pfn(pte), flags); pte_t *ptep = start_ptep + 1; VM_WARN_ON_FOLIO(!pte_present(pte), folio); while (ptep != end_ptep) { - pte = ptep_get(ptep); + pte = __pte_batch_clear_ignored(ptep_get(ptep), flags); if (!pte_same(pte, expected_pte)) break; @@ -1004,6 +1024,7 @@ copy_present_ptes(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma { struct page *page; struct folio *folio; + fpb_t flags = 0; int err, nr; page = vm_normal_page(src_vma, addr, pte); @@ -1018,7 +1039,12 @@ copy_present_ptes(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma * by keeping the batching logic separate. */ if (unlikely(!*prealloc && folio_test_large(folio) && max_nr != 1)) { - nr = folio_pte_batch(folio, addr, src_pte, pte, max_nr); + if (src_vma->vm_flags & VM_SHARED) + flags |= FPB_IGNORE_DIRTY; + if (!vma_soft_dirty_enabled(src_vma)) + flags |= FPB_IGNORE_SOFT_DIRTY; + + nr = folio_pte_batch(folio, addr, src_pte, pte, max_nr, flags); folio_ref_add(folio, nr); if (folio_test_anon(folio)) { if (unlikely(folio_try_dup_anon_rmap_ptes(folio, page,