Fix: workset=8192 SEGV - Align slab_index_for to Box3 geometry (iteration 2)
Problem: After Box3 geometry unification (commit2fe970252), workset=8192 still SEGVs: - 200K iterations: ✅ OK - 300K iterations: ❌ SEGV Root Cause (identified by ChatGPT): Header/metadata class mismatches around 300K iterations: - [HDR_META_MISMATCH] hdr_cls=6 meta_cls=5 - [FREE_FAST_HDR_META_MISMATCH] hdr_cls=5 meta_cls=4 - [TLS_SLL_PUSH_META_MISMATCH] cls=5 meta_cls=4 Cause: slab_index_for() geometry mismatch with Box3 - tiny_slab_base_for_geometry() (Box3): - Slab 0: ss + SUPERSLAB_SLAB0_DATA_OFFSET - Slab 1: ss + 1*SLAB_SIZE - Slab k: ss + k*SLAB_SIZE - Old slab_index_for(): rel = p - (base + SUPERSLAB_SLAB0_DATA_OFFSET); idx = rel / SLAB_SIZE; - Result: Off-by-one for slab_idx > 0 Example: tiny_slab_base_for_geometry(ss, 4) returns 0x...40000 slab_index_for(ss, 0x...40000) returns 3 (wrong!) Impact: - Block allocated in "C6 slab 4" appears to be in "C5 slab 3" - Header class_idx (C6) != meta->class_idx (C5) - TLS SLL corruption → SEGV after extended runs Fix: core/superslab/superslab_inline.h ====================================== Rewrite slab_index_for() as inverse of Box3 geometry: static inline int slab_index_for(SuperSlab* ss, void* ptr) { // ... bounds checks ... // Slab 0: special case (has metadata offset) if (p < base + SLAB_SIZE) { return 0; } // Slab 1+: simple SLAB_SIZE spacing from base size_t rel = p - base; // ← Changed from (p - base - OFFSET) int idx = (int)(rel / SLAB_SIZE); return idx; } Verification: - slab_index_for(ss, tiny_slab_base_for_geometry(ss, idx)) == idx ✅ - Consistent for any address within slab Test Results: ============= workset=8192 SEGV threshold improved further: Before this fix (after2fe970252): ✅ 200K iterations: OK ❌ 300K iterations: SEGV After this fix: ✅ 220K iterations: OK (15.5M ops/s) ❌ 240K iterations: SEGV (different bug) Progress: - Iteration 1 (2fe970252): 0 → 200K stable - Iteration 2 (this fix): 200K → 220K stable - Total improvement: ∞ → 220K iterations (+10% stability) Known Issues: - 240K+ still SEGVs (suspected: TLS SLL double-free, per ChatGPT) - Debug builds may show TLS_SLL_PUSH FATAL double-free detection - Requires further investigation of free path Impact: - No performance regression in stable range - Header/metadata mismatch errors eliminated - workset=256 unaffected: 60M+ ops/s maintained Credit: Root cause analysis and fix by ChatGPT 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -30,19 +30,33 @@ static inline uint8_t* tiny_slab_base_for(SuperSlab* ss, int slab_idx)
|
||||
}
|
||||
|
||||
// Compute slab index for a pointer inside ss.
|
||||
// Box 5 wrapper: inverse of Box 3 geometry (tiny_slab_base_for_geometry).
|
||||
// Layout (data regions):
|
||||
// - Slab 0: [ss + SUPERSLAB_SLAB0_DATA_OFFSET, ss + SLAB_SIZE)
|
||||
// - Slab 1: [ss + 1*SLAB_SIZE, ss + 2*SLAB_SIZE)
|
||||
// - Slab k: [ss + k*SLAB_SIZE, ss + (k+1)*SLAB_SIZE)
|
||||
static inline int slab_index_for(SuperSlab* ss, void* ptr)
|
||||
{
|
||||
if (!ss || !ptr) return -1;
|
||||
if (!ss || !ptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uintptr_t base = (uintptr_t)ss;
|
||||
uintptr_t p = (uintptr_t)ptr;
|
||||
size_t ss_size = (size_t)1 << ss->lg_size;
|
||||
|
||||
// Outside overall SuperSlab range
|
||||
if (p < base + SUPERSLAB_SLAB0_DATA_OFFSET || p >= base + ss_size) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t rel = p - (base + SUPERSLAB_SLAB0_DATA_OFFSET);
|
||||
// Slab 0: from first data byte up to the end of first slab
|
||||
if (p < base + SLAB_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Slabs 1+ use simple SLAB_SIZE spacing from SuperSlab base
|
||||
size_t rel = p - base;
|
||||
int idx = (int)(rel / SLAB_SIZE);
|
||||
if (idx < 0 || idx >= SLABS_PER_SUPERSLAB_MAX) {
|
||||
return -1;
|
||||
|
||||
Reference in New Issue
Block a user