diff --git a/Kernel/Tasks/PowerStateSwitchTask.cpp b/Kernel/Tasks/PowerStateSwitchTask.cpp index a12bc640528..687f35f1b30 100644 --- a/Kernel/Tasks/PowerStateSwitchTask.cpp +++ b/Kernel/Tasks/PowerStateSwitchTask.cpp @@ -90,14 +90,11 @@ ErrorOr PowerStateSwitchTask::perform_shutdown() g_in_system_shutdown = true; // Make sure to kill all user processes first, otherwise we might get weird hangups. - TRY(kill_processes(ProcessKind::User, finalizer_process->pid())); - TRY(kill_processes(ProcessKind::Kernel, finalizer_process->pid())); + TRY(kill_all_user_processes()); - finalizer_process->die(); - finalizer_process->finalize(); size_t alive_process_count = 0; Process::all_instances().for_each([&](Process& process) { - if (process.pid() != Process::current().pid() && !process.is_dead()) + if (!process.is_kernel_process() && !process.is_dead()) alive_process_count++; }); // Don't panic here (since we may panic in a bit anyways) but report the probable cause of an unclean shutdown. @@ -143,6 +140,12 @@ ErrorOr PowerStateSwitchTask::perform_shutdown() } } + // NOTE: We don't really need to kill kernel processes, because in contrast + // to user processes, kernel processes will simply not make syscalls + // or do some other unexpected behavior. + // Therefore, we just lock the scheduler big lock to ensure nothing happens + // beyond this point forward. + SpinlockLocker lock(g_scheduler_lock); dbgln("Attempting system shutdown..."); arch_specific_poweroff(); @@ -152,15 +155,15 @@ ErrorOr PowerStateSwitchTask::perform_shutdown() Processor::halt(); } -ErrorOr PowerStateSwitchTask::kill_processes(ProcessKind kind, ProcessID finalizer_pid) +ErrorOr PowerStateSwitchTask::kill_all_user_processes() { - bool kill_kernel_processes = kind == ProcessKind::Kernel; - - Process::all_instances().for_each([&](Process& process) { - if (process.pid() != Process::current().pid() && process.pid() != finalizer_pid && process.is_kernel_process() == kill_kernel_processes) { - process.die(); - } - }); + { + SpinlockLocker lock(g_scheduler_lock); + Process::all_instances().for_each([&](Process& process) { + if (!process.is_kernel_process()) + process.die(); + }); + } // Although we *could* finalize processes ourselves (g_in_system_shutdown allows this), // we're nice citizens and let the finalizer task perform final duties before we kill it. @@ -171,7 +174,7 @@ ErrorOr PowerStateSwitchTask::kill_processes(ProcessKind kind, ProcessID f Scheduler::yield(); alive_process_count = 0; Process::all_instances().for_each([&](Process& process) { - if (process.pid() != Process::current().pid() && !process.is_dead() && process.pid() != finalizer_pid && process.is_kernel_process() == kill_kernel_processes) + if (!process.is_kernel_process() && !process.is_dead()) alive_process_count++; }); @@ -181,9 +184,9 @@ ErrorOr PowerStateSwitchTask::kill_processes(ProcessKind kind, ProcessID f if constexpr (PROCESS_DEBUG) { Process::all_instances().for_each_const([&](Process const& process) { - if (process.pid() != Process::current().pid() && !process.is_dead() && process.pid() != finalizer_pid && process.is_kernel_process() == kill_kernel_processes) { - dbgln("Process {:2} kernel={} dead={} dying={} ({})", - process.pid(), process.is_kernel_process(), process.is_dead(), process.is_dying(), + if (!process.is_kernel_process() && !process.is_dead()) { + dbgln("Process (user) {:2} dead={} dying={} ({})", + process.pid(), process.is_dead(), process.is_dying(), process.name().with([](auto& name) { return name.representable_view(); })); } }); diff --git a/Kernel/Tasks/PowerStateSwitchTask.h b/Kernel/Tasks/PowerStateSwitchTask.h index 8e7f091b8c3..1c87226001c 100644 --- a/Kernel/Tasks/PowerStateSwitchTask.h +++ b/Kernel/Tasks/PowerStateSwitchTask.h @@ -32,11 +32,7 @@ private: static ErrorOr perform_reboot(); static ErrorOr perform_shutdown(); - enum class ProcessKind { - User, - Kernel, - }; - static ErrorOr kill_processes(ProcessKind, ProcessID finalizer_pid); + static ErrorOr kill_all_user_processes(); }; }