[linux-nvidia-6.18-next]: Backport "mm/gup: fix GUP-fast fallback for NULL-mapping order-0 folios" - #533
Closed
jamieNguyenNVIDIA wants to merge 1 commit into
Conversation
Since commit f002882 ("mm: merge folio_is_secretmem() and folio_fast_pin_allowed() into gup_fast_folio_allowed()"), gup_fast_folio_allowed() falls back to the slow path for any order-0 folio with a NULL mapping when CONFIG_SECRETMEM=y. This causes a performance regression for drivers that allocate pages with alloc_page() and insert them into VMAs via vm_insert_page(). These pages legitimately have a NULL folio->mapping, but they cannot be secretmem pages. Secretmem pages are always added to the secretmem inode's page cache via filemap_add_folio(), which sets folio->mapping to the inode's i_mapping. A folio with a NULL mapping can never be a secretmem folio. The NULL-mapping check was intended to handle truncated file-backed pages (a reject_file_backed concern), not secretmem detection. When only check_secretmem is true (and reject_file_backed is false), a NULL mapping is sufficient to prove the folio is not secretmem, so the fast path can proceed. Link: https://lore.kernel.org/20260708005745.164928-1-jhubbard@nvidia.com Fixes: f002882 ("mm: merge folio_is_secretmem() and folio_fast_pin_allowed() into gup_fast_folio_allowed()") Signed-off-by: John Hubbard <jhubbard@nvidia.com> Tested-by: Sourab Gupta <sougupta@nvidia.com> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Cc: Alistair Popple <apopple@nvidia.com> Cc: Balbir Singh <balbirs@nvidia.com> Cc: Zi Yan <ziy@nvidia.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> (cherry picked from commit c494788faffe67216c56623d240541fde50139c3 linux-next) Signed-off-by: Jamie Nguyen <jamien@nvidia.com>
Collaborator
|
Verified backport is the same as the 7.0 kernels, no issues.
|
sforshee
approved these changes
Aug 5, 2026
sforshee
left a comment
Collaborator
There was a problem hiding this comment.
Acked-by: Seth Forshee <sforshee@nvidia.com>
Collaborator
|
Applied to |
Collaborator
BaseOS Kernel ReviewSummaryThe GUP-fast change is safe, but its rationale is inaccurate: a truncated secretmem folio can have a NULL mapping. Safety instead depends on truncation unmapping PTEs before folio removal and GUP validating the sampled PTE. Findings: Critical: 0, High: 0, Medium: 0, Low: 1 Latest watcher review: open review Generated test plan: open test plan Kernel deb build: successful (download debs, 4 files) Head: This comment is maintained by nv-pr-bot. It is updated when the GitHub watcher publishes a newer review. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Target:
linux-nvidia-6.18-next· Topic:jamien/6.18-next/gup-fast-null-mapping· Base:da0bc2776f136(6.18.40)Clean cherry-pick from linux-next:
John Hubbard, Acked-by David Hildenbrand, applied by Andrew Morton.
Lore thread.
Same pick already applied to
26.04_linux-nvidiaand26.04_linux-nvidia-bos(#531, #532).
gup_fast_folio_allowed()is byte-identical on all three branches, sothe change and the diff are identical.
Problem
f002882ca369(in mainline since v6.10, so present on this branch) madegup_fast_folio_allowed()bail to the slow path for any order-0 folio with a NULL->mappingwhenCONFIG_SECRETMEM=y:Pages from
alloc_page()+vm_insert_page()legitimately have a NULL mapping, soevery
pin_user_pages_fast()over such a range misses the fast path — nvidia-fs(GPUDirect Storage) allocates its shadow buffers exactly this way
(
nvfs-mmap.c:750/761), then pins them withpin_user_pages_fast(..., FOLL_WRITE, ...)and no
FOLL_LONGTERM, which is precisely the case the patch restores.The NULL check was meant to catch truncated file-backed pages, not secretmem.
Secretmem folios are published via
filemap_add_folio(), which always sets->mapping, so a NULL mapping proves the folio is not secretmem. Returning!reject_file_backedkeeps long-term writable pins on the slow path and restores thefast path otherwise — exactly the pre-
f002882ca369behaviour.arch/arm64/configs/full-64k.configsetsCONFIG_SECRETMEM=y, so this is live on theshipping 64K configuration.
Measurement (GH200, 288 cores, 64K pages)
Two kernels built from this branch tip (6.18.40), differing only by this patch,
configured with
scripts/kconfig/merge_config.sh arch/arm64/configs/full-64k.config arch/arm64/configs/nvidia.config.A module reproduces the nvidia-fs pattern (
alloc_page+vm_insert_page, thenpin_user_pages_fast(..., FOLL_WRITE, ...)), with an anonymous-memory control thepatch cannot affect.
get_user_pages_fast_only()gives the GUP-fast verdict directly.Mechanism, at every thread count:
Median ns/page, 512 pages/thread, 5 reps:
The anon control held at ~30-34 ns/page on both kernels, so only the affected range
moved. Single-threaded it is a wash; the win appears under the concurrency a real IO
submitter uses. On the equivalent 7.0 pair,
perfshowed the unpatched slow path is~90% lock contention (
queued_spin_lock_slowpath), which disappears once patched — sothis is contention that scales with thread count, not a fixed per-page cost.
Risk
Low. One line in a static function with three callers, all in GUP-fast. Only
reject_file_backed == false && check_secretmem && mapping == NULLchanges behaviour;long-term writable pins are untouched.
A secretmem folio caught mid-truncate cannot happen here:
secretmem_setattr()refusesto shrink, there is no
.fallocate(so no punch-hole), andsecretmem_migrate_folio()returns
-EBUSY. Only inode eviction remains, which requires every VMA gone — no VMA,no PTE for GUP-fast to walk. Raised by David Hildenbrand on v1 and resolved before he
Acked.
Testing
Applies cleanly to the branch tip;
gup_fast_folio_allowed()is byte-identical to thetree the patch was written against. Built for arm64 64K using the in-tree
full-64k.config+nvidia.configfragments, no new warnings. Verified in the binary,not just the source: unpatched emits
mov w0, #0x0on the NULL-mapping path, patchedemits
eor w0, w0, #0x1. Both kernels were built from this branch tip, booted onGH200, and benchmarked as above.
Bugs
nvbug: 6064778
LP: https://bugs.launchpad.net/ubuntu/+source/linux-nvidia-7.0/+bug/2162917