If the cursor is left sitting at the end of managed memory after an allocation, then the next allocation request will lead it to march into unmanaged memory, with dire consequences.
Details
I think this change is supposed to fix issue like kostik1026.
Diff Detail
- Repository
- rS FreeBSD src repository - subversion
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
Ran the test scenario which triggered the "panic: Swapdev not found" for 5 hours without issues.
I have run numerous tests since r322459 was committed that have wrapped around the swap area without crashing, so there must be another prerequisite to a crash: Your swap area is a fully allocated tree, i.e., the number of blocks equals the radix. Can we also solve this problem by placing a sentinel entry at the end of a fully allocated tree?
A sentinel is not sufficient. While cursor sits at the end of managed memory, we start with scan = bl_root, and compute blk == cursor, so child == 0, so we loop over the 16 subchildren of root and if we find a free block at p, we report a free block at p+radix. Nothing gets us to actually look at the new sentinel, unless we make the tree one level higher, with the 2nd child of the root consisting of the sentinel only.
Also worth considering - a change that adds no new lines and only rewrites line 253 as
bl->bl_cursor = blk;
Ok. After considering the trade-offs among the three possible fixes, I'm going to commit the original one.