Page MenuHomeFreeBSD

Fix a race in release_page().
ClosedPublic

Authored by markj on Nov 4 2019, 4:39 PM.

Details

Summary

Since r354156 we may call release_page() without the page's object's
lock held. Specifically, this happens following the page copy in a CoW
fault. release_page() must therefore unbusy the page only after calling
vm_page_deactivate(). Otherwise, nothing prevents the page from being
freed after the unbusy, and vm_page_deactivate() does not handle races
with vm_page_free_prep().

I do not think there is any harm in keeping the page busy across the
requeue: vm_page_deactivate() moves the page to the tail of the queue,
where the page daemon is not likely to see it before the unbusy is
performed.

Add some assertions to various queue manipulation functions that are
useful for catching this type of bug.

Test Plan

Peter is testing the patch.

Diff Detail

Repository
rS FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

markj created this revision.Nov 4 2019, 4:39 PM
markj edited the test plan for this revision. (Show Details)Nov 4 2019, 4:40 PM
markj added reviewers: kib, alc, jeff, dougm.
kib accepted this revision.Nov 4 2019, 5:00 PM
This revision is now accepted and ready to land.Nov 4 2019, 5:00 PM
alc accepted this revision.Nov 4 2019, 6:49 PM
jeff accepted this revision.Nov 4 2019, 6:50 PM
This revision was automatically updated to reflect the committed changes.