Page MenuHomeFreeBSD

Allocation of last block requires blist cursor reset
ClosedPublic

Authored by dougm on Aug 23 2017, 6:32 AM.
Tags
None
Referenced Files
Unknown Object (File)
Sat, Apr 27, 10:57 PM
Unknown Object (File)
Mar 30 2024, 12:40 PM
Unknown Object (File)
Dec 20 2023, 4:54 AM
Unknown Object (File)
Sep 3 2023, 9:51 PM
Unknown Object (File)
Aug 26 2023, 2:04 AM
Unknown Object (File)
Aug 4 2023, 6:37 AM
Unknown Object (File)
Aug 4 2023, 6:37 AM
Unknown Object (File)
Aug 4 2023, 6:37 AM
Subscribers

Details

Summary

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.

Test Plan

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

kib added a subscriber: pho.

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;

In D12106#251258, @dougm_rice.edu wrote:

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.

Ok. After considering the trade-offs among the three possible fixes, I'm going to commit the original one.

This revision is now accepted and ready to land.Aug 25 2017, 6:17 PM
This revision was automatically updated to reflect the committed changes.