2025-11-08 01:18:37 +09:00
|
|
|
|
# Current Task – 2025-11-08
|
2025-11-05 16:47:04 +09:00
|
|
|
|
|
2025-11-08 01:35:45 +09:00
|
|
|
|
## ✅ 完了: リモートキューとフリーリストの競合バグ修正
|
2025-11-07 17:34:24 +09:00
|
|
|
|
|
2025-11-08 01:18:37 +09:00
|
|
|
|
### 根本原因
|
2025-11-08 01:35:45 +09:00
|
|
|
|
マルチスレッド環境で、**フリーリストとリモートキューが同じブロックを参照**していたため、以下の競合が発生していた:
|
|
|
|
|
|
|
|
|
|
|
|
1. **スレッド A (所有者)**:
|
|
|
|
|
|
- `trc_pop_from_freelist()` でブロック X をフリーリストから取得
|
|
|
|
|
|
- ブロック X をユーザーに割り当て
|
|
|
|
|
|
- ユーザーがブロック X にデータ ("ab") を書き込み
|
|
|
|
|
|
|
|
|
|
|
|
2. **スレッド B (リモートスレッド)**:
|
|
|
|
|
|
- `free(ブロック X)` → `ss_remote_push()` でリモートキューに追加
|
|
|
|
|
|
|
|
|
|
|
|
3. **スレッド A (後で)**:
|
|
|
|
|
|
- `_ss_remote_drain_to_freelist_unsafe()` を実行
|
|
|
|
|
|
- `*(void**)block_X = chain_head` → **ユーザーデータを上書き!** 💥
|
2025-11-07 17:34:24 +09:00
|
|
|
|
|
2025-11-08 01:18:37 +09:00
|
|
|
|
### 発見プロセス
|
2025-11-08 01:35:45 +09:00
|
|
|
|
1. Larson ベンチマーク (4 スレッド) で SEGV 発生
|
|
|
|
|
|
2. Fail-Fast 診断ログで次ポインタ破壊を検出: `0x79a4eca06261` (ASCII "ab")
|
|
|
|
|
|
3. リモート free パス (`ss_remote_push`) を疑うも、リモートサイドテーブル有効のため書き込みなし
|
|
|
|
|
|
4. `_ss_remote_drain_to_freelist_unsafe()` のチェーン構築時に `*(void**)node = ...` を発見
|
|
|
|
|
|
5. **フリーリスト pop の前にリモートキューの drain がない**ことを確認
|
|
|
|
|
|
|
|
|
|
|
|
### 証拠
|
|
|
|
|
|
- `bench_random_mixed` (シングルスレッド): ✅ 動作正常 (865K ops/s)
|
|
|
|
|
|
- `larson_hakmem` (4 スレッド): ❌ SEGV (freelist corruption)
|
|
|
|
|
|
- リモート drain 追加後: ✅ Larson 1073秒安定稼働 (931K ops/s)
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-08 01:35:45 +09:00
|
|
|
|
### 実装した修正
|
|
|
|
|
|
|
|
|
|
|
|
**`core/hakmem_tiny_refill_p0.inc.h` にリモートキューの drain を追加**
|
|
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
|
// CRITICAL FIX: Drain remote queue BEFORE popping from freelist
|
|
|
|
|
|
// Without this, blocks in both freelist and remote queue can be double-allocated
|
|
|
|
|
|
// (Thread A pops from freelist, Thread B adds to remote queue, Thread A drains remote → overwrites user data)
|
|
|
|
|
|
if (tls->ss && tls->slab_idx >= 0) {
|
|
|
|
|
|
_ss_remote_drain_to_freelist_unsafe(tls->ss, tls->slab_idx, meta);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Handle freelist items first (usually 0)
|
|
|
|
|
|
TinyRefillChain chain;
|
|
|
|
|
|
uint32_t from_freelist = trc_pop_from_freelist(
|
|
|
|
|
|
meta, class_idx, ss_base, ss_limit, bs, want, &chain);
|
2025-11-05 12:31:14 +09:00
|
|
|
|
```
|
2025-11-08 01:35:45 +09:00
|
|
|
|
|
|
|
|
|
|
**理由:**
|
|
|
|
|
|
- リモートキューからフリーリストへの drain を**先に実行**することで、フリーリストとリモートキューの重複を解消
|
|
|
|
|
|
- これにより、allocate 済みブロックへの書き込みを防止
|
|
|
|
|
|
|
|
|
|
|
|
### テスト結果
|
|
|
|
|
|
|
|
|
|
|
|
**Larson ベンチマーク (マルチスレッド)**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 修正前: SEGV (数秒で crash)
|
|
|
|
|
|
HAKMEM_TINY_USE_SUPERSLAB=1 ./larson_hakmem 2 8 128 1024 1 12345 4
|
|
|
|
|
|
→ ❌ Segmentation fault
|
|
|
|
|
|
|
|
|
|
|
|
# 修正後: 1073秒安定稼働
|
|
|
|
|
|
HAKMEM_TINY_USE_SUPERSLAB=1 ./larson_hakmem 2 8 128 1024 1 12345 4
|
|
|
|
|
|
→ ✅ 931,629 ops/s (クラッシュなし、1073秒実行)
|
2025-11-05 12:31:14 +09:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-11-08 01:35:45 +09:00
|
|
|
|
**bench_random_mixed (シングルスレッド)**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
HAKMEM_TINY_USE_SUPERSLAB=1 ./bench_random_mixed_hakmem 100000 2048 1234567
|
|
|
|
|
|
→ ✅ 1,020,163 ops/s (クラッシュなし)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 修正されたファイル
|
|
|
|
|
|
- `core/hakmem_tiny_refill_p0.inc.h` - フリーリスト pop 前にリモートキュー drain 追加
|
|
|
|
|
|
- `_ss_remote_drain_to_freelist_unsafe()` 呼び出しを挿入
|
|
|
|
|
|
- `#include "superslab/superslab_inline.h"` 追加
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## ✅ 完了 (前回): 二重割り当てバグの修正
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-08 01:35:45 +09:00
|
|
|
|
### 根本原因
|
|
|
|
|
|
`trc_linear_carve()` が `meta->used` をカーソルとして使用していたが、`meta->used` はブロック解放時に減少するため、既に割り当て済みのブロックが再度カーブされる**二重割り当てバグ**が発生していた。
|
|
|
|
|
|
|
|
|
|
|
|
### 実装した修正
|
2025-11-08 01:18:37 +09:00
|
|
|
|
**1. `TinySlabMeta` 構造体に `carved` フィールド追加** (`core/superslab/superslab_types.h`)
|
2025-11-05 12:31:14 +09:00
|
|
|
|
```c
|
2025-11-08 01:18:37 +09:00
|
|
|
|
typedef struct TinySlabMeta {
|
|
|
|
|
|
void* freelist;
|
|
|
|
|
|
uint16_t used; // 現在使用中のブロック数(増減両方)
|
|
|
|
|
|
uint16_t capacity;
|
|
|
|
|
|
uint16_t carved; // 線形領域からカーブしたブロック数(単調増加のみ)
|
|
|
|
|
|
uint16_t owner_tid; // uint32_t → uint16_t に変更
|
|
|
|
|
|
} TinySlabMeta;
|
2025-11-05 12:31:14 +09:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-11-08 01:18:37 +09:00
|
|
|
|
**2. `trc_linear_carve()` を修正** (`core/tiny_refill_opt.h`)
|
2025-11-05 12:31:14 +09:00
|
|
|
|
```c
|
2025-11-08 01:18:37 +09:00
|
|
|
|
// Before: meta->used をカーソルとして使用(バグ!)
|
|
|
|
|
|
uint8_t* cursor = base + ((size_t)meta->used * bs);
|
|
|
|
|
|
meta->used += batch;
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-08 01:18:37 +09:00
|
|
|
|
// After: meta->carved をカーソルとして使用(修正版)
|
|
|
|
|
|
uint8_t* cursor = base + ((size_t)meta->carved * bs);
|
|
|
|
|
|
meta->carved += batch; // 単調増加のみ
|
|
|
|
|
|
meta->used += batch; // 使用中カウントも更新
|
2025-11-05 12:31:14 +09:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-11-08 01:18:37 +09:00
|
|
|
|
### テスト結果
|
2025-11-05 12:31:14 +09:00
|
|
|
|
```bash
|
2025-11-08 01:35:45 +09:00
|
|
|
|
# 通常モード
|
|
|
|
|
|
./bench_random_mixed_hakmem 100000 2048 1234567
|
|
|
|
|
|
→ ✅ 812,670~1,020,163 ops/s
|
2025-11-05 12:31:14 +09:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-11-08 01:35:45 +09:00
|
|
|
|
---
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-08 01:18:37 +09:00
|
|
|
|
## 次のステップ
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-08 01:35:45 +09:00
|
|
|
|
1. **性能ベンチマーク**
|
|
|
|
|
|
- Larson の長時間実行テスト (registry 容量問題の調査)
|
|
|
|
|
|
- mimalloc との比較
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-08 01:35:45 +09:00
|
|
|
|
2. **Registry 容量問題の修正** (Optional)
|
|
|
|
|
|
- `SUPER_REG_PER_CLASS` の調整
|
|
|
|
|
|
- Class 4 で registry full が頻発
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-08 01:35:45 +09:00
|
|
|
|
3. **診断ログのクリーンアップ** (Optional)
|
|
|
|
|
|
- Fail-Fast ログを本番向けに最適化
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-08 01:18:37 +09:00
|
|
|
|
## 実行コマンド
|
|
|
|
|
|
```bash
|
2025-11-08 01:35:45 +09:00
|
|
|
|
# 通常テスト (シングルスレッド)
|
|
|
|
|
|
HAKMEM_TINY_USE_SUPERSLAB=1 ./bench_random_mixed_hakmem 100000 2048 1234567
|
|
|
|
|
|
|
|
|
|
|
|
# Larson ベンチマーク (マルチスレッド)
|
|
|
|
|
|
HAKMEM_TINY_USE_SUPERSLAB=1 ./larson_hakmem 2 8 128 1024 1 12345 4
|
2025-11-05 12:31:14 +09:00
|
|
|
|
|
2025-11-08 01:18:37 +09:00
|
|
|
|
# Fail-fast 診断モード
|
|
|
|
|
|
HAKMEM_TINY_REFILL_FAILFAST=2 HAKMEM_TINY_USE_SUPERSLAB=1 \
|
|
|
|
|
|
./bench_random_mixed_hakmem 50000 2048 1234567
|
2025-11-05 12:31:14 +09:00
|
|
|
|
```
|