Files
hakmem/C7_TLS_SLL_CORRUPTION_ANALYSIS.md
Moe Charm (CI) 25d963a4aa Code Cleanup: Remove false positives, redundant validations, and reduce verbose logging
Following the C7 stride upgrade fix (commit 23c0d9541), this commit performs
comprehensive cleanup to improve code quality and reduce debug noise.

## Changes

### 1. Disable False Positive Checks (tiny_nextptr.h)
- **Disabled**: NXT_MISALIGN validation block with `#if 0`
- **Reason**: Produces false positives due to slab base offsets (2048, 65536)
  not being stride-aligned, causing all blocks to appear "misaligned"
- **TODO**: Reimplement to check stride DISTANCE between consecutive blocks
  instead of absolute alignment to stride boundaries

### 2. Remove Redundant Geometry Validations

**hakmem_tiny_refill_p0.inc.h (P0 batch refill)**
- Removed 25-line CARVE_GEOMETRY_FIX validation block
- Replaced with NOTE explaining redundancy
- **Reason**: Stride table is now correct in tiny_block_stride_for_class(),
  defense-in-depth validation adds overhead without benefit

**ss_legacy_backend_box.c (legacy backend)**
- Removed 18-line LEGACY_FIX_GEOMETRY validation block
- Replaced with NOTE explaining redundancy
- **Reason**: Shared_pool validates geometry at acquisition time

### 3. Reduce Verbose Logging

**hakmem_shared_pool.c (sp_fix_geometry_if_needed)**
- Made SP_FIX_GEOMETRY logging conditional on `!HAKMEM_BUILD_RELEASE`
- **Reason**: Geometry fixes are expected during stride upgrades,
  no need to log in release builds

### 4. Verification
- Build:  Successful (LTO warnings expected)
- Test:  10K iterations (1.87M ops/s, no crashes)
- NXT_MISALIGN false positives:  Eliminated

## Files Modified
- core/tiny_nextptr.h - Disabled false positive NXT_MISALIGN check
- core/hakmem_tiny_refill_p0.inc.h - Removed redundant CARVE validation
- core/box/ss_legacy_backend_box.c - Removed redundant LEGACY validation
- core/hakmem_shared_pool.c - Made SP_FIX_GEOMETRY logging debug-only

## Impact
- **Code clarity**: Removed 43 lines of redundant validation code
- **Debug noise**: Reduced false positive diagnostics
- **Performance**: Eliminated overhead from redundant geometry checks
- **Maintainability**: Single source of truth for geometry validation

🧹 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 23:00:24 +09:00

