Page MenuHomeFreeBSD

diagnostic: avoid a quadratic vm_map consistency walk after fork
Needs ReviewPublic

Authored by nprice on Sun, Oct 18, 4:24 PM.
Referenced Files
F176497453: D60841.id190208.diff
Mon, Oct 19, 8:15 AM
F176497223: D60841.id.diff
Mon, Oct 19, 8:12 AM
Unknown Object (File)
Mon, Oct 19, 4:45 AM
Unknown Object (File)
Mon, Oct 19, 4:43 AM
Unknown Object (File)
Mon, Oct 19, 3:41 AM
Unknown Object (File)
Mon, Oct 19, 3:34 AM
Unknown Object (File)
Mon, Oct 19, 2:45 AM
Unknown Object (File)
Mon, Oct 19, 1:03 AM
Subscribers

Details

Summary

The DIAGNOSTIC consistency walk searches the tree from the root for
every entry, so it is O(n * depth). vmspace_fork() links the copied
entries in address order, leaving the child's tree a path, so the
child's first fault pays an O(n^2) walk. A forked smbd with over
70000 map entries makes over a billion node visits in that fault.

Walk the tree depth-first instead, carrying each subtree's bounds, in
O(n). Visit the smaller address span first; each push at least halves
the span, so one pending slot per address bit suffices.

Checking the bounds and the header links covers the threads, which
makes the list walk redundant.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 78345
Build 75228: arc lint + arc unit

Event Timeline

nprice retitled this revision from vm_map: avoid a quadratic consistency walk after fork to diagnostic: vm_map: avoid a quadratic consistency walk after fork.
nprice retitled this revision from diagnostic: vm_map: avoid a quadratic consistency walk after fork to diagnostic:avoid a quadratic vm_map consistency walk after fork.
nprice retitled this revision from diagnostic:avoid a quadratic vm_map consistency walk after fork to diagnostic: avoid a quadratic vm_map consistency walk after fork.
adrian added inline comments.
sys/vm/vm_map.c
5343

is this an OK stack allocation?

only reserve stack space (~1k) during check

sys/vm/vm_map.c
5343

moved the check out of line so we're only allocating the ~1k if/when the check actually runs

def open to better options though