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
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user