HomeFreeBSD

vm_fault: Defer marking COW pages valid

Description

vm_fault: Defer marking COW pages valid

Suppose an object O has two shadow objects S1, S2 mapped into processes
P1, P2. Suppose a page resident in O is mapped read-only into P1. Now
suppose that P1 writes to the page, triggering a COW fault: it allocates
a new page in S1 and copies the page, then marks it valid. If the page
in O was busy when initially looked up, P1 would have to release the map
lock and sleep first. Then, after handling COW, P1 must re-check the
map lookup because locks were dropped. Suppose the map indeed changed,
so P1 has to retry the fault.

At this point, the mapped page in O is shadowed by a valid page in S1.
If P2 exits, S2 will be deallocated, resulting in a collapse of O into
S1. In this case, because the mapped page is shadowed, P2 will free it,
but that is illegal; this triggers a "freeing mapped page" assertion in
invariants kernels.

Fix the problem by deferring the vm_page_valid() call which marks the
COW copy valid: only mark it once we know that the fault handler will
succeed. It's okay to leave an invalid page in the top-level object; it
will be freed when the fault is retried, and vm_object_collapse_scan()
will similarly free invalid pages in the shadow object.

Reviewed by: kib
MFC after: 1 month
Sponsored by: Innovate UK
Differential Revision: https://reviews.freebsd.org/D49758

Details

Provenance
markjAuthored on Apr 13 2025, 4:09 PM
Reviewer
kib
Differential Revision
D49758: vm_fault: Defer marking COW pages valid
Parents
rGd8cf51949252: fhopen: Restore the O_CREAT check
Branches
Unknown
Tags
Unknown