From dc9ddf8104d79d4a939cca4fc65dc88271907539 Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 1 Nov 2020 10:14:27 -0700 Subject: [PATCH] Kernel: Fix deadlock when unicasting/broadcasting SMP message When two processors send each others a SMP message at the same time they need to process messages while waiting for delivery of the message they just sent, or they will deadlock. --- Kernel/Arch/i386/CPU.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp index d162a0d0e8..6df49f7acc 100644 --- a/Kernel/Arch/i386/CPU.cpp +++ b/Kernel/Arch/i386/CPU.cpp @@ -1884,11 +1884,10 @@ void Processor::smp_broadcast_message(ProcessorMessage& msg, bool async) while (atomic_load(&msg.refs, AK::MemoryOrder::memory_order_consume) != 0) { // TODO: pause for a bit? - // We need to check here if another processor may have requested - // us to halt before this message could be delivered. Otherwise - // we're just spinning the CPU because msg.refs will never drop to 0. - if (cur_proc.m_halt_requested.load(AK::MemoryOrder::memory_order_relaxed)) - halt_this(); + // We need to process any messages that may have been sent to + // us while we're waiting. This also checks if another processor + // may have requested us to halt. + cur_proc.smp_process_pending_messages(); } smp_cleanup_message(msg); @@ -1934,11 +1933,10 @@ void Processor::smp_unicast_message(u32 cpu, ProcessorMessage& msg, bool async) while (atomic_load(&msg.refs, AK::MemoryOrder::memory_order_consume) != 0) { // TODO: pause for a bit? - // We need to check here if another processor may have requested - // us to halt before this message could be delivered. Otherwise - // we're just spinning the CPU because msg.refs will never drop to 0. - if (cur_proc.m_halt_requested.load(AK::MemoryOrder::memory_order_relaxed)) - halt_this(); + // We need to process any messages that may have been sent to + // us while we're waiting. This also checks if another processor + // may have requested us to halt. + cur_proc.smp_process_pending_messages(); } smp_cleanup_message(msg);