Skip to content

Tlsf align overhead reduction#422

Open
han-jiang277 wants to merge 7 commits into
vivoblueos:mainfrom
han-jiang277:tlsf-align-overhead-reduction
Open

Tlsf align overhead reduction#422
han-jiang277 wants to merge 7 commits into
vivoblueos:mainfrom
han-jiang277:tlsf-align-overhead-reduction

Conversation

@han-jiang277

@han-jiang277 han-jiang277 commented Jun 5, 2026

Copy link
Copy Markdown
Contributor
Current (absorb padding) — 4 KiB-aligned, 4 KiB payload, GRANULARITY = 32 (64-bit)
 block_start (G-aligned)                         aligned_payload
 │                                               │
 ▼                                               ▼
 ┌──────┬───────── dead padding ─────────┬──────┬──────── PAYLOAD ────────┐
 │BlkHdr│        ~4080 B (lost)          │ Pad  │         4096 B           │
 └──────┴───────────────────────────────┴──────┴─────────────────────────┘
 └───────────────── used block ≈ 8192 B (retained) ──────────────────────┘


Proposed (reclaim leading gap)
 block_start          U_start = aligned_payload - G      aligned_payload
 │                    │                                  │
 ▼                    ▼                                  ▼
 ┌──── FREE  L ───────┬──────┬──────┬──── PAYLOAD ───────┬─── FREE T ───┐
 │  ~4064 B (reused)  │BlkHdr│ Pad  │      4096 B         │  remainder   │
 └────────────────────┴──────┴──────┴────────────────────┴──────────────┘
 phys chain:  prev ← L ← U(used) ← T ← next      (all prev_phys fixed up)
 retained for this alloc ≈ 4128 B   (was ≈ 8192 B)

@CLAassistant

CLAassistant commented Jun 5, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

…rhead

For align >= GRANULARITY, if the gap between the chosen free block start
and aligned_payload - GRANULARITY is >= GRANULARITY, carve it into a
standalone free block L and relocate the used block header to U_start =
aligned_payload - GRANULARITY.

Result: 4K-aligned 4K alloc retains ~4K+GRANULARITY instead of ~8K.
L is an ordinary free block; free/reallocate/coalescing are unchanged.

Also adds #[cfg(test)] unit tests with a physical-chain integrity checker.

Divergence from upstream rlsf (MIT, yvt) is documented in block.rs.
- carve_leading_free_block: read prev_phys before aliasing write (Critical #1)
- carve_leading_free_block: use addr_of_mut! for U.prev_phys to avoid UB (Critical #2)
- allocate: remove spurious mut from next_phys_block (Minor vivoblueos#9)
- allocate: add comment explaining new_size <= search_size after reclamation (Important vivoblueos#7)
- with_pool: assert pool_len > 0 + improve safety comment (Important vivoblueos#11 + vivoblueos#6)
- test_aligned_4k_reclaims_gap: add follow-up alloc to verify L is in free list (Important vivoblueos#5)
- test_aligned_minimum_gap: new test for l_size == GRANULARITY boundary (Important vivoblueos#8)
@han-jiang277 han-jiang277 force-pushed the tlsf-align-overhead-reduction branch from cede726 to eb83eaf Compare June 5, 2026 07:53
@han-jiang277

Copy link
Copy Markdown
Contributor Author

build_prs

@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

❌ Job failed. Failed jobs: build_and_check_boards (failure), see https://github.com/vivoblueos/kernel/actions/runs/27002826313.

@han-jiang277

Copy link
Copy Markdown
Contributor Author

build_prs

@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

@han-jiang277

Copy link
Copy Markdown
Contributor Author

Two reasons block.rs doesn't need code changes:

  1. get_overhead_and_size — search size stays the same by design

This function computes the search size — how large a free block to look for. After reclamation, we still need to find a block of that size because the gap must physically exist before we can carve it. The search size is a mathematical floor, not the retained size. Changing it would break the allocator.

  1. used_block_hdr_for_allocation — header location protocol unchanged

For align >= GRANULARITY, it reads the UsedBlockPad pointer stored immediately before the payload. After reclamation:

U_start = aligned_payload - GRANULARITY
UsedBlockPad sits at aligned_payload - sizeof(UsedBlockPad) = aligned_payload - GRANULARITY/2
The pad stores a pointer back to U_start
This is identical to the non-reclamation path — the pad is always placed just before the payload, and always points to the header. The relative geometry between payload, pad, and header is unchanged; only the header's absolute position in the pool moved forward. free/deallocate just follows the pad pointer and finds the right header regardless.

So block.rs needed only a comment update (provenance note), not a code change.

@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

✅ All jobs completed successfully, see https://github.com/vivoblueos/kernel/actions/runs/27003660272.

@xuchang-vivo xuchang-vivo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants