From a0f404551e0e04b03e6f91523a8885f9a273f8cf Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Wed, 26 Jan 2022 18:34:31 +0200 Subject: [PATCH] Kernel: Ignore allocation failures during thread finalization We ignore allocation failures above the first 32 guaranteed thread slots, and just flag our future-selves to finalize these threads at a later point. --- Kernel/Tasks/FinalizerTask.cpp | 6 ++++-- Kernel/Thread.cpp | 9 +++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Kernel/Tasks/FinalizerTask.cpp b/Kernel/Tasks/FinalizerTask.cpp index a8283f4826..8021453abb 100644 --- a/Kernel/Tasks/FinalizerTask.cpp +++ b/Kernel/Tasks/FinalizerTask.cpp @@ -14,10 +14,12 @@ static void finalizer_task(void*) { Thread::current()->set_priority(THREAD_PRIORITY_LOW); for (;;) { - g_finalizer_wait_queue->wait_forever("FinalizerTask"); - + // The order of this if-else is important: We want to continue trying to finalize the threads in case + // Thread::finalize_dying_threads set g_finalizer_has_work back to true due to OOM conditions if (g_finalizer_has_work.exchange(false, AK::MemoryOrder::memory_order_acq_rel) == true) Thread::finalize_dying_threads(); + else + g_finalizer_wait_queue->wait_forever("FinalizerTask"); } }; diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index e3cd8b580c..3196e0a1b1 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -529,8 +529,13 @@ void Thread::finalize_dying_threads() { SpinlockLocker lock(g_scheduler_lock); for_each_in_state(Thread::State::Dying, [&](Thread& thread) { - if (thread.is_finalizable()) - dying_threads.append(&thread); + if (!thread.is_finalizable()) + return; + auto result = dying_threads.try_append(&thread); + // We ignore allocation failures above the first 32 guaranteed thread slots, and + // just flag our future-selves to finalize these threads at a later point + if (result.is_error()) + g_finalizer_has_work.store(true, AK::MemoryOrder::memory_order_release); }); } for (auto* thread : dying_threads) {