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:
co-authored by
Claude Opus 5.5
parent
8409e376cf
commit
5bc7b4dee7
@@ -35,6 +35,7 @@
|
||||
#include "starkernel/capsule_vm_switch_signal.h" /* FABRIC-3.8.md §3.13.3 -- the decision */
|
||||
#include "starkernel/vm/bootstrap/sk_vm_bootstrap.h" /* sk_get_mama_vm() -- the idle root */
|
||||
#include "starkernel/percpu.h" /* FABRIC-3.10.8 MC-0a -- this core's current VM */
|
||||
#include "starkernel/spinlock.h" /* FABRIC-3.10.8 MC-0b -- no lock crosses a switch */
|
||||
#include <stdint.h>
|
||||
|
||||
/* Arch-specific (switch.S in each arch dir). sk_vm_switch_prime() builds
|
||||
@@ -226,6 +227,11 @@ void sk_vm_idle_point(int may_drain_self) {
|
||||
VM *self = sk_percpu()->current_vm;
|
||||
VM *next;
|
||||
|
||||
/* FABRIC-3.10.8 MC-0b: nothing is held on return to the idle point,
|
||||
* which makes this the place to log any lock failure counted since. */
|
||||
sk_lock_check_none_held("idle point");
|
||||
sk_lock_report();
|
||||
|
||||
if (!self || self != (VM *)sk_get_mama_vm()) return;
|
||||
if (self->frames.count != 0) return; /* inside a word (KEY/EXPECT): not idle */
|
||||
|
||||
@@ -280,7 +286,10 @@ int sk_vm_context_switch(VM *from, VM *to) {
|
||||
sk_vm_switch_signal_note_parked(from->stadium_vm_id); /* §3.13.3 wait stamp */
|
||||
sk_percpu()->current_vm = to;
|
||||
|
||||
/* FABRIC-3.10.8 MC-0b: no lock crosses a switch (spinlock.h). */
|
||||
sk_lock_check_none_held("context switch, leaving");
|
||||
sk_vm_switch_to(&from->native_stack_saved_sp, new_sp);
|
||||
sk_lock_check_none_held("context switch, resumed");
|
||||
|
||||
/* Resumes here only once something later switches back to `from` --
|
||||
* from `from`'s own point of view, this call simply took a while.
|
||||
|
||||
Reference in New Issue
Block a user