diff --git a/lib/event/scheduler_dynamic.c b/lib/event/scheduler_dynamic.c index 88922a220..dfef05f5f 100644 --- a/lib/event/scheduler_dynamic.c +++ b/lib/event/scheduler_dynamic.c @@ -205,20 +205,27 @@ deinit(struct spdk_governor *governor) } static void -_balance_thread(struct spdk_lw_thread *lw_thread) +_balance_idle(struct spdk_lw_thread *lw_thread) +{ + if (_get_thread_load(lw_thread) >= SCHEDULER_LOAD_LIMIT) { + return; + } + /* This thread is idle, move it to the main core. */ + _move_thread(lw_thread, g_main_lcore); +} + +static void +_balance_active(struct spdk_lw_thread *lw_thread) { uint32_t target_lcore; - uint8_t load; - load = _get_thread_load(lw_thread); - if (load < SCHEDULER_LOAD_LIMIT) { - /* This thread is idle, move it to the main core. */ - _move_thread(lw_thread, g_main_lcore); - } else { - /* This thread is active. */ - target_lcore = _find_optimal_core(lw_thread); - _move_thread(lw_thread, target_lcore); + if (_get_thread_load(lw_thread) < SCHEDULER_LOAD_LIMIT) { + return; } + + /* This thread is active. */ + target_lcore = _find_optimal_core(lw_thread); + _move_thread(lw_thread, target_lcore); } static void @@ -239,8 +246,11 @@ balance(struct spdk_scheduler_core_info *cores_info, int cores_count, } main_core = &g_cores[g_main_lcore]; - /* Distribute active threads across all cores and move idle threads to main core */ - _foreach_thread(cores_info, _balance_thread); + /* Distribute threads in two passes, to make sure updated core stats are considered on each pass. + * 1) Move all idle threads to main core. */ + _foreach_thread(cores_info, _balance_idle); + /* 2) Distribute active threads across all cores. */ + _foreach_thread(cores_info, _balance_active); /* Switch unused cores to interrupt mode and switch cores to polled mode * if they will be used after rebalancing */