Public bug reported:

Clean cherry-pick from linux-next:

```
(cherry picked from commit ae75e88d8c258fd849de594e7d468b5263e7b3e3 linux-next)
```

John Hubbard, Acked-by David Hildenbrand, applied by Andrew Morton.
[Lore 
thread](https://lore.kernel.org/all/[email protected]/).

## Problem

`f002882ca369` (present on this branch) made `gup_fast_folio_allowed()` bail to 
the
slow path for *any* order-0 folio with a NULL `->mapping` when 
`CONFIG_SECRETMEM=y`.
Pages from `alloc_page()` + `vm_insert_page()` legitimately have a NULL 
mapping, so
every `pin_user_pages_fast()` over such a range misses the fast path — nvidia-fs
(GPUDirect Storage) allocates its shadow buffers exactly this way.

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_backed` keeps long-term writable pins on the slow path and 
restores
the fast path otherwise — exactly the pre-`f002882ca369` behaviour.

`CONFIG_SECRETMEM=y` on amd64 and arm64, so this is live on every
flavour we ship.

## Measurement (GH200, 288 cores)

A module reproducing the nvidia-fs pattern (`alloc_page` + `vm_insert_page`, 
then
`pin_user_pages_fast(..., FOLL_WRITE, ...)`), with an anonymous-memory control 
the
patch cannot affect. `get_user_pages_fast_only()` gives the GUP-fast verdict
directly: **0/N unpatched, N/N patched**.

Median ns/page, 512 pages/thread, 5 reps:

| threads | 4K unpatched → patched | 64K unpatched → patched |
|--------:|-----------------------:|------------------------:|
| 1       | 34 → 34 (1.0x)         | 33 → 30 (1.1x)          |
| 8       | 74 → 33 (**2.2x**)     | 1920 → 31 (**62x**)     |
| 32      | 95 → 33 (**2.9x**)     | 4792 → 33 (**145x**)    |
| 128     | 500 → 218 (noisy)      | 16673 → 76 (**219x**)   |

The anon control held at 30-35 ns/page across all four kernels, so only the 
affected
range moved. Stock `7.0.0-1015-nvidia-64k` independently reproduces the 
unpatched 64K
numbers (8 threads: 1176 vs 37), so this isn't a test-config artefact.

Single-threaded it's a wash; the win is under concurrency. `perf` on the 
unpatched
64K kernel shows the slow path is ~90% lock contention 
(`queued_spin_lock_slowpath`
72%), gone entirely once patched — 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 == NULL` changes
behaviour; long-term writable pins are untouched.

A secretmem folio caught mid-truncate can't happen here: `secretmem_setattr()`
refuses to shrink, there's no `.fallocate` (so no punch-hole), and
`secretmem_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; built arm64 4K/64K and x86_64, no new warnings; verified in the
binary (unpatched `mov w0, #0x0` vs patched `eor w0, w0, #0x1`); benchmarked as 
above.

** Affects: linux-nvidia-7.0 (Ubuntu)
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2162917

Title:
  Backport: "mm/gup: fix GUP-fast fallback for NULL-mapping order-0
  folios"

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux-nvidia-7.0/+bug/2162917/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to