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)
Thu, Jun 27, 9:01 PM
Unknown Object (File)
Thu, Jun 27, 8:33 PM
Unknown Object (File)
Wed, Jun 26, 9:51 AM
Unknown Object (File)
Sat, Jun 22, 3:30 AM
Unknown Object (File)
May 29 2024, 12:06 PM
Unknown Object (File)
May 28 2024, 9:40 PM
Unknown Object (File)
May 7 2024, 10:40 PM
Unknown Object (File)
Dec 22 2023, 10:10 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 Skipped
Unit
Tests Skipped
Build Status
Buildable 14755

Event Timeline

sys/vm/vm_object.c
2330

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.