kernel/debug: Enter KDL even if some CPUs can't be trapped in it.

Otherwise the system just hangs, which isn't good.

Turns #20090 from a hang into a KDL, as one CPU is stuck in a loop
with interrupts disabled.
This commit is contained in:
Augustin Cavalier
2026-05-19 15:25:02 -04:00
parent ced8a80543
commit 57a5a0ff6c
+22 -2
View File
@@ -151,6 +151,7 @@ static bool sPreviousDprintfState;
static volatile bool sHandOverKDL = false; static volatile bool sHandOverKDL = false;
static int32 sHandOverKDLToCPU = -1; static int32 sHandOverKDLToCPU = -1;
static bool sCPUTrapped[SMP_MAX_CPUS]; static bool sCPUTrapped[SMP_MAX_CPUS];
static int32 sCPUsTrapped = 0;
// #pragma mark - DebugOutputFilter // #pragma mark - DebugOutputFilter
@@ -829,6 +830,11 @@ kernel_debugger_loop(const char* messagePrefix, const char* message,
print_kernel_debugger_message(); print_kernel_debugger_message();
if (atomic_get(&sCPUsTrapped) != (smp_get_num_cpus() - 1)) {
kprintf("PANIC: %d/%d CPUs are not trapped in the kernel debugger!\n",
smp_get_num_cpus() - (sCPUsTrapped + 1), smp_get_num_cpus());
}
kprintf("Welcome to Kernel Debugging Land...\n"); kprintf("Welcome to Kernel Debugging Land...\n");
kprintf("revision: %s\n", get_haiku_revision()); kprintf("revision: %s\n", get_haiku_revision());
@@ -978,8 +984,20 @@ enter_kernel_debugger(int32 cpu, int32& previousCPU)
CPUSet cpuMask; CPUSet cpuMask;
cpuMask.SetAll(); cpuMask.SetAll();
cpuMask.ClearBit(cpu); cpuMask.ClearBit(cpu);
smp_multicast_ici_interrupts_disabled(cpu, cpuMask, SMP_MSG_CPU_HALT, 0, 0, smp_multicast_ici_interrupts_disabled(cpu, cpuMask, SMP_MSG_CPU_HALT,
0, NULL, SMP_MSG_FLAG_SYNC); 0, 0, 0, NULL, 0);
// We don't use a synchronous message in order to avoid hanging when
// other CPU(s) are stuck somewhere they won't notice ICIs.
bigtime_t timeout = system_time() + 1 * 1000 * 1000;
while (atomic_get(&sCPUsTrapped) < (smp_get_num_cpus() - 1)) {
cpu_pause();
if (system_time() >= timeout) {
// Just continue entering KDL. The main loop will print
// a message about the stuck CPUs.
break;
}
}
} }
previousCPU = sDebuggerOnCPU; previousCPU = sDebuggerOnCPU;
@@ -1826,6 +1844,7 @@ debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver)
arch_debug_save_registers(&sDebugRegisters[cpu]); arch_debug_save_registers(&sDebugRegisters[cpu]);
sCPUTrapped[cpu] = true; sCPUTrapped[cpu] = true;
atomic_add(&sCPUsTrapped, 1);
while (sInDebugger != 0) { while (sInDebugger != 0) {
arch_debug_snooze(10000); arch_debug_snooze(10000);
@@ -1841,6 +1860,7 @@ debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver)
} }
sCPUTrapped[cpu] = false; sCPUTrapped[cpu] = false;
atomic_add(&sCPUsTrapped, -1);
} }