Kernel: Fix scheduler load balancing
I was not updating the current queue of the thread which lead to blocked threads think they were in run queue
This commit is contained in:
parent
20e17a28cf
commit
35b3c3c98c
|
@ -7,7 +7,6 @@
|
||||||
#include <kernel/Timer/Timer.h>
|
#include <kernel/Timer/Timer.h>
|
||||||
|
|
||||||
#define SCHEDULER_ASSERT 1
|
#define SCHEDULER_ASSERT 1
|
||||||
#define SCHEDULER_LOAD_BALANCE 0
|
|
||||||
|
|
||||||
#if SCHEDULER_ASSERT == 0
|
#if SCHEDULER_ASSERT == 0
|
||||||
#undef ASSERT
|
#undef ASSERT
|
||||||
|
@ -296,7 +295,6 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
|
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
|
||||||
|
|
||||||
if constexpr(SCHEDULER_LOAD_BALANCE)
|
|
||||||
if (Processor::is_smp_enabled())
|
if (Processor::is_smp_enabled())
|
||||||
do_load_balancing();
|
do_load_balancing();
|
||||||
|
|
||||||
|
@ -339,6 +337,7 @@ namespace Kernel
|
||||||
node->blocked = false;
|
node->blocked = false;
|
||||||
if (node != m_current)
|
if (node != m_current)
|
||||||
m_run_queue.add_thread_to_back(node);
|
m_run_queue.add_thread_to_back(node);
|
||||||
|
update_most_loaded_node_queue(node, &m_run_queue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -388,7 +387,6 @@ namespace Kernel
|
||||||
return least_loaded_id;
|
return least_loaded_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SCHEDULER_LOAD_BALANCE
|
|
||||||
void Scheduler::do_load_balancing()
|
void Scheduler::do_load_balancing()
|
||||||
{
|
{
|
||||||
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
|
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
|
||||||
|
@ -421,9 +419,9 @@ namespace Kernel
|
||||||
|
|
||||||
if (m_current)
|
if (m_current)
|
||||||
{
|
{
|
||||||
const char* name = "unknown";
|
const char* name = "<unknown>";
|
||||||
if (m_current->thread->has_process() && m_current->thread->process().is_userspace() && m_current->thread->process().userspace_info().argv)
|
if (m_current->thread->has_process() && *m_current->thread->process().name())
|
||||||
name = m_current->thread->process().userspace_info().argv[0];
|
name = m_current->thread->process().name();
|
||||||
const uint64_t load_percent_x1000 = BAN::Math::div_round_up<uint64_t>(m_current->time_used_ns * 100'000, processing_ns);
|
const uint64_t load_percent_x1000 = BAN::Math::div_round_up<uint64_t>(m_current->time_used_ns * 100'000, processing_ns);
|
||||||
dprintln(" tid { 2}: { 3}.{3}% <{}> current", m_current->thread->tid(), load_percent_x1000 / 1000, load_percent_x1000 % 1000, name);
|
dprintln(" tid { 2}: { 3}.{3}% <{}> current", m_current->thread->tid(), load_percent_x1000 / 1000, load_percent_x1000 % 1000, name);
|
||||||
}
|
}
|
||||||
|
@ -474,9 +472,6 @@ namespace Kernel
|
||||||
break;
|
break;
|
||||||
if (thread_info.node == m_current || thread_info.queue == nullptr)
|
if (thread_info.node == m_current || thread_info.queue == nullptr)
|
||||||
continue;
|
continue;
|
||||||
// FIXME: allow load balancing with blocked threads, with this algorithm there is a race condition
|
|
||||||
if (thread_info.node->blocked)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto least_loaded_id = find_least_loaded_processor();
|
auto least_loaded_id = find_least_loaded_processor();
|
||||||
if (least_loaded_id == Processor::current_id())
|
if (least_loaded_id == Processor::current_id())
|
||||||
|
@ -566,7 +561,6 @@ namespace Kernel
|
||||||
|
|
||||||
m_last_load_balance_ns += s_load_balance_interval_ns;
|
m_last_load_balance_ns += s_load_balance_interval_ns;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
BAN::ErrorOr<void> Scheduler::bind_thread_to_processor(Thread* thread, ProcessorID processor_id)
|
BAN::ErrorOr<void> Scheduler::bind_thread_to_processor(Thread* thread, ProcessorID processor_id)
|
||||||
{
|
{
|
||||||
|
@ -610,12 +604,14 @@ namespace Kernel
|
||||||
auto state = Processor::get_interrupt_state();
|
auto state = Processor::get_interrupt_state();
|
||||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||||
|
|
||||||
|
ASSERT(m_current->processor_id == Processor::current_id());
|
||||||
ASSERT(!m_current->blocked);
|
ASSERT(!m_current->blocked);
|
||||||
|
|
||||||
m_current->blocked = true;
|
m_current->blocked = true;
|
||||||
m_current->wake_time_ns = wake_time_ns;
|
m_current->wake_time_ns = wake_time_ns;
|
||||||
if (blocker)
|
if (blocker)
|
||||||
blocker->add_thread_to_block_queue(m_current);
|
blocker->add_thread_to_block_queue(m_current);
|
||||||
|
update_most_loaded_node_queue(m_current, &m_block_queue);
|
||||||
Processor::yield();
|
Processor::yield();
|
||||||
|
|
||||||
Processor::set_interrupt_state(state);
|
Processor::set_interrupt_state(state);
|
||||||
|
|
Loading…
Reference in New Issue