Skip to content

Possible page leak: anonymous pages returned into a VM_PFNMAP vma (unverified) #24

Description

@congwang-mk

Unverified. Traced by reading the fault path, not reproduced. Wanted it recorded rather than lost, but it needs a repro before anyone acts on it.

daxfs_file_mmap() (daxfs/file.c:769) sets VM_PFNMAP for every shared mapping:

if (vma->vm_flags & VM_SHARED)
        vm_flags_set(vma, VM_PFNMAP);

The read path in daxfs_dax_fault() (daxfs/file.c:671) can nonetheless hand back an ordinary anonymous page, which is the fallback whenever the data is not page-aligned or lives in the pcache:

page = alloc_page(GFP_HIGHUSER_MOVABLE);
...
__SetPageUptodate(page);
lock_page(page);
vmf->page = page;
return VM_FAULT_LOCKED;

For a shared fault the core then runs finish_fault() -> set_pte_range() -> folio_add_file_rmap_ptes(), taking a mapcount reference. On teardown zap_pte_range() calls vm_normal_page(), which returns NULL for a VM_PFNMAP vma, so the page is never unmapped through the normal path and the mapcount and refcount are never dropped.

If that reading is right, every such fault leaks a page with a permanently elevated mapcount, and the pages are invisible to reclaim. A long-running workload doing shared reads of non-aligned or pcache-backed data would leak steadily.

Reasons for doubt: the interaction between VM_PFNMAP and a vmf->page return is subtle, do_shared_fault() does unlock the folio via fault_dirty_shared_page(), and it is possible some path drops the reference that I did not trace.

To verify: mmap a pcache-backed or unaligned region MAP_SHARED, fault a known number of pages, unmap, and watch MemFree or a page-owner trace across repeated cycles.

If confirmed, the fix is probably to not return a struct page into a VM_PFNMAP vma at all: either drop VM_PFNMAP for mappings that can fall back to anonymous pages, or use VM_MIXEDMAP so vm_normal_page() resolves correctly.

Found during the review in #14.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions