diff options
author | Mark Johnston <markj@FreeBSD.org> | 2025-04-13 16:09:31 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2025-04-13 16:09:31 +0000 |
commit | c98367641991019bac0e8cd55b70682171820534 (patch) | |
tree | 3de9e605edc1001c7a6494515ab1177b037ad625 /contrib/groff/font/devdvi/(developers-only) | |
parent | d8cf519492523f6dd239ab153029db62749afa52 (diff) |
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
Diffstat (limited to 'contrib/groff/font/devdvi/(developers-only)')
0 files changed, 0 insertions, 0 deletions