Stage MC-0b: real kernel spinlocks; sf_mutex no longer a no-op (FABRIC-3.10.8 §3.2)

- New spinlock primitive (spinlock.h/.c): CAS on an owner word (core+1),
  interrupts masked while any lock is held (state kept in the per-core
  block, so release order doesn't matter). Recursion, release-not-held,
  held-at-switch and destroyed-while-held are counted and logged, never
  silent. Locks are no-ops until the boot core's block is installed
  (riscv64's monolithic early boot prints before sk_percpu_boot_init()).
- Kernel locks in a documented order: hermes, switch, registry, doe, log,
  console, heap, vmm, pmm. sf_mutex (dict_lock/tuning_lock) uses the same
  lock word.
- Hermes: public functions over *_locked internals; never held across the
  drain's vm_interpret_kind(); switch notifications after dropping the
  lock; event payload moved off static storage. Switch table and registry
  never call out while held (slot/entry copied under the lock).
- No lock crosses a switch: checked at context switch (leave, resume) and
  the idle point.
- Probe (removed): every lock balances on all three ISAs; 0 held at
  switch over 7.5M-51M checks; 0 recursions, 0 bad releases.
- Standard sequence on amd64/aarch64/riscv64: hashes and G byte-identical
  to MC-0a, MINT/WIREBIND/USE ok, conservation true, 0 idle growth.
- Block subsystem split out as MC-0b2 (Captain Bob's ruling).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-09-25 16:43:19 -04:00
co-authored by Claude Opus 5.5
parent 8409e376cf
commit 5bc7b4dee7
28 changed files with 56110 additions and 274 deletions
+30 -6
View File
@@ -36,6 +36,7 @@
#include <string.h>
#include "block_subsystem.h" /* blk_meta_zone_read/write, compute_crc64 */
#include "starkernel/spinlock.h" /* FABRIC-3.10.8 MC-0b -- g_lock_doe */
static uint64_t doe_region_ctrl_compute_crc(const doe_region_ctrl_t *ctrl) {
size_t crc_span = offsetof(doe_region_ctrl_t, hdr_crc);
@@ -119,11 +120,13 @@ static int doe_region_read_slot(uint32_t slot_index, doe_trial_slot_t *out) {
return 0;
}
int doe_region_append(uint32_t run_id, uint32_t cfg, uint32_t rep, uint32_t nw,
uint32_t mode, uint32_t fail_count,
uint64_t fleet_k_q48, uint32_t fleet_conserved,
uint64_t switch_count_cumulative,
const char *isa, uint32_t isa_len) {
/* FABRIC-3.10.8 MC-0b: append and count run under g_lock_doe (the public
* functions below); these are their bodies. */
static int doe_region_append_locked(uint32_t run_id, uint32_t cfg, uint32_t rep, uint32_t nw,
uint32_t mode, uint32_t fail_count,
uint64_t fleet_k_q48, uint32_t fleet_conserved,
uint64_t switch_count_cumulative,
const char *isa, uint32_t isa_len) {
doe_region_ctrl_t ctrl;
if (doe_region_ctrl_read(&ctrl) != 0) {
doe_region_ctrl_init_fresh(&ctrl);
@@ -174,7 +177,20 @@ int doe_region_append(uint32_t run_id, uint32_t cfg, uint32_t rep, uint32_t nw,
return doe_region_ctrl_write(&ctrl) == 0 ? 0 : -1;
}
uint32_t doe_region_count_for_isa(const char *isa, uint32_t isa_len) {
int doe_region_append(uint32_t run_id, uint32_t cfg, uint32_t rep, uint32_t nw,
uint32_t mode, uint32_t fail_count,
uint64_t fleet_k_q48, uint32_t fleet_conserved,
uint64_t switch_count_cumulative,
const char *isa, uint32_t isa_len) {
int rc;
sk_spin_lock(&g_lock_doe);
rc = doe_region_append_locked(run_id, cfg, rep, nw, mode, fail_count, fleet_k_q48,
fleet_conserved, switch_count_cumulative, isa, isa_len);
sk_spin_unlock(&g_lock_doe);
return rc;
}
static uint32_t doe_region_count_for_isa_locked(const char *isa, uint32_t isa_len) {
doe_region_ctrl_t ctrl;
if (doe_region_ctrl_read(&ctrl) != 0) return 0;
@@ -202,3 +218,11 @@ uint32_t doe_region_count_for_isa(const char *isa, uint32_t isa_len) {
}
return count;
}
uint32_t doe_region_count_for_isa(const char *isa, uint32_t isa_len) {
uint32_t n;
sk_spin_lock(&g_lock_doe);
n = doe_region_count_for_isa_locked(isa, isa_len);
sk_spin_unlock(&g_lock_doe);
return n;
}