From 376e4b4c45b27885b874af48c8402165b06393c7 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 19 May 2026 23:52:38 +0300 Subject: [PATCH] Kernel: Reduce the number of sent IPIs Only send an IPI when the target processors don't have pending messages. This basically gets rid of TLB shootdowns from showing up in profiles. Before they were taking maybe >10% kernel time :^D --- kernel/include/kernel/Processor.h | 2 +- kernel/kernel/Processor.cpp | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/kernel/include/kernel/Processor.h b/kernel/include/kernel/Processor.h index b898f116..64f79482 100644 --- a/kernel/include/kernel/Processor.h +++ b/kernel/include/kernel/Processor.h @@ -132,7 +132,7 @@ namespace Kernel static void handle_ipi(); static void handle_smp_messages(); - static void send_smp_message(ProcessorID, const SMPMessage&, bool send_ipi = true); + static bool send_smp_message(ProcessorID, const SMPMessage&, bool send_ipi = true); static void broadcast_smp_message(const SMPMessage&); static void load_segments(); diff --git a/kernel/kernel/Processor.cpp b/kernel/kernel/Processor.cpp index e08fd9e4..3bb9c7ea 100644 --- a/kernel/kernel/Processor.cpp +++ b/kernel/kernel/Processor.cpp @@ -488,7 +488,7 @@ namespace Kernel set_interrupt_state(state); } - void Processor::send_smp_message(ProcessorID processor_id, const SMPMessage& message, bool send_ipi) + bool Processor::send_smp_message(ProcessorID processor_id, const SMPMessage& message, bool send_ipi) { auto state = get_interrupt_state(); set_interrupt_state(InterruptState::Disabled); @@ -499,6 +499,8 @@ namespace Kernel { processor.lock_tlb_lock(); + const bool is_first_entry = (processor.m_tlb_entry_count == 0); + const auto& tlb_msg = message.flush_tlb; processor.m_tlb_global |= (tlb_msg.page_table == nullptr); @@ -515,7 +517,7 @@ namespace Kernel processor.unlock_tlb_lock(); set_interrupt_state(state); - return; + return is_first_entry; } // find a slot for message @@ -557,15 +559,19 @@ namespace Kernel storage->next = processor.m_smp_pending; } + const bool needs_ipi = (storage->next == nullptr); + if (send_ipi) { if (processor_id == current_id()) handle_smp_messages(); - else + else if (needs_ipi) InterruptController::get().send_ipi(processor_id); } set_interrupt_state(state); + + return needs_ipi; } void Processor::broadcast_smp_message(const SMPMessage& message) @@ -576,15 +582,18 @@ namespace Kernel const auto state = get_interrupt_state(); set_interrupt_state(InterruptState::Disabled); + bool needs_ipi = false; + const auto current_id = Processor::current_id(); for (size_t i = 0; i < Processor::count(); i++) { const auto processor_id = s_processor_ids[i]; if (processor_id != current_id) - send_smp_message(processor_id, message, false); + needs_ipi |= send_smp_message(processor_id, message, false); } - InterruptController::get().broadcast_ipi(); + if (needs_ipi) + InterruptController::get().broadcast_ipi(); set_interrupt_state(state); }