FABRIC-3.10.8 K-11: check the lock order at run time
Every lock carries a rank (hermes < switch < registry < VM dict_lock < VM tuning_lock < stadium < slot < doe < log < block < console < heap < vmm < pmm); each core counts held locks per rank and an acquisition not above the highest held rank counts an order violation, reported in full at the idle point. Probe inversion reported exactly once; O-A, a 28-VM churn and the standard sequence show 0 violations on all three ISAs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
a66c4f3d5e
commit
7252e2ed72
@@ -774,3 +774,33 @@ Only these two FABRIC docs record the old hashes; nothing in code or scripts che
|
||||
| riscv64 | `logs/20260926-102708` | same as amd64 |
|
||||
|
||||
**K-10 closes the three stale Hermes-VM references found at K-3.** `ARTEMIS-READY-ACK` (no caller) and the `switch_hermes_readiness` CSV column name (always 0, kept with its two siblings pending FABRIC-3.8.md Stage I) remain, as noted in §4.9.
|
||||
|
||||
### 4.12 K-11 — the lock order checked at run time (2026-09-26)
|
||||
|
||||
**Change.**
|
||||
- **Ranks** (`spinlock.h`, `sk_lock_rank_t`): hermes < switch < registry < VM `dict_lock` < VM `tuning_lock` < stadium < Stadium slot < doe < log < block < console < heap < vmm < pmm.
|
||||
- `sk_spinlock_t` carries its rank (`SK_SPINLOCK_INIT(rank)`).
|
||||
- The raw-lockword calls take one: `sk_lockword_acquire/release(word, rank)` for Stadium slots and `sf_mutex`.
|
||||
- The kernel `sf_mutex_t` gains a `rank`. `sf_mutex_init()` sets the dict rank, and the kernel `vm_init()` re-ranks `tuning_lock`.
|
||||
- **The check** (`spinlock.c`).
|
||||
- Each core counts the locks it holds per rank (`sk_percpu_t.held_rank[]`).
|
||||
- Taking a lock whose rank is not above the highest held rank counts an order violation, recording both ranks and the call site. A same-rank pair counts too.
|
||||
- A recursion is still counted as a recursion only.
|
||||
- New `sk_lock_order_violations()`.
|
||||
- **The report** (`sk_lock_report()`, at the idle point) prints the full line to the console. The log line keeps only the count, because `log_message()` cuts at `LOG_LINE_MAX` (64 bytes): the first probe run showed `...while holding he` (`logs/20260926-103947`). This follows parity.c's INCOMPLETE report.
|
||||
|
||||
**Evidence.**
|
||||
- **Probe** (temporary `K11-PROBE` word: heap, then registry; amd64, `logs/20260926-104239`). Nothing is reported through boot. After the probe, exactly one line: `LOCK: order violation x1 (first: took registry while holding heap, from 0x000000003d71a62c)`.
|
||||
- **Clean** (probe reverted; the tree is byte-identical to the saved stage diff). O-A, then a 28-VM churn (32 births, 28 kills), then the standard sequence:
|
||||
|
||||
| ISA | log | order violations / any `LOCK:` line | result |
|
||||
|---|---|---|---|
|
||||
| amd64 | `logs/20260926-104446` | **0 / none** | K-10 hashes, G A=40 B=40, HHH, all ok `3`, 0 B idle, 0 / 0 |
|
||||
| aarch64 | `logs/20260926-110203` | **0 / none** | same |
|
||||
| riscv64 | `logs/20260926-112011` | **0 / none** | same; 0 `timed out` |
|
||||
|
||||
The ledger reads pulled 319488 / returned 316703 on all three. That is the K-3 baseline plus 28 × 2048: the churn's 28 SENDs, each a message cell pulled and returned. Held and consumed are unchanged, and conservation holds.
|
||||
|
||||
**Found, not fixed:** MC-0b's three older lock reports (recursion, bad release, held at switch) go through `log_message()` only, so they are cut at 64 bytes and lose the lock name and site. None fired in any run here.
|
||||
|
||||
**K-11 closes the "lock order checked by inspection only" finding.** With K-9..K-11, every ruling from K-8's report is carried out.
|
||||
|
||||
Reference in New Issue
Block a user