[PATCH 0/2] mm/huge_memory: take a reference on a device DAX PUD copied by fork

From: Konstantin Khorenko

Date: Wed Oct 21 2026 - 14:15:37 EST


copy_huge_pud() copies a device DAX PUD into the child without the
reference, rmap and counter that vmf_insert_folio_pud() took, so the
child's unmap takes them from the parent. fork copies a device DAX VMA
once it has a guard region, so it takes no more than:

1. map a devdax instance with 1 GiB alignment and fault in a PUD;
2. MADV_GUARD_INSTALL a page elsewhere in the VMA;
3. fork, and let the child exit.

Patch 1 is the fix, patch 2 a selftest for it. I found it while
reworking copy_huge_pmd() for fork after David's review [1]; it is
independent of that series and applies to v7.3-rc7 on its own.

Testing
=======

* v7.3-rc7 x86_64 KVM guest with CONFIG_DEBUG_VM
* pmem from memmap=3G!4G
* devdax made with "ndctl create-namespace -m devdax -a 1G":

kernel fork_dax_pud log
7.3-rc7 not ok BUG: Bad rss-counter state mm:...
type:MM_FILEPAGES val:-262144
7.3-rc7 + patch 1 ok clean

A variant that writes to the device and forks three times also hit,
on 7.3-rc7:

WARNING: ./include/linux/rmap.h:159 at
__folio_large_mapcount_sanity_checks+0x90/0x150

The selftest only runs on a device given in FORK_DAX_PUD_DEVICE or
argv[1], as on an unfixed kernel it leaves that device's folio with a
mapcount below zero. On pmem emulated in RAM, with
CONFIG_X86_PMEM_LEGACY and CONFIG_DEV_DAX_PMEM:

boot with memmap=3G!4G
ndctl create-namespace -f -e namespace0.0 -m devdax -a 1G
FORK_DAX_PUD_DEVICE=/dev/dax0.0 ./fork_dax_pud

[1] https://lore.kernel.org/linux-mm/20261014-b4-prep-vstor-149847-copy_huge_pmd-recheck-special-pmd-v3-0-85eaec8417f6@xxxxxxxxxxxxx/

Signed-off-by: Konstantin Khorenko <khorenko@xxxxxxxxxxxxx>
---
Konstantin Khorenko (2):
mm/huge_memory: take a reference on a folio PUD copied by fork
selftests/mm: test fork of a device DAX PUD

MAINTAINERS | 1 +
include/linux/huge_mm.h | 2 +-
include/linux/rmap.h | 22 +++++
mm/huge_memory.c | 13 ++-
mm/memory.c | 4 +-
tools/testing/selftests/mm/Makefile | 1 +
tools/testing/selftests/mm/fork_dax_pud.c | 136 ++++++++++++++++++++++++++++++
tools/testing/selftests/mm/run_vmtests.sh | 1 +
8 files changed, 175 insertions(+), 5 deletions(-)
---
base-commit: a804c5742bff224d4cb4d25dd383554d598be32b
change-id: 20261021-vstor-150143-copy_huge_pud-folio-refcount-ea269e668270

Best regards,
--
Konstantin Khorenko,
Virtuozzo Linux Kernel Team