167 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# C7 (1024B) TLS SLL Corruption Root Cause Analysis
## 症状
**修正後も依然として発生**:
- Class 7 (1024B)でTLS SLL破壊が継続
- `tiny_nextptr.h` line 45を `return 1u` に修正済みC7もoffset=1
- 破壊がClass 6からClass 7に移動修正の効果はあるが根本解決せず
**観察事項**:
```
[TLS_SLL_POP_INVALID] cls=7 head=0x5d dropped count=1
[TLS_SLL_POP_INVALID] cls=7 last_push=0x7815fa801003 ← 奇数アドレス!
[TLS_SLL_POP_INVALID] cls=7 head=0xfd dropped count=2
[TLS_SLL_POP_INVALID] cls=7 last_push=0x7815f99a0801 ← 奇数アドレス!
```
1. headに無効な小さい値0x5d, 0xfd等が入る
2. `last_push`アドレスが奇数0x...03, 0x...01等)
## アーキテクチャ確認
### Allocation Path正常
**tiny_alloc_fast.inc.h**:
- `tiny_alloc_fast_pop()` returns `base` (SuperSlab block start)
- `HAK_RET_ALLOC(7, base)`:
```c
*(uint8_t*)(base) = 0xa7; // Write header at base[0]
return (void*)((uint8_t*)(base) + 1); // Return user = base + 1
```
- User receives: `ptr = base + 1`
### Free Pathここに問題がある可能性
**tiny_free_fast_v2.inc.h** (line 106-144):
```c
int class_idx = tiny_region_id_read_header(ptr); // Read from ptr-1 = base ✓
void* base = (char*)ptr - 1; // base = user - 1 ✓
```
**tls_sll_box.h** (line 117, 235-238):
```c
static inline bool tls_sll_push(int class_idx, void* ptr, uint32_t capacity) {
// ptr parameter = base (from caller)
...
PTR_NEXT_WRITE("tls_push", class_idx, ptr, 0, g_tls_sll[class_idx].head);
g_tls_sll[class_idx].head = ptr;
...
s_tls_sll_last_push[class_idx] = ptr; // ← Should store base
}
```
**tiny_next_ptr_box.h** (line 39):
```c
static inline void tiny_next_write(int class_idx, void *base, void *next_value) {
tiny_next_store(base, class_idx, next_value);
}
```
**tiny_nextptr.h** (line 44-45, 69-80):
```c
static inline size_t tiny_next_off(int class_idx) {
return (class_idx == 0) ? 0u : 1u; // C7 → offset = 1 ✓
}
static inline void tiny_next_store(void* base, int class_idx, void* next) {
size_t off = tiny_next_off(class_idx); // C7 → off = 1
if (off == 0) {
*(void**)base = next;
return;
}
// off == 1: C7はここを通る
uint8_t* p = (uint8_t*)base + off; // p = base + 1 = user pointer!
memcpy(p, &next, sizeof(void*)); // Write next at user pointer
}
```
### 期待される動作C7 freelist中
Memory layoutC7 freelist中:
```
Address: base base+1 base+9 base+2048
┌────┬──────────────┬───────────────┬──────────┐
Content: │ ?? │ next (8B) │ (unused) │ │
└────┴──────────────┴───────────────┴──────────┘
header ← ここにnextを格納offset=1
```
- `base`: headerの位置freelist中は破壊されてもOK - C0と同じ
- `base + 1`: next pointerを格納user dataの先頭8バイトを使用
### 問題の仮説
**仮説1: header restoration logic**
`tls_sll_box.h` line 176:
```c
if (class_idx != 0 && class_idx != 7) {
// C7はここに入らない → header restorationしない
...
}
```
C7はC0と同様に「freelist中はheaderを潰す」設計だが、`tiny_nextptr.h`では:
- C0: `offset = 0` → base[0]からnextを書くheader潰す
- C7: `offset = 1` → base[1]からnextを書くheader保持❌ **矛盾!**
**これが根本原因**: C7は「headerを潰す」前提offset=0だが、現在は「headerを保持」offset=1になっている。
## 修正案
### Option A: C7もoffset=0に戻す元の設計に従う
**tiny_nextptr.h** line 44-45を修正:
```c
static inline size_t tiny_next_off(int class_idx) {
// Class 0, 7: offset 0 (freelist時はheader潰す)
// Class 1-6: offset 1 (header保持)
return (class_idx == 0 || class_idx == 7) ? 0u : 1u;
}
```
**理由**:
- C7 (2048B total) = [1B header] + [2047B payload]
- Next pointer (8B)はheader位置から書く → payload = 2047B確保
- Header restorationは allocation時に行うHAK_RET_ALLOC
### Option B: C7もheader保持現在のoffset=1を維持し、restoration追加
**tls_sll_box.h** line 176を修正:
```c
if (class_idx != 0) { // C7も含める
// All header classes (C1-C7) restore header during push
...
}
```
**理由**:
- 統一性全header classes (C1-C7)でheader保持
- Payload: 2047B → 2039B (8B next pointer)
## 推奨: Option A
**根拠**:
1. **Design Consistency**: C0とC7は「headerを犠牲にしてpayload最大化」という同じ設計思想
2. **Memory Efficiency**: 2047B payload維持8B節約
3. **Performance**: Header restoration不要1命令削減
4. **Code Simplicity**: 既存のC0 logicを再利用
## 実装手順
1. `core/tiny_nextptr.h` line 44-45を修正
2. Build & test with C7 (1024B) allocations
3. Verify no TLS_SLL_POP_INVALID errors
4. Verify `last_push` addresses are even (base pointers)
## 期待される結果
修正後:
```
# 100K iterations, no errors
Throughput = 25-30M ops/s (current: 1.5M ops/s with corruption)
```