From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from shelob.surriel.com (shelob.surriel.com [96.67.55.147]) (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 8BFD23DDDAF for ; Sat, 1 Aug 2026 03:15:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=96.67.55.147 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785554170; cv=none; b=aM4iwSGmWaQjSF2ZPRN+TkF0VVNx27ddUw5fOPslSMzwokhr6QAq/OeGzfJmq2H9A1w61zoolKhiuzjYuVyp4q4X4iYPadNqm60r/rciDZXCDUCYVkO46QAKGFoIwpsWfktEl8mMwlcXoP1Dv1hYfOnQQbr+tnn4Y6qKOKVcpV8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785554170; c=relaxed/simple; bh=E1bfLYtI2RZWnD5lfzUqEGDGV77yVvMK6NCn5AqvZhI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=criQ2ConCrTwvpa9SGW2CIWA2WZgkfqng3/AUtOh45djliiCA8PkXbrkgcEEpGd8LjMQEbkT3cPUiOY1wtV8TgIJ1UtKnZRjZ61H6RRkH0doe/T9y/QVCvL6PYExO4hvj0vmxjLrNW6Cp95Yq6Wrm+gMjNeEPY60sbEve3tp5rI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=surriel.com; spf=pass smtp.mailfrom=surriel.com; dkim=pass (2048-bit key) header.d=surriel.com header.i=@surriel.com header.b=bMMULlZD; arc=none smtp.client-ip=96.67.55.147 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=surriel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=surriel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=surriel.com header.i=@surriel.com header.b="bMMULlZD" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=surriel.com ; s=mail; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=M1pHvAK4N9+3KUvGzv0LO80HoGs7+eXLX4dwzNp1IZM=; b=bMMULlZD2Ev3kM3uCYDeagi7uu SGxDMlBuA+9EC1H10raJQGthPKNwhRU/ByxUaR8mzy4Pct6RgOIcGMUv+2zX9H4D3xBhOCic0mypU pVI1HwOm6NVbJgW3QO36LLC8eaUzW19upwDg4XfYc5XXnsKgI59fjNScFpZGCa33d47YowjBMU3kY +iINXrsIg7lb4r3iUrvP4UB9zNWK51o++i77raAAmcGYPUx/t6ryctUgrrGNJ9OYPIxiKE9W7jONp 6J6UKhulw3MrIoaqs21CpiYFmHYnOmEaVqmjvk1XK0nWBqhJfiRJpZB27pNbbKKkpRul0TOCw5z3K QE07Sn+w==; Received: from [96.67.55.146] (helo=fangorn.surriel.com) by shelob.surriel.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.97.1) (envelope-from ) id 1wq0CU-000000001Q5-3m7I; Fri, 31 Jul 2026 23:15:50 -0400 From: Rik van Riel To: linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand Cc: kernel-team@meta.com, Rik van Riel , Jason Gunthorpe , John Hubbard , Peter Xu , linux-mm@kvack.org, Lorenzo Stoakes Subject: [PATCH 2/5] mm/gup: split follow_page_pte_commit() out of follow_page_pte() Date: Fri, 31 Jul 2026 23:15:37 -0400 Message-ID: <20260801031540.2742891-3-riel@surriel.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260801031540.2742891-1-riel@surriel.com> References: <20260801031540.2742891-1-riel@surriel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit follow_page_pte() does two things once it has resolved a present PTE to a page: run the per-PTE safety checks (write-fault, unshare), then commit to that page: grab a ref, fault it in if pinning, mark it dirty/accessed, and hand it back to the caller. Split the second part into its own follow_page_pte_commit(), unchanged except for taking its inputs as parameters instead of local variables. A later change teaches it to commit more than one page at a time. No functional changes intended. Suggested-by: David Hildenbrand Assisted-by: Claude:claude-opus-4.8 Signed-off-by: Rik van Riel --- mm/gup.c | 86 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/mm/gup.c b/mm/gup.c index 09c64ef2f57c..053da43760a2 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -813,6 +813,56 @@ static inline bool can_follow_write_pte(pte_t pte, struct page *page, return !userfaultfd_pte_wp(vma, pte); } +/* + * The caller has already run every per-PTE safety check (present, + * write-fault, gup_must_unshare()) on the PTE, so this only does the + * per-folio work: the refcount grab, the FOLL_PIN accessibility fault-in, + * dirty/accessed marking, and the array fill with the cache flush. + */ +static long follow_page_pte_commit(struct vm_area_struct *vma, + unsigned long address, struct folio *folio, struct page *page, + pte_t pte, unsigned int flags, struct page **pages) +{ + long ret; + + /* try_grab_folio() does nothing unless FOLL_GET or FOLL_PIN is set. */ + ret = try_grab_folio(folio, 1, flags); + if (unlikely(ret)) + return ret; + + /* + * We need to make the page accessible if and only if we are going + * to access its content (the FOLL_PIN case). Please see + * Documentation/core-api/pin_user_pages.rst for details. + */ + if (flags & FOLL_PIN) { + ret = arch_make_folio_accessible(folio); + if (ret) { + gup_put_folio(folio, 1, flags); + return ret; + } + } + if (flags & FOLL_TOUCH) { + if ((flags & FOLL_WRITE) && + !pte_dirty(pte) && !folio_test_dirty(folio)) + folio_mark_dirty(folio); + /* + * pte_mkyoung() would be more correct here, but atomic care + * is needed to avoid losing the dirty bit: it is easier to use + * folio_mark_accessed(). + */ + folio_mark_accessed(folio); + } + + if (pages) { + pages[0] = page; + flush_anon_page(vma, page, address); + flush_dcache_page(page); + } + + return 0; +} + static long follow_page_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd, unsigned int flags, struct page **pages) @@ -868,40 +918,10 @@ static long follow_page_pte(struct vm_area_struct *vma, VM_WARN_ON_ONCE_PAGE((flags & FOLL_PIN) && PageAnon(page) && !PageAnonExclusive(page), page); - /* try_grab_folio() does nothing unless FOLL_GET or FOLL_PIN is set. */ - ret = try_grab_folio(folio, 1, flags); - if (unlikely(ret)) + ret = follow_page_pte_commit(vma, address, folio, page, pte, flags, + pages); + if (ret) goto out; - - /* - * We need to make the page accessible if and only if we are going - * to access its content (the FOLL_PIN case). Please see - * Documentation/core-api/pin_user_pages.rst for details. - */ - if (flags & FOLL_PIN) { - ret = arch_make_folio_accessible(folio); - if (ret) { - gup_put_folio(folio, 1, flags); - goto out; - } - } - if (flags & FOLL_TOUCH) { - if ((flags & FOLL_WRITE) && - !pte_dirty(pte) && !folio_test_dirty(folio)) - folio_mark_dirty(folio); - /* - * pte_mkyoung() would be more correct here, but atomic care - * is needed to avoid losing the dirty bit: it is easier to use - * folio_mark_accessed(). - */ - folio_mark_accessed(folio); - } - - if (pages) { - pages[0] = page; - flush_anon_page(vma, page, address); - flush_dcache_page(page); - } ret = 1; out: pte_unmap_unlock(ptep, ptl); -- 2.53.0-Meta