From 76b7210226d333258af108ae9a2d4116117b6e6f Mon Sep 17 00:00:00 2001 From: Maciej Szwed Date: Fri, 5 Mar 2021 09:05:36 +0100 Subject: [PATCH] scheduler_dynamic: refactor out searching for target core Refactors logic for finding the optimal core for a thread to single function. Signed-off-by: Maciej Szwed Signed-off-by: Tomasz Zawadzki Change-Id: Ifc2b09acb6f698640ce9602fec4f567eb32b79fa Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6732 Tested-by: SPDK CI Jenkins Reviewed-by: Shuhei Matsumoto Reviewed-by: Paul Luse Reviewed-by: Jim Harris --- lib/event/scheduler_dynamic.c | 67 +++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/lib/event/scheduler_dynamic.c b/lib/event/scheduler_dynamic.c index 38f97d617..4adbf8f06 100644 --- a/lib/event/scheduler_dynamic.c +++ b/lib/event/scheduler_dynamic.c @@ -110,6 +110,36 @@ _move_thread(struct spdk_lw_thread *lw_thread, uint32_t dst_core) lw_thread->lcore = dst_core; } +static uint32_t +_find_optimal_core(struct spdk_lw_thread *lw_thread) +{ + uint32_t i; + uint32_t target_lcore; + struct spdk_thread *thread = spdk_thread_get_from_ctx(lw_thread); + struct spdk_cpuset *cpumask = spdk_thread_get_cpumask(thread); + uint64_t thread_busy = lw_thread->current_stats.busy_tsc; + + /* Find a core that can fit the thread. */ + for (i = 0; i < spdk_env_get_core_count(); i++) { + target_lcore = _get_next_target_core(); + + /* Ignore cores outside cpumask. */ + if (!spdk_cpuset_get_cpu(cpumask, target_lcore)) { + continue; + } + + /* Do not use main core if it is too busy for new thread. */ + if (target_lcore == g_main_lcore && thread_busy > g_cores[g_main_lcore].idle) { + continue; + } + + return target_lcore; + } + + /* If no better core is found, remain on the same one. */ + return lw_thread->lcore; +} + static int init(struct spdk_governor *governor) { @@ -168,9 +198,8 @@ balance(struct spdk_scheduler_core_info *cores_info, int cores_count, struct spdk_scheduler_core_info *core; struct spdk_cpuset *cpumask; struct core_stats *main_core; - uint64_t thread_busy; uint32_t target_lcore; - uint32_t i, j, k; + uint32_t i, j; int rc; uint8_t load; bool busy_threads_present = false; @@ -190,43 +219,19 @@ balance(struct spdk_scheduler_core_info *cores_info, int cores_count, lw_thread = core->threads[j]; thread = spdk_thread_get_from_ctx(lw_thread); cpumask = spdk_thread_get_cpumask(thread); - - thread_busy = lw_thread->current_stats.busy_tsc; - load = _get_thread_load(lw_thread); if (i == g_main_lcore && load >= SCHEDULER_LOAD_LIMIT) { /* This thread is active and on the main core, we need to pick a core to move it to */ - for (k = 0; k < spdk_env_get_core_count(); k++) { - target_lcore = _get_next_target_core(); - - /* Do not use main core if it is too busy for new thread */ - if (target_lcore == g_main_lcore && thread_busy > main_core->idle) { - continue; - } - - if (spdk_cpuset_get_cpu(cpumask, target_lcore)) { - _move_thread(lw_thread, target_lcore); - break; - } - } + target_lcore = _find_optimal_core(lw_thread); + _move_thread(lw_thread, target_lcore); } else if (i != g_main_lcore && load < SCHEDULER_LOAD_LIMIT) { /* This thread is idle but not on the main core, so we need to move it to the main core */ _move_thread(lw_thread, g_main_lcore); - } else { + } else if (i != g_main_lcore && !spdk_cpuset_get_cpu(cpumask, i)) { /* Move busy thread only if cpumask does not match current core (except main core) */ - if (i != g_main_lcore) { - if (!spdk_cpuset_get_cpu(cpumask, i)) { - for (k = 0; k < spdk_env_get_core_count(); k++) { - target_lcore = _get_next_target_core(); - - if (spdk_cpuset_get_cpu(cpumask, target_lcore)) { - _move_thread(lw_thread, target_lcore); - break; - } - } - } - } + target_lcore = _find_optimal_core(lw_thread); + _move_thread(lw_thread, target_lcore); } } }