Page MenuHomeFreeBSD

On munlock(), unwire correct page.
ClosedPublic

Authored by kib on Feb 3 2018, 12:13 PM.
Tags
None
Referenced Files
Unknown Object (File)
Dec 22 2023, 10:10 PM
Unknown Object (File)
Nov 18 2023, 12:49 AM
Unknown Object (File)
Sep 18 2023, 3:28 PM
Unknown Object (File)
Aug 29 2023, 2:06 PM
Unknown Object (File)
Aug 4 2023, 7:11 PM
Unknown Object (File)
Jun 15 2023, 6:53 PM
Unknown Object (File)
Jun 3 2023, 1:41 AM
Unknown Object (File)
Jan 6 2023, 5:48 PM
Subscribers

Details

Summary

It is possible, for complex fork()/collapse situations, to have sibling address spaces to partially share shadow chains. If one sibling performs wiring, it can happen that a transient page, invalid and busy, is installed into a shadow object which is visible to other sibling. If the backing object contains the valid page, and the wiring is performed on read-only entry, the transient page is eventually removed.

But the sibling which observed the transient page might perform the unwire, executing vm_object_unwire(). There, the first page found in the shadow chain is considered as the page that was wired for the mapping. It is really the page below it which is wired. So we unwire the wrong page, either triggering the asserts of breaking the page' wire counter.

As the fix, wait for the busy state to finish if we find such page during unwire.

See for instance https://people.freebsd.org/~pho/stress/log/kostik1083.txt which demonstrates the situation.

Reported and tested by: pho

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

sys/vm/vm_object.c
2330 ↗(On Diff #38809)

It seems a bit simpler and more natural to decrement locked_depth on each iteration.

Iterate over the locked_depth var.

This revision is now accepted and ready to land.Feb 5 2018, 5:52 AM
This revision was automatically updated to reflect the committed changes.