kernel: contain a fatal fault — name the task, release the BKL before halt
Two gaps a real-hardware crash exposed, both in onException's terminal path (and the panic path): - The report was anonymous. Add the faulting task's id + name and whether it trapped in ring 3 (a user process) or ring 0 (the trusted base) — so a fatal fault says WHAT crashed and WHERE, not just the vector. scheduler gains currentIdSafe/currentNameSafe (early-boot-guarded, like currentCpuIndex, so the reporter can't fault a second time). - halt() never released the big kernel lock, so a core that died holding it deadlocked every other core spinning in acquire() — the whole machine hangs, not just the one core the design promises. The BKL now records its owner (architecture.cpuLocal(), a unique per-core token); sync.releaseIfHeldHere() frees the lock only if this core holds it, called before halt on both fatal paths. Caveat: if we held it mid-mutation the shared state may be inconsistent, but letting the other cores + the supervisor keep running is strictly more recoverable than a guaranteed total hang.
This commit is contained in:
@@ -791,6 +791,21 @@ pub fn currentCpuIndex() u32 {
|
||||
return thisCpu().index;
|
||||
}
|
||||
|
||||
/// The running task's id, or 0 if this core's scheduler isn't up yet (early boot, no GS
|
||||
/// base). Safe for a fault reporter to call unconditionally — like `currentCpuIndex`,
|
||||
/// it never dereferences an unpublished per-CPU pointer and so can't fault a second time.
|
||||
pub fn currentIdSafe() u32 {
|
||||
if (architecture.cpuLocal() == 0) return 0;
|
||||
return thisCpu().current.id;
|
||||
}
|
||||
|
||||
/// The running task's name (argv[0]), or "" if this core's scheduler isn't up yet.
|
||||
/// The companion to `currentIdSafe` for naming the culprit in a fatal fault report.
|
||||
pub fn currentNameSafe() []const u8 {
|
||||
if (architecture.cpuLocal() == 0) return "";
|
||||
return thisCpu().current.name();
|
||||
}
|
||||
|
||||
/// Change the running task's priority (takes effect next time it's enqueued).
|
||||
pub fn setPriority(p: Priority) void {
|
||||
current().priority = p;
|
||||
|
||||
Reference in New Issue
Block a user