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 7479B3911A9 for ; Tue, 11 Aug 2026 03:07:14 +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=1786417635; cv=none; b=C7nsE+fO9CkKROD44q/WEa9hFHswyjVE2RWQXimzL5xZqglSG86nPFxKbuXoKq75vgpZ3jb/IRU+9rAFPBVdjTlxG5+rJClCFzPbz3jHHU5K8OFHVft0R3L/ysxN8NLYDb9qKNXtd/FW5dS7Ux815ZMMHAvAW+cDRvAE/0Ib2iY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786417635; c=relaxed/simple; bh=6k1vvZ2QCIkSSPB4LwmfDbY1MsTRlItzPMSL+ZJDfYM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jTGi9sLTqD3I3x+bQubjRci/cYTNww/9LyM1yGrSB779bj9i8Xn8W7HgS0aZCv8jcYQ6/k7k6qm3Ffn/0KsalTBhoQW38Q3RPS+hSacZkOdnc3KnNO1iSuVz+obP4qKCRqp8TT8cEkJTEZzDXs8rXW+1NNsCyTF/hrhUZWw4EQk= 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=cfi4HImM; 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="cfi4HImM" 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=3RZbPAYAvl32QwZ/NBytlP1RvgJPCM8BP5+kfIW6nbE=; b=cfi4HImMhV4qUUW5bIGJpJ4mnR 1PShb1UDO+ftIPtt6/K82ZZU3h6dbBWlKUKmBcLeJEUes3hkHsg7lKqdRz+5TCrs2jD/3MxpW6f7p 8wuKx3bFxJqDgVTIcaZbSJFT3/SuX2lT1sET1WOh0FQWmitcQqj+STzd8xwbPk5qLNPVIYXDPdoUn JELJvxGnXpEnyq2xGcROLAMLyppdays83XuaOfcoAxw1ahS73RLe1j2k4rlUTiGUYf6zusRVCPaOY AH8W6UKFdm8zcZi0wVJujTMMpjcU/t59Qv0RW9ilGCWLqPlOQQhNUh3XmhaJsJTDJ+sU8bULblfFO xys5upwQ==; 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 1wtcb6-000000007kZ-2X8W; Mon, 10 Aug 2026 22:52:12 -0400 From: Rik van Riel To: linux-kernel@vger.kernel.org Cc: kernel-team@meta.com, Rik van Riel , Andrew Morton , David Hildenbrand , Jason Gunthorpe , John Hubbard , Peter Xu , linux-mm@kvack.org Subject: [RFC PATCH v3 3/8] mm/gup: split follow_page_pte_commit() out of follow_page_pte() Date: Mon, 10 Aug 2026 22:51:52 -0400 Message-ID: <20260811025157.1632867-4-riel@surriel.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260811025157.1632867-1-riel@surriel.com> References: <20260811025157.1632867-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, so the checks and the commit can be applied at different granularities. No functional changes intended. Suggested-by: David Hildenbrand Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Rik van Riel --- mm/gup.c | 78 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/mm/gup.c b/mm/gup.c index e4e6d0993424..b755ceaac0f5 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -822,6 +822,52 @@ 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); + } + + gup_fill_pages(vma, address, page, 1, pages); + + return 0; +} + static long follow_page_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd, unsigned int flags, struct page **pages) @@ -877,36 +923,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); - } - - gup_fill_pages(vma, address, page, 1, pages); ret = 1; out: pte_unmap_unlock(ptep, ptl); -- 2.55.0