Files
hakmem/docs/SLAB_HANDLE.md

53 lines
3.0 KiB
Markdown
Raw Normal View History

SlabHandle Box (Ownership + Remote Drain + Metadata)
===================================================
目的
- Slab 単位の操作を「所有権を持つハンドル」でカプセル化し、境界の 1 箇所化と不変条件の自動チェックを実現する。
- 下層RemoteQueue / Ownershipの堅牢性を高め、上層Publish/Adoptが壊れない土台を作る。
ファイル
- core/slab_handle.h約 100 行)
- `SlabHandle { ss, meta, slab_idx, owner_tid, valid }`
- `valid==1` のときのみ drain/modify が可能。
API
- `slab_try_acquire(ss, idx, tid) -> SlabHandle`
- `owner_tid==0` の場合のみ CAS で取得し、`valid=1` のハンドルを返す。
- `slab_drain_remote(&h)`
- `valid==1` 必須。RemoteQueue → freelist へ統合。`remote_counts` を 0 に。
- `slab_release(&h)`
- `owner_tid=0` に戻し、`valid=0` にする(明示的に解放したい場合)。
- アクセサ: `slab_meta(&h)`, `slab_freelist(&h)`, `slab_used(&h)`, `slab_capacity(&h)`, `slab_is_valid(&h)`
- 便宜操作: `slab_freelist_push(&h, ptr)`, `slab_freelist_pop(&h)`(いずれも `valid==1` 必須)
不変条件Invariants
- RemoteQueueBox 2は push/exchange と `remote_counts` の整合のみ扱い、owner/freelist には触れない。
- OwnershipBox 3`owner_tid==0` からの取得と release のみ扱い、RemoteQueue には触れない。
- Refill 採用境界 1 箇所でのみ `drain → bind → owner_acquire` を行う。
適用箇所6 箇所)
- `tiny_refill.h`: Sticky / Hot / Bench / Mailbox 採用分岐
- `tiny_mmap_gate.h`: Registry scan 採用
- `hakmem_tiny_free.inc`: SuperSlab adopt path
アンチパターンの禁止Do/Dont
- Dont: publish 側で drain / owner を弄る(通知とヒントのみに限定)。
- Dont: RemoteQueue が freelist/owner に触る。
- Do: 採用境界でのみ `slab_try_acquire``slab_drain_remote``bind` の順で処理。
デバッグ TIPS
- `HAKMEM_SAFE_FREE=1`: free 境界での範囲/クラス不一致の FailFast。
- `HAKMEM_TINY_TRACE_RING=1 + SIGUSR2`: `remote_push/remote_drain/mailbox_publish/mailbox_fetch/bind` を確認。
- `HAKMEM_TINY_RF_FORCE_NOTIFY=1`: 初回通知の見逃しが疑われるケースの可視化。
既知の現象(追跡中)
- `fault_addr=0x6261``free_enter` が同一 `ptr` で異なる `class` に跨って記録されるケースがある。
- 読み: free 境界のクラス判定lookupまたは直前の bind/owner の不整合。
- 対処: 上記 FailFast を既定 ONデバッグ期間、Ring の直前イベントで境界のどこでズレたかを特定。
関連修正(所有権なし drain の是正)
- `hakmem_tiny_superslab.h:376` 付近: `ss_remote_drain_light()` が所有権チェックなしで drain していた問題を修正。
- 修正方針: `ss_owner_try_acquire()` 成功時にのみ `ss_remote_drain_to_freelist()` を実行Box 3→2 の順)。